I was trying to learn some histograms tools in gnuplot, I made the following script
set samples 500
set table "set1.dat"
plot [0:10] 5+2*rand(0)
unset table
set table "set2.dat"
plot [0:10] 10*rand(0)
unset table
rmin = 0.0
rmax = 10.0
nbins = 20.0
binwidth = (rmax-rmin)/nbins
bin(x,w) = w*(floor((x-rmin)/w)+0.5)+rmin
set table "h1.dat"
plot "set1.dat" u (bin($2,binwidth)):(1.0) smooth freq w boxes noti
unset table
set table "h2.dat"
plot "set2.dat" u (bin($2,binwidth)):(1.0) smooth freq w boxes noti
unset table
I want to plot the histograms h1 and h2 on top of each other (rowstack
). It should be noted at that point, that h1.dat
and h2.dat
have a last line marked u
(instead of i
), which somehow appears to screw the plot. I then tried the following
set style data histogram
set style histogram rowstack
set boxwidth 0.9*binwidth
plot "< grep i h2.dat" u 1:2 w boxes noti, "< grep i h1.dat" u 1:2 w boxes noti
Which gives me
Individually, the two histograms are fine. But they hardly follow the rowstack
-stacking approach. I tried replacing the u 1:2
by u 2
as all examples around seem to be using that. But then the bins are placed on every units instead of every half units. Which I suppose, I could solve by using u 2:xtic(1)
. But in any case the second (red) histogram is moved down the the left side of the spectrum.
My question is then quite simple: why doesn't the second histogram stack on top of the first one?
You don't need external tools or scripts for this task. You simply need a few extra lines in gnuplot.
If the x-ranges of your two histograms are not the same, you simply have to make them the same, but how?
Since gnuplot 5.0 you can print to datablocks via with table
. With this you can simply append datablocks.
So, append $Histo1
and $Histo2
into a new table $Histo3
. Apply smooth freq
on $Histo3
and you will get the sum of $Histo1
and $Histo2
in $Histo4
.
Now, you plot $Histo4
with the color you want for $Histo1
and afterwards $Histo2
on top.
Unless you want transparent boxes you can use this to "mimic" a stacked histogram.
You can do the same "trick" for impulses: How to stack impulses in Gnuplot
Script: (works with gnuplot 5.0.0, Jan 2015)
### stack histograms with different x-ranges
reset session
# create some random test data
set samples 500
set table $Data1
plot [0:10] 5+2*rand(0)
set table $Data2
plot [0:10] 10*rand(0)
unset table
rmin = 0.0
rmax = 10.0
nbins = 20.0
binwidth = (rmax-rmin)/nbins
bin(x,w) = w*(floor((x-rmin)/w)+0.5)+rmin
set table $Histo1
plot $Data1 u (bin($2,binwidth)):(1.0) smooth freq
set table $Histo2
plot $Data2 u (bin($2,binwidth)):(1.0) smooth freq
unset table
set table $Histo3
plot $Histo1 u 1:2 w table
plot $Histo2 u 1:2 w table
set table $Histo4
plot $Histo3 u 1:2 smooth freq
unset table
# set offsets 0,0,0,0
set yrange [0:]
set key out
set grid y
set boxwidth 0.8 relative # for gnuplot<5.0.7 you should use: set boxwidth 0.4 absolute
set style fill solid 0.3
set multiplot layout 3,1
set ytics 40
plot $Histo1 u 1:2 w boxes lc "red" ti "Data1"
set ytics 10
plot $Histo2 u 1:2 w boxes lc "blue" ti "Data2"
set ytics 40
plot $Histo4 u 1:2 w boxes lc "red" ti "Data1", \
$Histo2 u 1:2 w boxes lc "blue" ti "Data2"
unset multiplot
### end of script
Result: