答案1
好的,这是一个非常简化的版本。可以使其类似 3D,但这将需要付出更多努力。现在有 6 行(这个数字 6 由 控制\pgfplotsinvokeforeach{6,5,...,1}{
)梳子,每行 5 个\amax
齿(由 控制)。我将其保持在最低限度,因为我不知道您想要哪些功能。
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\def\amax{5} %<- maximal a
\begin{tikzpicture}
\begin{axis}[width=9cm,
set layers=standard,
domain=0:{\amax+1},
samples y=1,
view={20}{20},
xmin=-1,ymax=\amax+3,
%hide axis,
%xtick=\empty, ytick=\empty, ztick=\empty,
clip=false
]
\def\sumcurve{0}
\pgfplotsinvokeforeach{6,5,...,1}{ % your n will now be stored in #1
\draw [on layer=background, gray!20] (axis cs:0,#1,0) -- (axis cs:{\amax+1},#1,0);
\addplot3 [line width=3pt,on layer=main,scatter,scatter src=#1, ycomb, samples at={1,...,\amax}]
(x,#1,{((#1)^x/x!)*exp(-#1)});
}
\end{axis}
\end{tikzpicture}
\end{document}
只是为了好玩:3D 版本。缺点:你需要\gconv
在最后进行调整。代码会抱怨并告诉你该怎么做,但如果可以自动化就更好了,这是我无法实现的。
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.16}
\begin{document}
\def\amax{5} %<- maximal a
\begin{tikzpicture}
\begin{axis}[
set layers=standard,
domain=0:{\amax+1},
samples y=1,
view={40}{20},
xmax=\amax+1,
ymax=7,
zmax=1,
ymin=-1,
xmin=0,
xlabel={$a$},
ylabel={$n$},
zticklabels={}, % here one has to "cheat"
%hide axis,
%unit vector ratio*=1 2 1,
%xtick=\empty, ytick=\empty, ztick=\empty,
clip=false
]
\def\sumcurve{0}
\pgfmathsetmacro{\gconv}{195.28195} %<- you'll get told when you need to adjust this value
\pgfplotsinvokeforeach{6,5,...,1}{ % your n will now be stored in #1
\draw [on layer=background, gray!20] (axis cs:0,#1,0) -- (axis cs:{\amax+1},#1,0);
\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
};
\addplot3 [visualization depends on={
\gconv*rawz \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=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,samples at={1,...,\amax},
mark=cube*,mark size=5,opacity=1]
(x+0.5,#1-1,{((#1)^x/x!)*exp(-#1)});
}
\end{axis}
\end{tikzpicture}
\end{document}
既然你似乎对条形图和非常平滑的插值感兴趣,这里有一个建议。对于插值,我使用众所周知的性质,即阶乘可以通过欧拉伽马函数进行插值。Gamma(n+1)=n!
然后我更喜欢在 3D 图中使用 3D 条形图。在这里,我也使用了以下方法,color maps
而不是\mycolor
这个答案。
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
% gamma definition from https://tex.stackexchange.com/a/120449/121799
\tikzset{declare function={gamma(\z)=
(2.506628274631*sqrt(1/\z) + 0.20888568*(1/\z)^(1.5) +
0.00870357*(1/\z)^(2.5) - (174.2106599*(1/\z)^(3.5))/25920 -
(715.6423511*(1/\z)^(4.5))/1244160)*exp((-ln(1/\z)-1)*\z);
myf(\X,\Y)=((\Y)^(\X/2)/\X!)*((\Y)^(\X/2)*exp(-\Y));
myfcont(\X,\Y)=2*((\Y)^(\X/2)/gamma(\X+1))*((\Y)^(\X/2)*exp(-\Y));}}
% Note that there is some cheating involved. Therefore the factor 2
\usetikzlibrary{calc}
\pgfplotsset{compat=1.16}
\pgfplotsset{colormap={cm}{color(0)=(red) color(1)=(blue) color(2)=(green!50!black)
color(3)=(orange) color(4)=(cyan) color(5)=(purple)}}
\begin{document}
\pgfmathtruncatemacro{\amax}{5} %<- maximal a
\pgfmathtruncatemacro{\Xmax}{6} %<- maximal n
\begin{tikzpicture}
\begin{axis}[
set layers=standard,
domain=0:{\amax+1},
samples y=1,
view={40}{20},
xmax=\amax+1,
ymax=7,
zmax=1,
ymin=-1,
xmin=0,
xlabel={$a$},
ylabel={$n$},
zticklabels={}, % here one has to "cheat"
%hide axis,
%unit vector ratio*=1 2 1,
%xtick=\empty, ytick=\empty, ztick=\empty,
clip=false
]
\def\sumcurve{0}
\pgfmathsetmacro{\gconv}{194.6991} %<- you'll get told when you need to adjust this value
\pgfplotsinvokeforeach{\Xmax,...,1}{ % your n will now be stored in #1
\draw [on layer=background, gray!20] (axis cs:0,#1,0) -- (axis cs:{\amax+1},#1,0);
\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
};
\edef\myplot{\noexpand\addplot3 [point meta=rawy,visualization depends on={
\noexpand\gconv*rawz \noexpand\as \noexpand\myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=\noexpand\myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=10pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=2pt},%
scatter,only marks,samples at={1,...,\amax},
mark=cube*,mark size=5,opacity=0.5]
(x+0.5,#1-1,{myf(x,#1)});}
\myplot
\edef\myplot{\noexpand\addplot3 [name path=A,point meta=rawy,domain=1:\amax,
samples=50,opacity=0.5]
(x+0.5,#1-1,{myfcont(x,#1)});}
\myplot
\addplot3 [name path=B,draw=none] coordinates {(1.5,#1-1,0) (\amax+0.5,#1-1,0)};
\edef\myplot{\noexpand\addplot3 [opacity=0.2,index of colormap={#1-1 of cm}] fill between [of=A
and B];}
\myplot
}
\end{axis}
\end{tikzpicture}
\end{document}