gnuplot histogram chart with overlap - gnuplot

I would like to plot a bar chart or histogram like this in gnuplot.
I tried set style histogram rowstacked which is a start but it adds the columns on top of each other while I need them overlapped. Next is the issue of transparent color shading.
Thanks for your feedback.
UPDATE: user8153 asked for additional data.
The set style histogram clustered gap 0.0 is doing the cluster mode of the histogram bars. If you blur the eye it sort-of shows what I want but with overlap and transparent shading.
The only other histogram modes given in the docs are rowstacked and columnstacked. I never got a plot out of columnstacked so I discarded it. Now rowstacked stacks the histogram bars.
The overlay appearance is there but it is wrong. I don't want the stacked appearance. The histograms have to overlay.
Code :
set boxwidth 1.0 absolute
set style fill solid 0.5 noborder
set style data histogram
set style histogram clustered gap 0.0
#set style histogram rowstacked gap 0.0
set xtics in rotate by 90 offset first +0.5,0 right
set yrange [0:8000]
set xrange [90:180]
plot 'dat1.raw' using 3 lc rgb 'orange', \
'dat2.raw' using 3 lc rgb 'blue', \
'dat3.raw' using 3 lc rgb 'magenta'
Thanks for your feedback.

Given a sample datafile test.dat
-10 4.5399929762484854e-05
-9 0.0003035391380788668
-8 0.001661557273173934
-7 0.007446583070924338
-6 0.02732372244729256
-5 0.0820849986238988
-4 0.20189651799465538
-3 0.4065696597405991
-2 0.6703200460356393
-1 0.9048374180359595
0 1.0
1 0.9048374180359595
2 0.6703200460356393
3 0.4065696597405991
4 0.20189651799465538
5 0.0820849986238988
6 0.02732372244729256
7 0.007446583070924338
8 0.001661557273173934
9 0.0003035391380788668
10 4.5399929762484854e-05
you can use the following commands
set style fill transparent solid 0.7
plot "test.dat" with boxes, \
"test.dat" u ($1+4):2 with boxes
to get the following result (using the pngcairo terminal):

Using transparency as in user8153's solution is certainly the easiest way to visualize an overlap of two histograms.
This works even if the two histogram do not have identical bins or x-data-ranges.
However, the color of the overlap is pretty much bound to the colors of the two histogram and the level of transparency. Furthermore, if you want to show the overlap in the key you have to do it "manually".
Here is a solution where you can choose an independent color for the overlap area.
The overlap is basically the minimum y-value from both histograms for each x-value.
For this you need to compare the y-values for each x-value. This can be done in gnuplot with some "trick" by merging the two files line by line. This requires the data in a datablock (how to get it there from a file). Since this merging procedure is using indexing of datablock lines, it requires gnuplot>=5.2.0.
This assumes that you have the same x-range and bins for each histogram. If this is not the case, you have to implement some further steps.
Script: (works with gnuplot>=5.2.0, Sept. 2017)
### plot overlap of two histograms
reset session
# create some random test data
set samples 21
f(x,a,b) = 1./(a*(x-b)**4+1)
set table $Data1
plot '+' u 1:(f(x,0.01,-2)) w table
set table $Data2
plot '+' u 1:(f(x,0.02,4)) w table
unset table
set boxwidth 1.0
set grid y
set ytics 0.2
set multiplot layout 2,1
set style fill transparent solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2"
set print $Overlap
do for [i=1:|$Data1|] { print $Data1[i].$Data2[i] }
set print
set style fill solid 0.3
plot $Data1 u 1:2 w boxes lc 1 ti "Data1", \
$Data2 u 1:2 w boxes lc 2 ti "Data2", \
$Overlap u 1:($2>$4?$4:$2) w boxes lc "red" ti "Overlap"
unset multiplot
### end of script
Result:

Related

Fitting a normalized histogram using gnuplot

I have a datafile containing N random numbers generated from a C-code. Now I want to normalize the histogram from this datafile and, then, fit it to a given distribution function. How can I do that?
This is my gnuplot code for the histogram plot:
width = 5000
hist(x,width)=width*floor(x/width)+width/2.0
set boxwidth width
set style fill solid 0.5
set xrange [0:500000]
set yrange [0:20]
plot "out.dat" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green"
Since gnuplot version 5.2 there is an new smoothing type smooth fnormal which does exactly that: sum up all values with same x-value and normalize the data so that the overall sum is 1.
A simple example:
set boxwidth 0.9
set style fill solid 0.5
set yrange [0:*]
$data <<EOD
1
1
2
2
2
3
3
EOD
set style data boxes
plot $data u 1:(1) smooth freq title 'smooth frequency',\
'' u 1:(1) smooth fnormal title 'smooth fnormal'
Applied to you example you must only update the actual plotting line to
plot "out.dat" u (hist($1,width)):(1.0/(sum)) smooth fnormal w boxes lc rgb "green"

