# How to plot trinomial distribution in tikz?

I am trying to plot a 3d probability mass function like below (probability histogram for trinomial distribution). Could not find anything helpful online for 3D discrete plotting like below given a function (joint pmf). Kindly help.

Function:

The pic is from the book here Page 132. Probability and Statistical Inference By Hoggs et al.

Update:
Thanks to @marmot, I have managed to bring to a level as below. Yet to understand his code fully though.

• Could you please add the function in form of a typed text? – user121799 Oct 28 '18 at 16:03
• I think there are a lot of parameters. In order to plot you have to pick particular values, I think. – manooooh Oct 28 '18 at 16:21
• oh sorry marmot just saw this comment now. – Parthiban Rajendran Oct 28 '18 at 18:16

Here is a proposal (1st EDIT: resolved dimension too large problems; 2nd EDIT: followed @AndréC's excellent suggestion to slightly redefine the cube plot mark. Redefining the cube mark actually allows one to get rid of one ugly point: unlike in my older answer, it is no longer necessary to cheat, i.e. to manually adjust the z ticks.). The colors of the faces of the 3D bars are set by the pgf keys cube top color and so on.

\documentclass[tikz,border=3.14pt]{standalone}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\pgfkeys{/tikz/.cd,
cube top color/.store in=\CubeTopColor,
cube top color=blue!60,
cube front color/.store in=\CubeFrontColor,
cube front color=blue!30,
cube side color/.store in=\CubeSideColor,
cube side color=blue!40,
}
\makeatletter
\pgfdeclareplotmark{my cube*}
{%
\pgfplots@cube@gethalf@x
\let\pgfplots@cube@halfx=\pgfmathresult
\pgfplots@cube@gethalf@y
\let\pgfplots@cube@halfy=\pgfmathresult
\pgfplots@cube@gethalf@z
\let\pgfplots@cube@halfz=\pgfmathresult
\pgfmathparse{0*\pgfplots@cube@halfz}
\let\pgfplots@cube@topz=\pgfmathresult
%
\pgfplotsifaxissurfaceisforeground{0vv}{%
\pgfsetfillcolor{\CubeFrontColor}
\pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathclose
\pgfusepathqfillstroke
}{%
\pgfsetfillcolor{\CubeFrontColor}
\pgfpathmoveto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathclose
\pgfusepathqfillstroke
}%
\pgfplotsifaxissurfaceisforeground{v0v}{%
\pgfsetfillcolor{\CubeSideColor}
\pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathclose
\pgfusepathqfillstroke
}{%
\pgfsetfillcolor{\CubeSideColor}
\pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathclose
\pgfusepathqfillstroke
}%
\pgfplotsifaxissurfaceisforeground{vv0}{%
\pgfsetfillcolor{\CubeTopColor}
\pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{-\pgfplots@cube@halfz}}%
\pgfpathclose
\pgfusepathqfillstroke
}{%
\pgfsetfillcolor{\CubeTopColor}
\pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
\pgfpathclose
\pgfusepathqfillstroke
}%
}
\makeatother

\begin{document}
\pgfmathsetmacro{\gconv}{2*326.32446}
% from https://tex.stackexchange.com/a/435234/121799
\begin{tikzpicture}[declare function={% (0.00001*\n!/(0.01*\x!*0.01*\y!*0.01*(\n-\x-\y)!))*
f(\x,\y,\px,\py,\n)=(0.000001*\n!/(0.01*\x!*0.01*\y!*0.01*(\n-\x-\y)!))*pow(\px,\x)*pow(\py,\y)*pow(1-\px-\py,\n-\x-\y);}] %
\pgfplotsset{set layers}
\begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={40}{40},
%x dir=reverse,
%y dir=reverse,
width=320pt,
height=280pt,
mesh,
%mesh/ordering=x varies,
z buffer=auto,%reverse xy seq,
xmin=-0.5,xmax=5.5,
ymin=-0.5,ymax=5.5,
zmin=0,zmax=0.3,
enlargelimits=upper,
ztick={0,0.15,0.3},
xtick=data,
extra tick style={grid=major},
ytick={0,...,5},xtick={0,...,5},
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$f(x,y)$},
minor tick num=1,
]
\path let \p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
\pgfextra{\pgfmathsetmacro{\conv}{2*\y1}
\ifx\gconv\conv
\typeout{z-scale\space good!}
\else
\typeout{Kindly\space consider\space setting\space the\space
prefactor\space of\space z\space to\space \conv}
\fi
};
\path let \p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
\pgfextra{\pgfmathsetmacro{\convx}{veclen(\x1,\y1)}
\typeout{One\space unit\space in\space x\space
direction\space is\space\convx pt}
};
\path let \p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
\pgfextra{\pgfmathsetmacro{\convy}{veclen(\x1,\y1)}
\typeout{One\space unit\space in\space y\space
direction\space is\space\convy pt}
};
\gconv*z \as \myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=\myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=24.3018pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=21.71275pt},%
scatter,only marks,
mark=my cube*,mark size=5,opacity=1,domain=0:5,domain y=0:5,samples=6,samples y=6]
{f(x,y,0.2,0.4,5)};
\end{axis}
\end{tikzpicture}
\end{document}


Notice that if you modify these plots, you may have to readjust \gconv as well as the x and y dimensions of the "cubes". However, the code will tell you which values you need to use.

• It would be much prettier if the sides were clearer than the upper faces. – AndréC Oct 28 '18 at 16:46
• @marmot I think OP meant lighter shade on the top surface as shown in question. – nidhin Oct 28 '18 at 16:48
• @AndréC I do not think that this will be straightforward unless one as willing to draw the thing row by row. – user121799 Oct 28 '18 at 17:06
• May be with \pgfdeclareplotmark ? – AndréC Oct 28 '18 at 17:23
• thank you @marmot again my saviour for the day, and yeah, darker shade on top and ligher on sides of the bars could help in perceiving the plot a lot. I thought once we figure out plotting,customization could be easier. – Parthiban Rajendran Oct 28 '18 at 17:36