14

I'm trying to plot the pmf of the binomial distribution for particular values of N and p. For example, when N=10 and p=0.5:

\documentclass{article}
\usepackage{amsmath}
\usepackage{pgfplots}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (10,0);
\foreach \x in {1,2,...,10} \draw (\x,10!/(\x!*(10-\x!))*(0.5)^\x*(0.5)^(10-\x)) circle (2pt);
\end{tikzpicture}
\end{document}

What I essentially what is a discrete plot of 10 points, where k is along the x-axis and the probability is plotted on the y-axis. That coordinate seems so complicated that I'm guessing there is a simpler way to approach this?

user21359
  • 1,449

1 Answers1

28

You can use PGFPlots for creating plots of functions (and of data files):

The binomial function isn't defined in the math engine, but you can define it yourself using the key

declare function={binom(\k,\n,\p)=\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k);}

Then you can plot the function using

\documentclass{article}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}[
    declare function={binom(\k,\n,\p)=\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k);}
]
\begin{axis}[
    samples at={0,...,40},
    yticklabel style={
        /pgf/number format/fixed,
        /pgf/number format/fixed zerofill,
        /pgf/number format/precision=1
    }
]
\addplot [only marks, cyan] {binom(x,40,0.2)}; \addlegendentry{$p=0.2$}
\addplot [only marks, orange] {binom(x,40,0.5)}; \addlegendentry{$p=0.5$}
\end{axis}
\end{tikzpicture}
\end{document}

To get a histogram, set ybar=0pt, bar width=1 in the axis options (make sure that you've set \pgfplotsset{compat=1.7} or newer in the preamble for this):

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}

\begin{document}
\begin{tikzpicture}[
    declare function={binom(\k,\n,\p)=\n!/(\k!*(\n-\k)!)*\p^\k*(1-\p)^(\n-\k);}
]
\begin{axis}[
    samples at={0,...,40},
    yticklabel style={
        /pgf/number format/fixed,
        /pgf/number format/fixed zerofill,
        /pgf/number format/precision=1
    },
    ybar=0pt, bar width=1
]
\addplot [fill=cyan, fill opacity=0.5] {binom(x,40,0.2)}; \addlegendentry{$p=0.2$}
\addplot [fill=orange, fill opacity=0.5] {binom(x,40,0.5)}; \addlegendentry{$p=0.5$}
\end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • Thank you! Is there anyway to make this into a histogram plot? – user21359 Sep 13 '14 at 22:37
  • 1
    @user21359: I've edited my answer to show how to get a histogram. – Jake Sep 14 '14 at 10:33
  • Hi, I tried plotting your code, but I don't get the image you have. It doesn't produce a histogram, even with ybar=0pt, bar width=1 added to the axis environment. – user21359 Sep 14 '14 at 18:39
  • 1
    @user21359: Sorry, I had pasted the old code twice. I've corrected the post now. – Jake Sep 14 '14 at 19:05
  • 1
    There are two 0.1s in ytick labels. – Z.H. Mar 29 '15 at 10:02
  • I know that this is quite a few time since an answer was given to the OP. I used it for my own document and it did work very well. --- When i recently tried to compile I found that there is an issue with babels french option. Does anyone know how to fix this? Just use one of the codes above and add \usepackage[french]{babel} to it. Thanks! – rsa-krypto Jul 18 '19 at 00:50
  • @Z.H. I'm guessing that the decimal fractions (0.05, 0.1, 0.15) are rounded off to one decimal place. Obviously, this is not accurate, and the code should be modified. – ahorn Jun 27 '20 at 10:10