GNUPLOT: Multiple histograms each with normalized bars

I'd like to start by saying I am very new to gnuplot. I am attempting to plot multiple stacked histograms that have been normalized so that the height of each bar is 1. I'd also prefer to no have to amend my data files to include the total as the last entry as I have a lot of data files to plot and this would take a lot of time. I've looked around and I know this can be done, but I have been unsuccessful in adapting examples I've found to work with the code I am using.
The data file I am using (shortened considerably) is named "Test.dat" and formatted as follows:
#a = 2
#b 1 2 3 X
b=1 1 3 1
b=2 0 1 1
#a = 4
b 1 2 3 X
b=1 1 1.5 1.5
b=2 1 2.1 1.9
Here each row beginning with b=x is meant to be a single bar, and there are two groups of two bars corresponding to an a=x. My .gp file currently looks like this:
set style data histogram
set style histogram rowstacked gap .5 title offset 0, -1
set style fill solid border -1
set boxwidth .75 relative
set yrange [0:]
unset xtics
plot \\
newhistogram "b=2" lt 1, for[col=2:4] 'Test.dat' index 0 u col:xtic(1) notitle \
,newhistogram "b=4" lt 1, for[col=2:4] 'Test.dat' index 1 u col:xtic(1) notitle \
This give the image, but this is what I would like to get. I'd appreciate any assistance you could provide.
You have missed a comment sign "#" in the second data bolck.
You have to separate each data block with 2 blank lines.
You are using "b=1" and "b=2" in the data file, but "b=2" and b=4 in the script.
Last: gnuplot is able to make stacked histograms, but there is no way to normalize them automatic, but manually :-/
set style data histogram
set style histogram rowstacked gap .5 title offset 0, -1
set style fill solid border -1
set boxwidth .75 relative
set yrange [0:]
unset xtics
plot \\\
newhistogram "b=1" lt 1, for[col=2:4] 'Test.dat' index 0 u (column(col)/$5):xtic(1) notitle, \
newhistogram "b=2" lt 1, for[col=2:4] 'Test.dat' index 1 u (column(col)/$5):xtic(1) notitle

Gnuplot columnstacked histogram with errorbars

Suppose I have the following data file, so-qn.dat:
Type on on-err off off-err
good 75 5 55 4
bad 15 2 30 3
#other 10 1 15 2
which contains values on columns 2 and 4 and corresponding error deltas on columns 3 and 5.
I can produce a columnstacked histogram:
#!/usr/bin/gnuplot
set terminal png
set output 'so-qn.png'
set linetype 1 lc rgb "blue" lw 2 pt 0
set linetype 2 lc rgb "dark-red" lw 2 pt 0
set style data histograms
set style histogram columnstacked
set style fill solid
set ylabel "% of all items"
set yrange [0:100]
set boxwidth 0.75
set xtics scale 0
set xlabel "Option"
plot 'so-qn.dat' using 2 ti col, \
'' using 4:key(1) ti col
But I can’t figure out how to add errorbars to this. The closest I got so far is with
plot 'so-qn.dat' using 2 ti col, '' using 2:3 with yerrorbars lc rgb 'black' ti col, \
'' using 4:key(1) ti col, '' using 4:5:key(1) with yerrorbars lc rgb 'black' ti col
which produces
but only one of the error bars is in the right spot (I actually have no idea where the bottom left one gets its y from), one is completely invisible (hidden behind the right stack?), and I’d like the error bars to not show up in the key.
Is it possible to combine column-stacked histograms and error bars?
You can add errorbars to column-stacked histograms by manually adding plot-commands for the errorbars. To do so, you need, however, to keep track of the y-positions.
Therefore, let's introduce two variables which store the y-position for each of the two columns' errorbars.
y1 = -2
y2 = -4
You need to initialize these variables with -(number of column)
Next, let us define two functions that update the variables y1, y2.
f1(x) = (y1 = y1+x)
f2(x) = (y2 = y2+x)
Now, generate the desired plot via
plot 'so-qn.dat' using 2 ti col, \
'' using 4:key(1) ti col, \
'' using (0):(f1($2)):3 w yerr t "", \
'' using (1):(f2($4)):5 w yerr t ""
As you can see, you can supress the errorbars in the key by assigning an empty title (t ""). This approach even gives you more flexibility in customizing the appearance of the errorbars (e.g., assign different linestyles etc.).
This being said, I personally think this visualization is rather confusing. You might want to consider another visualization:
set bars fullwidth 0
set style data histograms
set style fill solid 1 border lt -1
set style histogram errorbars gap 2 lw 2
plot 'so-qn.dat' using 2:3:xtic(1) ti columnhead(2), \
'' using 4:5:xtic(1) ti columnhead(4)

Gnuplot change color of bars in histogram

is it possible to change the color of bars in a Gnuplot script dynamically?
I have the following script
reset
fontsize = 12
set term postscript enhanced eps fontsize
set output "bargraph_speedup.eps"
set style fill solid 1.00 border 0
set style histogram
set style data histogram
set xtics rotate by -45
set grid ytics linestyle 1
set xlabel "Benchmarks" font "bold"
set ylabel "Relative execution time vs. reference implementation" font "bold"
set datafile separator ","
plot 'bm_speedup.dat' using 2:xtic(1) ti "Speedup" linecolor rgb "#00FF00"
which generates this plot:
Is it possible to make the color of the bars which are below zero red?
Thanks,
Sven
You can mimic this behavior using the boxes style:
My test data:
zip 2
baz 2
bar -1
cat 4
foo -3
And then plotting with gnuplot:
set style line 1 lt 1 lc rgb "green"
set style line 2 lt 1 lc rgb "red"
set style fill solid
plot 'test.dat' u (column(0)):2:(0.5):($2>0?1:2):xtic(1) w boxes lc variable
# #xval:ydata:boxwidth:color_index:xtic_labels
You could split your data file into two parts, positive values and negative, and plot them separately:
plot 'bm_speedup_pos.dat' using 2:xtic(1) ti "Faster" linecolor rgb "#00FF00", \
'bm_speedup_neg.dat' using 2:xtic(1) ti "Slower" linecolor rgb "#FF0000"
Or, if you only need to generate a few graphs, a few times, a common technique is to generate the raw graph in gnuplot, then post-process it in an image editor to adjust the colors. If you go that route, I suggest having gnuplot generate the graph in SVG format, which will give you much better looking graphs than any of the bitmap formats.
Doesn't seem like histogram lets you do it. May be like this:
set boxwidth 0.3
f(v)=v<0?1:2
plot 'bm_speedup.dat' using 0:2:(f($2)):xticlabels(1) with boxes ti "Speedup" lc variable
Actually you can also use linecolor rgb variable and give the color like this:
plot 'bm_speedup.dat' using 2:xtic(1):($2 >= 0 ? 0x00FF00 : 0xFF0000) ti Speedup lc rgb variable

Plotting graph using gnuplot

htmlResponseBytes 39842 397888
cssResponseBytes 109265 108988
imageResponseBytes 205179 206662
javascriptResponseBytes 468573 476888
otherResponseBytes 4326 4378
I want to plot Bar graph this data using gnuplot. 1st column should be present on x-axis, 2nd and 3rd column should be plotted using bar chart. 2nd column should have legend today and 3rd column should have legend yesterday. Also the values should be present on top of each bar.
I have tried this
reset
dx=5.
n=2
total_box_width_relative=0.75
gap_width_relative=0.1
d_width=(gap_width_relative+total_box_width_relative)*dx/2.
reset
set term png truecolor
set output "profit.png"
set xlabel "Year"
set ylabel "Profit(Million Dollars)"
set grid
set boxwidth total_box_width_relative/n relative
set style fill transparent solid 0.5 noborder
plot "profit.dat" u 1:2 w boxes lc rgb"green" notitle,\
"profit.dat" u ($1+d_width):3 w boxes lc rgb"red" notitle
Copied this code from here, works fine for his data file but doesn't work for mine data file pasted at the top
How about this:
set style data histogram
set style histogram cluster gap 1
set xtics rotate by 90
set style fill solid
plot 'test.dat' using 2:xtic(1) lc rgb "blue", \
'' using 3

Resources