# How to compute an histogram (plot bars) binning the values from a .csv using TeX?

I've a .csv with a column of acquired measures. I would like to make the histogram bins using TeX from the measures distribution so I have to create the bins first. I haven't found any reference to perform an automatic binning or to set manually the intervals to produce the bins. I would like to know how can I do that and if I can perform non-uniform bins histogram.

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}

\begin{filecontents}{data.csv}
dist
1
2
2.5
2
1
3.5
3
1
3
2
1
1
0.5
1
1.5
1
\end{filecontents}

\begin{document}
\begin{tikzpicture} \begin{axis}
col sep=comma,
x=dist
] {data.csv};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}
\begin{axis}
col sep=comma,
y=dist
] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}


I perform this usually in python (code below) this should be the output:

import matplotlib.pyplot as plt
dist=[1, 2, 2.5, 2, 1, 3.5, 3, 1, 3, 2, 1, 1, 0.5, 1, 1.5, 1]
plt.hist(dist,7) #Compute the histogram of a set of data.

-
You should accept one of the answers if any of them are useful. –  Svend Tveskæg Jan 11 at 15:57
@SvendTveskæg I usually wait a couple of days before to accept an answer... –  G M Jan 11 at 15:59
That's fair enough! :) –  Svend Tveskæg Jan 11 at 16:00

You can use the PGFPlots statistics library for this:

\documentclass[border=5mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots, pgfplotstable}
\usepgfplotslibrary{statistics}

\begin{filecontents}{data.csv}
dist
1
2
2.5
2
1
3.5
3
1
3
2
1
1
0.5
1
1.5
1
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
ybar,
ymin=0
]
hist={
bins=7,
data min=0.5,
data max=4
}
] table [y index=0] {data.csv};
\end{axis}
\end{tikzpicture}
\end{document}

-

Here is a solution using pst-plot:

\documentclass{article}

\usepackage{pst-plot}

\savedata{\data}[{{0.5,1},{1,7},{1.5,1},{2,3},{2.5,1},{3,2},{3.5,1}}]

\begin{document}

\psset{xunit = 2}
\begin{pspicture}(-0.23,-0.53)(4,7.5)
\listplot[
plotstyle = bar,
barwidth = 0.8,
linecolor = red,
fillstyle = solid,
fillcolor = blue!70
]{\data}
\psaxes[
Dx = 0.5,
xticksize = -4pt 0
]{->}(4,7.5)
\end{pspicture}

\end{document}


P.S. I can't figure out exactly what the data are, but from your plot I've guessed. If I'm wrong, you should be able to change it yourself.

-
I'm sorry I've saw only now that although the plotted data result is right the way in which is achieve is not what I was asking. The goal of my question is to perform the binning with TeX (See the Jake answer or the analogous Python code) not to plot an histogram with pre-computed bins. Thanks however for the help! –  G M Jan 13 at 18:49

Here, have some gnuplot. Using the gnuplottex package, typeset using pdflatex --shell-escape:

# Code

\documentclass{standalone}
\usepackage{gnuplottex}
\usepackage{filecontents}
\begin{filecontents}{data.csv}
1
2
2.5
2
1
3.5
3
1
3
2
1
1
0.5
1
1.5
1
\end{filecontents}
\begin{document}
\begin{gnuplot}[terminal=cairolatex,terminaloptions={pdf color}]
set xrange [0:4]
set yrange [0:8]
set style fill solid 1
plot 'data.csv' using 1:(1) smooth frequency with boxes title 'Data'
\end{gnuplot}
\end{document}


# Output

-
I finally got gnuplot inside tex working, based on your sample. Thanks! –  citronas Jun 3 at 15:29

Although is not a pure LaTeX approarch, may be an alternative to someone could be a Sweave (.Rnw) file, that R can convert in a true .tex file.

With a well configured LaTeX editor as TeXworks, or RStudio this is not extra work for the user, as you simply edit the .Rnw file an the PDF file is compiled with one click, without dealing with R nor intermediate LaTeX files.

With this approach is easy make non-uniform bins histograms (with option breaks in the R plot) and set the x-axis range (option xlim):

\documentclass{article}
\begin{document}
\SweaveOpts{concordance=TRUE}

Automatic breaks with range fixed:

<<examplea,echo=F,fig=T,height=3>>=
hist(sample$X1, xlim=c(0,4), main="",xlab="", ylab="", col="orange") @ Manual uneven breaks: <<exampleb,echo=F,fig=T,height=3>>= hist(sample$X1, breaks=c(0.5,1,1.5,3.5),freq=T, main="",xlab="", ylab="", col="cyan")
@

Automatic fixed breaks at these values:

<<examplec,echo=F,fig=T,height=3>>=
mybreaks <- as.vector(exp(seq(log(.01),log(6),by=0.5)))
mybreaks
hist(sample\$X1, breaks=mybreaks, freq=T,main="",xlab="", ylab="", col="red")
@

\end{document}

-
+1 thanks! I think maybe this is better regarding performance! the performance of the pure tex version are not so good (is quite slow) and so if someone have big data file he should use this alternative! –  G M Jan 15 at 11:09