1

Variations on this question have been asked multiple times before, but I have been unsuccessful in getting them to work. I may be (and most likely am) just inept at statistics.

I wish to plot a normal curve on top of this histogram using the data contained in the CSV file.

Many answers I have seen create a normal/gauss function, but I have excluded this from the MWE in case there is another, simpler way to do it.

Any assistance would be appreciated!

The histogram seeking a normal curve.

MWE:

\begin{filecontents*}{data.csv}
A
2
3
4
2
3
4
5
6
9
9
1
\end{filecontents*}

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\usepackage{pgfplotstable}

\begin{document}

\begin{tikzpicture}
  \centering
\begin{axis}[
ybar interval,
/pgf/number format/.cd,
use comma,
1000 sep={},
title={Title},
xlabel={X Label},
ylabel={Y Label},
x label style={at={(axis description cs:0.5,-0.1)},anchor=north},
y label style={at={(axis description cs:0.05,0.5)},anchor=south},
xticklabel style={rotate=90, anchor=near xticklabel},
ytick distance=2,
width=\textwidth, %10.5cm
height=6cm,
ymin=0
]

%%%
\addplot +[
black,
fill=lightgray,
hist={bins=5,
data min=0,
data max=10,
}
] table[y=A, col sep=comma] {data.csv};

\end{axis}
\end{tikzpicture}
\end{document}
1
  • 1
    When you are saying "create a normal/gauss function" do you mean literally a Gaussian whose center, width and normalization you will provide, or are you seeing a way to extract the center and the width from the data and to draw the Gaussian then?
    – user121799
    Jan 22, 2019 at 0:12

1 Answer 1

2

Here is a proposal building on this answer.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
A
2
3
4
2
3
4
5
6
9
9
1
\end{filecontents*}

\usepackage{pgfplotstable}

\newcommand\GetMean[2]{% from https://tex.stackexchange.com/a/268942/121799
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
    create on use/new/.style={
    create col/expr={\pgfmathaccuma + \thisrow{#2}}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1} 
  \pgfmathsetmacro{\Sum}{\pgfplotsretval}
  \pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}
\newcommand\GetVariance[3]{
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
    create on use/new/.style={
    create col/expr={\pgfmathaccuma + (\thisrow{#2}-#3)^2}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1} 
  \pgfmathsetmacro{\SumSquares}{\pgfplotsretval}
  \pgfmathsetmacro{\Variance}{sqrt(\SumSquares)/\NumRows}
}


\begin{document}



\begin{tikzpicture}[declare function={%
gauss(\x,\y,\z)=1/(2*\z*sqrt(pi))*exp(-(\x-\y)^2/(2*\z^2));}]
\begin{axis}[
/pgf/number format/.cd,
use comma,
1000 sep={},
title={Title},
xlabel={X Label},
ylabel={Y Label},
x label style={at={(axis description cs:0.5,-0.1)},anchor=north},
y label style={at={(axis description cs:0.05,0.5)},anchor=south},
xticklabel style={rotate=90, anchor=near xticklabel},
ytick distance=2,
width=\textwidth, %10.5cm
height=6cm,
ymin=0
]

%%%
\addplot +[ybar interval,
black,
fill=lightgray,
hist={bins=5,
data min=0,
data max=10,
}
] table[y=A, col sep=comma] {data.csv};
\GetMean{data.csv}{A}

\GetVariance{data.csv}{A}{\Mean}

\addplot[no marks,domain=0:8,smooth,samples=51,thick,color=blue]{\Sum*gauss(x,\Mean,\Variance)};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

1
  • Thanks @marmot, this indeed does the trick. It has also made me realise I wasn't clear in my original question (largely because I don't know what I'm talking about). I'll post another question.
    – Craig
    Jan 22, 2019 at 7:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .