How to plot this cascaded/waterfall python-type plot using TikZ
Clash Royale CLAN TAG#URR8PPP
up vote
10
down vote
favorite
I would like to make a plot of this equation
P_n = fracn^aa!exp[-n]
for different n
. How can I use this cascaded style from the TikZ/PGF examples, to plot P_n
(y-axis) with a (x-axis), for different values of n
(z-axis: the depth). The x-variable is integers, so I need a bar chart.
This post has received an answer here, but I wanted to resurrect the questions since the image style I would like is shown in this link. Instead of a continuous plot, I would have bar charts, but I would like an enveloping line for each waterfall plot that is tangential to all of the bar charts to clearly show the distributions.
tikz-pgf tikz-styles
add a comment |Â
up vote
10
down vote
favorite
I would like to make a plot of this equation
P_n = fracn^aa!exp[-n]
for different n
. How can I use this cascaded style from the TikZ/PGF examples, to plot P_n
(y-axis) with a (x-axis), for different values of n
(z-axis: the depth). The x-variable is integers, so I need a bar chart.
This post has received an answer here, but I wanted to resurrect the questions since the image style I would like is shown in this link. Instead of a continuous plot, I would have bar charts, but I would like an enveloping line for each waterfall plot that is tangential to all of the bar charts to clearly show the distributions.
tikz-pgf tikz-styles
add a comment |Â
up vote
10
down vote
favorite
up vote
10
down vote
favorite
I would like to make a plot of this equation
P_n = fracn^aa!exp[-n]
for different n
. How can I use this cascaded style from the TikZ/PGF examples, to plot P_n
(y-axis) with a (x-axis), for different values of n
(z-axis: the depth). The x-variable is integers, so I need a bar chart.
This post has received an answer here, but I wanted to resurrect the questions since the image style I would like is shown in this link. Instead of a continuous plot, I would have bar charts, but I would like an enveloping line for each waterfall plot that is tangential to all of the bar charts to clearly show the distributions.
tikz-pgf tikz-styles
I would like to make a plot of this equation
P_n = fracn^aa!exp[-n]
for different n
. How can I use this cascaded style from the TikZ/PGF examples, to plot P_n
(y-axis) with a (x-axis), for different values of n
(z-axis: the depth). The x-variable is integers, so I need a bar chart.
This post has received an answer here, but I wanted to resurrect the questions since the image style I would like is shown in this link. Instead of a continuous plot, I would have bar charts, but I would like an enveloping line for each waterfall plot that is tangential to all of the bar charts to clearly show the distributions.
tikz-pgf tikz-styles
asked Aug 7 at 17:55
Sid
590213
590213
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
11
down vote
accepted
Thanks for asking a new question! Note also that if you have more rows you'll need to extend the definition of mycolor
accordingly.
EDIT: Simplified the code and made it (as I think) much easier to customize by
- storing the function in
myf
. That is, if you have a different function, you'll only to adjust this bit. - adding explanations in the code.
- replacing the single
pgfplotsinvokeforeach
loop in a double loop over the parameters (a
andn
in your question).
Thats the code.
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^X/X!)*exp(-Y);
defamax5 %<- maximal a
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfmathtruncatemacroNumRows6
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
UPDATE: If you want to go to higher values of a
and/or n
, it might be worthwhile to rewrite your function, which is in the above of the form
(huge/large)*small
in the form
(not so huge/large)*((not so huge)*small) .
Here is an example. I do not claim that it is optimal, that's the first thing that came to my mind. Alternatives include to take the logarithms of subexpressions and taking the exponential at the end. (I compile with lualatex
.)
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Just for fun: if you wish to have bars instead of Gaussians (Gauss was a mathematician and in a bar one gets good drinks ;-), and also do not want the envelop touch the axis, do
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
pgfmathsetmacromyBarWidth0.2
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(1,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black] coordinates (-myBarWidth+X,Y,0)
(-myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,0);
myplot
xdefmyLstmyLst (amax,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,tension=0.2,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you changea
for, say, 10, then the waveforms don't follow the height of the bars.
– Sid
Aug 7 at 22:19
@Sid You can adjust thetension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima withtension=1
. And I cannot plot your function toamax=10
, how do you compile it? I get an! Arithmetic overflow.
error.
– marmot
Aug 7 at 22:29
 |Â
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
accepted
Thanks for asking a new question! Note also that if you have more rows you'll need to extend the definition of mycolor
accordingly.
EDIT: Simplified the code and made it (as I think) much easier to customize by
- storing the function in
myf
. That is, if you have a different function, you'll only to adjust this bit. - adding explanations in the code.
- replacing the single
pgfplotsinvokeforeach
loop in a double loop over the parameters (a
andn
in your question).
Thats the code.
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^X/X!)*exp(-Y);
defamax5 %<- maximal a
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfmathtruncatemacroNumRows6
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
UPDATE: If you want to go to higher values of a
and/or n
, it might be worthwhile to rewrite your function, which is in the above of the form
(huge/large)*small
in the form
(not so huge/large)*((not so huge)*small) .
Here is an example. I do not claim that it is optimal, that's the first thing that came to my mind. Alternatives include to take the logarithms of subexpressions and taking the exponential at the end. (I compile with lualatex
.)
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Just for fun: if you wish to have bars instead of Gaussians (Gauss was a mathematician and in a bar one gets good drinks ;-), and also do not want the envelop touch the axis, do
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
pgfmathsetmacromyBarWidth0.2
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(1,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black] coordinates (-myBarWidth+X,Y,0)
(-myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,0);
myplot
xdefmyLstmyLst (amax,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,tension=0.2,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you changea
for, say, 10, then the waveforms don't follow the height of the bars.
– Sid
Aug 7 at 22:19
@Sid You can adjust thetension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima withtension=1
. And I cannot plot your function toamax=10
, how do you compile it? I get an! Arithmetic overflow.
error.
– marmot
Aug 7 at 22:29
 |Â
show 1 more comment
up vote
11
down vote
accepted
Thanks for asking a new question! Note also that if you have more rows you'll need to extend the definition of mycolor
accordingly.
EDIT: Simplified the code and made it (as I think) much easier to customize by
- storing the function in
myf
. That is, if you have a different function, you'll only to adjust this bit. - adding explanations in the code.
- replacing the single
pgfplotsinvokeforeach
loop in a double loop over the parameters (a
andn
in your question).
Thats the code.
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^X/X!)*exp(-Y);
defamax5 %<- maximal a
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfmathtruncatemacroNumRows6
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
UPDATE: If you want to go to higher values of a
and/or n
, it might be worthwhile to rewrite your function, which is in the above of the form
(huge/large)*small
in the form
(not so huge/large)*((not so huge)*small) .
Here is an example. I do not claim that it is optimal, that's the first thing that came to my mind. Alternatives include to take the logarithms of subexpressions and taking the exponential at the end. (I compile with lualatex
.)
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Just for fun: if you wish to have bars instead of Gaussians (Gauss was a mathematician and in a bar one gets good drinks ;-), and also do not want the envelop touch the axis, do
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
pgfmathsetmacromyBarWidth0.2
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(1,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black] coordinates (-myBarWidth+X,Y,0)
(-myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,0);
myplot
xdefmyLstmyLst (amax,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,tension=0.2,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you changea
for, say, 10, then the waveforms don't follow the height of the bars.
– Sid
Aug 7 at 22:19
@Sid You can adjust thetension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima withtension=1
. And I cannot plot your function toamax=10
, how do you compile it? I get an! Arithmetic overflow.
error.
– marmot
Aug 7 at 22:29
 |Â
show 1 more comment
up vote
11
down vote
accepted
up vote
11
down vote
accepted
Thanks for asking a new question! Note also that if you have more rows you'll need to extend the definition of mycolor
accordingly.
EDIT: Simplified the code and made it (as I think) much easier to customize by
- storing the function in
myf
. That is, if you have a different function, you'll only to adjust this bit. - adding explanations in the code.
- replacing the single
pgfplotsinvokeforeach
loop in a double loop over the parameters (a
andn
in your question).
Thats the code.
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^X/X!)*exp(-Y);
defamax5 %<- maximal a
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfmathtruncatemacroNumRows6
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
UPDATE: If you want to go to higher values of a
and/or n
, it might be worthwhile to rewrite your function, which is in the above of the form
(huge/large)*small
in the form
(not so huge/large)*((not so huge)*small) .
Here is an example. I do not claim that it is optimal, that's the first thing that came to my mind. Alternatives include to take the logarithms of subexpressions and taking the exponential at the end. (I compile with lualatex
.)
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Just for fun: if you wish to have bars instead of Gaussians (Gauss was a mathematician and in a bar one gets good drinks ;-), and also do not want the envelop touch the axis, do
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
pgfmathsetmacromyBarWidth0.2
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(1,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black] coordinates (-myBarWidth+X,Y,0)
(-myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,0);
myplot
xdefmyLstmyLst (amax,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,tension=0.2,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Thanks for asking a new question! Note also that if you have more rows you'll need to extend the definition of mycolor
accordingly.
EDIT: Simplified the code and made it (as I think) much easier to customize by
- storing the function in
myf
. That is, if you have a different function, you'll only to adjust this bit. - adding explanations in the code.
- replacing the single
pgfplotsinvokeforeach
loop in a double loop over the parameters (a
andn
in your question).
Thats the code.
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^X/X!)*exp(-Y);
defamax5 %<- maximal a
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfmathtruncatemacroNumRows6
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
UPDATE: If you want to go to higher values of a
and/or n
, it might be worthwhile to rewrite your function, which is in the above of the form
(huge/large)*small
in the form
(not so huge/large)*((not so huge)*small) .
Here is an example. I do not claim that it is optimal, that's the first thing that came to my mind. Alternatives include to take the logarithms of subexpressions and taking the exponential at the end. (I compile with lualatex
.)
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(0,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black,smooth,
domain=-0.4:0.4] (x+X,Y,myf(X,Y)*exp(-SteepNess*x^2));
myplot
xdefmyLstmyLst (amax+1,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
Just for fun: if you wish to have bars instead of Gaussians (Gauss was a mathematician and in a bar one gets good drinks ;-), and also do not want the envelop touch the axis, do
documentclass[border=3.14mm]standalone
usepackagepgfplots
% if you plot more than 6 rows, you'll need to extend the following
% definition accordingly. alternatively you could work with color maps here.
newcommandmycolor[1]ifcase#1
white%0
or
blue%1
or
red%2
or
green!50!black%3
or
yellow%4
or
purple%5
or
orange%6
or
cyan%7
or
brown%8
or
red!50!black%9
or
blue!50!black%10
fi
pgfplotssetcompat=1.16
begindocument
tikzsetdeclare function=myf(X,Y)=((Y)^(X/2)/X!)*((Y)^(X/2)*exp(-Y));
defamax7 %<- maximal a
pgfmathtruncatemacroNumRows7
pgfmathsetmacromyBarWidth0.2
defSteepNess48 % <- this value determines the shape of the Gaussians. if
% you have different function myf, you may need to adjust it
begintikzpicture
beginaxis[width=9cm,
set layers=standard,
domain=0:amax+1,
samples y=1,
view=4020,
xmin=-1,ymax=amax+3,
%hide axis,
%xtick=empty, ytick=empty, ztick=empty,
clip=false
]
pgfplotsinvokeforeachNumRows,...,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);
pgfmathtruncatemacroXmaxNumRows*amax
foreach Y in 1,...,NumRows
xdefmyLst(1,Y,0) % initialize the list for envelopes
foreach X in 1,...,amax
pgfmathsetmacromymaxmyf(X,Y) %<- this is not absolutely necessary
xdefmyLstmyLst (X,Y,mymax) % build up the list
edefmyplotnoexpandaddplot3 [fill=mycolorY,fill opacity=0.4,
line width=0.7pt,on layer=main,draw=black] coordinates (-myBarWidth+X,Y,0)
(-myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,myf(X,Y)*exp(-SteepNess*0^2))
(myBarWidth+X,Y,0);
myplot
xdefmyLstmyLst (amax,Y,0) % complete the list
edefmyplotnoexpandaddplot3[smooth,tension=0.2,fill=mycolorY,fill opacity=0.1] coordinatesmyLst;
% if you do not want to have the envelope, just comment the following out
myplot
endaxis
endtikzpicture
enddocument
edited Aug 7 at 23:23
answered Aug 7 at 18:03


marmot
54.6k459117
54.6k459117
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you changea
for, say, 10, then the waveforms don't follow the height of the bars.
– Sid
Aug 7 at 22:19
@Sid You can adjust thetension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima withtension=1
. And I cannot plot your function toamax=10
, how do you compile it? I get an! Arithmetic overflow.
error.
– marmot
Aug 7 at 22:29
 |Â
show 1 more comment
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you changea
for, say, 10, then the waveforms don't follow the height of the bars.
– Sid
Aug 7 at 22:19
@Sid You can adjust thetension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima withtension=1
. And I cannot plot your function toamax=10
, how do you compile it? I get an! Arithmetic overflow.
error.
– marmot
Aug 7 at 22:29
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
You're welcome. This looks great! Is it possible to add a waveform that envelopes each of the coloured distributions?
– Sid
Aug 7 at 18:08
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
Fantastic! These waterfall plots are quite common in python's matplotlib package. Hopefully, many others can make use of this for a more native plot to LaTeX!
– Sid
Aug 7 at 18:50
image link is broken for me
– qwr
Aug 7 at 21:36
image link is broken for me
– qwr
Aug 7 at 21:36
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you change
a
for, say, 10, then the waveforms don't follow the height of the bars.– Sid
Aug 7 at 22:19
@marmot, if you look closely, some of the envelopes have some kink along the waveform. Also if you change
a
for, say, 10, then the waveforms don't follow the height of the bars.– Sid
Aug 7 at 22:19
@Sid You can adjust the
tension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima with tension=1
. And I cannot plot your function to amax=10
, how do you compile it? I get an ! Arithmetic overflow.
error.– marmot
Aug 7 at 22:29
@Sid You can adjust the
tension
of these plots. Or one would have to resort to more elaborate means, at the moment it is really just a smooth interpolation of the maxima with tension=1
. And I cannot plot your function to amax=10
, how do you compile it? I get an ! Arithmetic overflow.
error.– marmot
Aug 7 at 22:29
 |Â
show 1 more comment
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f445015%2fhow-to-plot-this-cascaded-waterfall-python-type-plot-using-tikz%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password