Gnuplot columnstacked histogram with errorbars - gnuplot

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)

Related

gnuplot partially stacked bars

I would like to make a gnuplot graph with one full bar and another one stacked.
The data is something like
x data E M L
[10,20) 0.000000 1.081916 2.0958133 5.473606
[20,40) 0.000000 2.331769 2.1402838 4.528341
[40,80) 3.262375 2.201788 1.3499280 3.023847
>80 2.368121 2.132216 0.7322889 2.610368
where E, M and L are the three "green" components.
I have tried to do something like
set style data histograms
set style histogram rowstacked
#set style histogram cluster gap 1
set style fill solid
...
plot newhistogram, "size_class_data/tree_paracou.txt" using 2:xticlabel(1) linecolor rgb data_color title "Model",\
newhistogram, '' using 3:xticlabel(1) linecolor rgb early_color title "d",\
'' using 4 linecolor rgb mid_color title "g",\
'' using 5 linecolor rgb late_color title "f"
but the two graphs lie on two different parts of the x axis.
The newhistogram command has an option at for setting the coordinate of the first box.
In you case you can fix the boxwidth, and start the second histogram at 0 + boxwidth:
set style data histograms
set style histogram rowstacked
set style fill solid
set boxwidth 0.33 absolute
plot "foo.dat" using 2:xticlabel(1) skip 1 linecolor rgb "black" title "Model",\
newhistogram at 0.33, '' using 3 skip 1 linecolor rgb "red" title "d",\
'' using 4 skip 1 linecolor rgb "green" title "g",\
'' using 5 skip 1 linecolor rgb "blue" title "f"

gnuplot histogram chart with overlap

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:

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

plotting fitted linear graphs at two different horizontal range values

I am plotting two graphs using gnuplot. First plot is actual data and the second one is the fitting of the data.
The script I used for plotting this is shown here below:
#!/usr/bin/gnuplot
reset
set terminal png enhanced
set terminal pngcairo enhanced color dashed
set output 'msd-maltoLyo12per-225ns.png'
##########################################
set macros
labelSIZE="font 'Arial,24'"
ticFONT="font 'Arial,16"
set key font 'Arial,14'
set key spacing 1.5 samplen 5
##########################################
set xrange [0:225]
set yrange [0:11000]
set xtic #ticFONT
set ytic #ticFONT
set xtics out nomirror
set ytics out nomirror
##############################
set style line 1 lt 1 lc rgb "red" lw 2.0
set style line 2 lt 2 lc rgb "blue" lw 2.0
set style line 3 lt 3 lc rgb "coral" lw 2.0
set style line 4 lt 4 lc rgb "green" lw 2.0
set style line 5 lt 5 lc rgb "black" lw 2.0
##############################
f(x)=a+b*x
fit [120:225] f(x) 'diff-xy-maltoLyo12per.dat' via a,b
plot 'diff-xy-maltoLyo12per.dat' using 1:2 with lines linestyle 1 title "{/Symbol b}Mal-C_{12}", f(x) lw 3.0 lc rgb 'black'
Here I plot the fitting graph from 1 to 120 as shown . Also I want to plot the same graph from range 120 to 225 as in the picture .
Now I want a single plot which contain the two black lines and the red line.
How can I achieve this?
Thanks in advance.
Working with the script you already have, you can use two functions to fit in the different ranges separately, and then use a conditional plot that selects one if x < 120 and the other one if x > 120:
f1(x)=a1+b1*x
fit [0:120] f1(x) 'diff-xy-maltoLyo12per.dat' via a1,b1
f2(x)=a2+b2*x
fit [120:225] f2(x) 'diff-xy-maltoLyo12per.dat' via a2,b2
f(x) = x < 120 ? f1(x) : f2(x)
plot 'diff-xy-maltoLyo12per.dat' using 1:2 with lines linestyle 1 title "{/Symbol b}Mal-C_{12}", f(x) lw 3.0 lc rgb 'black'
Now, the way I would go about this, would be to generate a special fitting function, whose parameters would give me the point at which the slope changes as a result of the fitting itself. Say you call that point x0 (for which the value of the function is y0), the slope at the left of it is m1 and the slope at the right m2. Then the function at the left has the form m1*(x-x0)+y0 and the function at the right has the form m2*(x-x0)+y0. The overall function can be defined in gnuplot as:
f(x) = x < x0 ? m1*(x-x0)+y0 : m2*(x-x0)+y0
and you can fit f(x) "data" via x0, m1, m2, y0. You can also generate this function without the condition using a step function:
f(x) = m1*(x-x0)*(sgn(x0-x)+1)/2 + m2*(x-x0)*(sgn(x-x0)+1)/2 + y0
After you fit, for which you might need to provide some initial values, you can print x0 and you'll get the best value (that should be close to 120 in your case, as you know) for the position of the change in slope.

GNUplot - plot data file (simple X and Y columns) - setting suitable color and scale on a figure

I have a simple file with two columns:
1 0.005467
2 0.005333
3 0.005467
4 0.005467
5 0.005600
6 0.005600
7 0.005467
8 0.005467
In the first column I have the x-axis values, while on the second column I have y-axis values. I would like to plot a figure of this data. I wrote a gnuplot script for this:
#!/usr/bin/gnuplot
set xlabel "test"
set ylabel "value"
set grid ytics lt 0 lw 1 lc rgb "#bbbbbb"
set grid xtics lt 0 lw 1 lc rgb "#bbbbbb"
set autoscale
set terminal postscript portrait enhanced mono dashed lw 1 'Helvetica' 14
set style line 1 lt 1 lw 3 pt 3 linecolor rgb "red"
set output 'out.eps'
plot 'data.txt' using 2:1 w points title "tests"
And, the output:
But of course, as a newbie in gnuplot, I have some troubles:
How to change the crosses on the fingure into dots?
How to change the color of the dots, to let's say, red? ( my command in my gnuplotscript seems not to work at all ...)
For the first test the adequate, accurate, exact value is 0.005467 but on my figure it doesnt look like so... I would like to place the dot on my figure for the first, second, third, (so on) test on the exact place, where is appropriate value.
How to add a grid to my figure? - SOLVED
How to get rid of the ugly text: 'data.txt' using 1:2 and replace it with a legend? - SOLVED
EDIT (SOLVED ISSUE NO 5)
plot 'data.txt' using 1:2 w points title "tests"
EDIT (SOLVED ISSUE NO 4)
set grid ytics lt 0 lw 1 lc rgb "#bbbbbb"
set grid xtics lt 0 lw 1 lc rgb "#bbbbbb"
You should read a bit in the documentation about all your commands!
Several remarks:
If you want colored points, you shouldn't use the mono (i.e. the monochrome) option, but rather color.
Your definition of the line style is correct, but in order to use it you must use linestyle 1 when plotting. Otherwise the linetype 1 is used. Compare:
set style line 1 lt 1 lw 3 pt 3 linecolor rgb "red"
plot x, 2*x linestyle 1
In order to see all the dots of a terminal, use the test command:
set terminal postscript eps enhanced color dashed lw 1 'Helvetica' 14
set output 'test.eps'
test
set output
You see, that for filled dots you must use pt 7.
I'm sure, that the points are shown at the correct values. Use
set ytics add (0.005467)
to see this.

Resources