How to Draw CDF of normal distribution in Tikz

Does anyone know how to draw the Cumulative distribution function of Normal Distribution (explained here) in tikzpicture environment? Many thanks!

-
Not everybody needs to know the terms you have provided on TeX.SX though many users are working mathematicians. Please provide your own effort in terms the definitions and the things you have tried otherwise it's not easy for us to solve your problem. – percusse Jun 23 '12 at 13:16
Also related tex.stackexchange.com/q/31708/3235 – percusse Jun 23 '12 at 13:20

One way to do so is to use pgfplots and interact with Gnuplot. In facts Gnuplot here is useful because of the erf function.

Here is a simple example to be compiled with pdflatex -shell-escape:

\documentclass{minimal}
\usepackage{amsmath}
\usepackage{pgfplots}

\def\cdf(#1)(#2)(#3){0.5*(1+(erf((#1-#2)/(#3*sqrt(2)))))}%
% to be used: \cdf(x)(mean)(variance)

\DeclareMathOperator{\CDF}{cdf}

\begin{document}
\begin{tikzpicture}
\begin{axis}[%
xlabel=$x$,
ylabel=$\CDF(x)$,
grid=major]
\end{axis}
\end{tikzpicture}
\end{document}


Result:

Notice that the function \cdf has been defined by means of \def to have () delimiters around arguments.

-

Note that in newer versions of gnuplot there is the "norm" function that plots the standard normal cdf.

 \addplot [very thick] gnuplot{norm(x)};

-

If you want to avoid using gnuplot to do the calculations, you can use an approximation of the normal CDF like the very nice and simple one given by Bowling et al (which John D. Cook shows in his blog):

\tikzset{
declare function={
normcdf(\x,\m,\s)=1/(1 + exp(-0.07056*((\x-\m)/\s)^3 - 1.5976*(\x-\m)/\s));
}
}


The maximum error is given as 0.014%, which is more than sufficient for visualization purposes.

Here's a comparison of the gnuplot version and Bowling et al's approximation:

\documentclass[border=5mm]{standalone}
\usepackage{amsmath}
\usepackage{pgfplots}
\DeclareMathOperator{\CDF}{cdf}

\def\cdf(#1)(#2)(#3){0.5*(1+(erf((#1-#2)/(#3*sqrt(2)))))}%

\tikzset{
declare function={
normcdf(\x,\m,\s)=1/(1 + exp(-0.07056*((\x-\m)/\s)^3 - 1.5976*(\x-\m)/\s));
}
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[%
xlabel=$x$,
ylabel=$\CDF(x)$,
grid=major,
legend entries={gnuplot, Bowling et al},
legend pos=south east]
\end{axis}
\end{tikzpicture}
\end{document}

-

Another way is via Asymptote, which also has a built-in erf function. cdfs.tex:

\documentclass{article}
\usepackage{lmodern}
\usepackage[inline]{asymptote}
\begin{asydef}
import graph;
defaultpen(currentpen+fontsize(10pt));
typedef real realFunc(real);

struct cdfGraph{

real xMin, xMax, yMin, yMax;

real cdfnormal(real x, real mu, real sigmaSquared){
return 0.5*(1+erf((x-mu)/sqrt(2sigmaSquared)));
}

realFunc[] cdf;
pen[] curvePen;
string[] curveLegend;

void add(real mu=0, real sigmaSquared=1,pen p=currentpen){
cdf.push(new real(real x){return cdfnormal(x,mu,sigmaSquared);});
curvePen.push(p);
curveLegend.push("$\mu="+string(mu)+",\," +"\sigma^2="+string(sigmaSquared)+"$");
}

void drawAxes(){
xaxis(Label("$x$",0.5),BottomTop,xMin,xMax
,LeftTicks(Step=1,step=0.5,extend=true
,pTick=gray(0.3),ptick=gray(0.6)
)
);
yaxis(Label("$\Phi_{\mu,\sigma^2}(x)$",0.5)
,LeftRight,yMin,yMax
,RightTicks(Step=0.2,step=0.1,extend=true
,pTick=gray(0.3),ptick=gray(0.6)
,trailingzero
)
);
}

void draw(){
for(int i=0;i<cdf.length;++i){
draw(graph(cdf[i],xMin,xMax),curvePen[i],curveLegend[i]);
}
drawAxes();
}

void operator init(real xMin=-5, real xMax=5,real yMin=0, real yMax=1){
this.xMin=xMin;
this.xMax=xMax;
this.yMin=yMin;
this.yMax=yMax;
}
}
\end{asydef}

\begin{document}
\begin{figure}
\begin{asy}
size(300,200,IgnoreAspect);

cdfGraph g=cdfGraph();

real w=1bp;

g.draw();
\end{asy}
\caption{Cumulative distribution function}
\end{figure}
\end{document}


To process it with latexmk, create file latexmkrc:

sub asy {return system("asy '$_[0]'");} add_cus_dep("asy","eps",0,"asy"); add_cus_dep("asy","pdf",0,"asy"); add_cus_dep("asy","tex",0,"asy");  and run latexmk -pdf cdfs.tex. The solution consists of two parts: • asydef environment (in the preamble), which defines the struct cdfGraph, • and the asy picture environment that actually uses it. - Here is some code that may help. \begin{tikzpicture}[domain=0:4, yscale=4] \def\cumulative{\x,{1/(1 + exp((0-\x))}} \def\betaA{\x,{1/(1 + (0.25*exp(0-\x))}} \def\betaB{\x,{1/(1 + (0.5*exp(0-\x))}} \def\betaC{\x,{1/(1 + (5*exp(0-\x))}} \def\betaD{\x,{1/(1 + (15*exp(0-\x))}} \draw[very thin,color=gray, step=0.25] (-6.1,-0.025) grid (5.9,1.025) ; \draw[very thick, ->] (-6.1,0) -- (6,0) node[right] {Project Time} ; \draw[very thick, ->] (-6,-0.025) -- (-6,1.2) node[above] {\% Budget }; \draw[thick,color=red,domain=-6:6] plot (\cumulative); \draw[thick,color=green,domain=-6:4] plot (\betaA) node[above left] {$\beta = 0.05$}; \draw[thick,color=blue,domain=-6:5] plot (\betaB) node[above] {$\beta = 0.25$}; \draw[thick,color=cyan,domain=-6:6] plot (\betaC) node[right] {$\beta = 5.00$}; \draw[thick,color=magenta,domain=-6:6] plot (\betaD) node[below right] {$\beta = 15.00$}; \node at (-6.4,0.25) {25\%}; \node at (-6.4,0.50) {50\%}; \node at (-6.4,0.75) {75\%}; \node at (-6.5,1.0) {100\%}; \node at (0,-.1){\textbf{Effect of Changing$\beta\$}};
\end{tikzpicture}

-