I have gnuplot script like this:
set term pos eps
set style data histogram
set style histogram clustered gap 1
set grid y
set boxwidth 0.8 absolute
set style fill transparent solid 0.8 noborder
#set key outside right top vertical Left
#component stuff
set output 'eps/component.eps'
set title "Component in interesting Issues"
set xlabel "Components"
set xtics nomirror rotate by -270
plot 'dat/!component' using 2:xtic(1) t "Count" lc rgbcolor "blue" lt 1
and data:
Cmp count
AM 167
NM 90
RM 83
JT 53
TT 51
RED 32
MAP 29
COMM 3
SX 6
HS 68
and this is my output:
I see my graph has long spaces between the Y axis and the first bar. How can I spread the bars out evenly?
gnuplot gets confused by the first line in your data file, which is supposed to be the header. Just skip this line with every ::1 and the autoscaling is fine:
plot 'dat/!component' using 2:xtic(1) every ::1 t "Count" lc rgbcolor "blue" lt 1
Result with 4.6.4:
In general you don't need to use histograms for this kind of data, the plotting style with boxes also works fine.
Related
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:
I have data I would like to plot in a histogram style with a "cumulated" curve on top. I have the following problem:
My data consists of one column with the categories ("discharge") and one column with the quantity of values ("probability") that belong to the respective category. The last value of the category-column is ">100" summarizing all power plants that have a bigger discharge than the last numeric value ("100 m^3/s"). I have not found a solution to plot this last category and the respective values with the command plot 'datafile.dat' using 1:2 with boxes ... because (as I assume) in this case only numerical values are read out for the x-ticlabels, so the last category is missing. If
I plot it with this command plot 'datafile.dat' using 2:xtics(1) with boxes ... I get the last category ">100" plotted just fine.
BUT: if I use the latter command the x-axis labels appear in the normal font size. Even though I have the line set format x '\footnotesize \%10.0f' in my code.
I have read about explicit labels in the plotcommand line that overwrite format style which was set before but was not able to adapt it to my code.
Changing ytic font size in gnuplot epslatex (multiplot)
Do you have an idea how to do this?
Excel screenshot to visualize what I want to achieve
'datafile.dat'
discharge probability cumulated
10 20 20%
20 10 10%
30 5 5%
40 6 6%
50 4 4%
60 12 12%
70 8 8%
80 15 15%
90 20 20%
100 6 6%
>100 4 4%`
[terminal=epslatex,terminaloptions={size 15cm, 8cm font ",10"}]
set xrange [*:*]
set yrange [0:20]
set y2range [0:100]
set xlabel 'Discharge$' offset 0,-1
set ylabel 'No. of power plants' offset 10.5
set y2label 'Cumulated probability' offset -10
set format xy '$\%g$'
set format x '\footnotesize \%10.0f'
set format y '\footnotesize \%10.0f'
set format y2 '\footnotesize \%10.0f'
set xtics rotate by 45 center offset 0,-1
set style fill pattern border -1
set boxwidth 0.3 relative
set style line 1 lt 1 lc rgb 'black' lw 2 pt 6 ps 1 dt 2
plot 'datafile.dat' using 1:2 with boxes axes x1y1 fs pattern 6 lc black notitle, \
'datafile.dat' using 1:3 with linespoints axes x1y2 ls 1 notitle
I am confused by your datafile; the numbers in the third column do not seem to be cumulative, and do not add up to 100%. Here is a solution that uses only the first two columns of your file:
set term epslatex standalone header "\\usepackage[T1]{fontenc}"
set output 'test.tex'
stats "datafile.dat" using 2
total = STATS_sum
set xlabel "Discharge" offset 0, 1.5
set xtics rotate
set ylabel "No. of power plants"
set ytics nomirror
set yrange [0:*]
set y2label "Cumulative probability"
set y2tics
set y2range [0:]
set boxwidth 0.3 relative
set style line 1 lt 1 lc rgb 'black' lw 2 pt 6 ps 1 dt 2
plot \
'datafile.dat' using 2:xtic("\\footnotesize " . stringcolumn(1)) with boxes axes x1y1 fs pattern 6 lc black notitle, \
'datafile.dat' using ($2/total) smooth cumulative with linespoints axes x1y2 ls 1 notitle
set output
The trick is to add the latex command \footnotesize in front of each label in the using command. It also first computes the total number of power plants so that it can compute probabilities, and computes cumulative values with the smooth cumulative option.
yesteraday I made a similar question (this one). I could not display the value on top of bar in a gnuplot histogram. I lost many time because I couldn't find really good documentation about it, and I only can find similar issues on differents websites.
I lost many time with that but fortunately someone give me the solution. Now I am having a similar issue with an histogram with two bars, in which I have to put on top of both bars its value. I am quite near, or that is what I think, but I can't make it work properly. I am changing the script and regenerating the graph many times but I am not sure of what I am doing.
script.sh
#!/usr/bin/gnuplot
set term postscript
set terminal pngcairo nocrop enhanced size 600,400 font "Siemens Sans,8"
set termoption dash
set output salida
set boxwidth 0.8 absolute
set border 1
set style fill solid 1.00 border lt -1
set key off
set style histogram clustered gap 1 title textcolor lt -1
set datafile missing '-'
set style data histograms
set xtics border in scale 0,0 nomirror autojustify
set xtics norangelimit
set xtics ()
unset ytics
set title titulo font 'Siemens Sans-Bold,20'
set yrange [0.0000 : limite1] noreverse nowriteback
set y2range [0.0000 : limite2] noreverse nowriteback
show style line
set style line 1 lt 1 lc rgb color1 lw 1
set style line 2 lt 1 lc rgb color2 lw 1
## Last datafile plotted: "immigration.dat"
plot fuente using 2:xtic(1) ls 1 ti col axis x1y1, '' u 3 ls 2 ti col axis x1y2, '' u 0:2:2 with labels offset -3,1 , '' u 0:2:3 with labels offset 3,1
I am modifying the last code line, because is here where I set the labels. I have been able to show both labels, but in bad positions, I have also been able to show one of the labels in the right position but no the other. I have been able to show almost everything but the thing that I want. This is the graph that generates the script.
output.png
This is the source file that I use for generating the graph
source.dat
"Momento" "Torre 1" "Torre 2"
"May-16" 1500.8 787.8
"Jun-16" 1462.3 764.1
"Jul-16" 1311.2 615.4
"Ago-16" 1199.0 562.0
"Sep-16" 1480.0 713.8
"Oct-16" 1435.1 707.8
And that's the command that I execute with the parameters set
gnuplot -e "titulo='Energía consumida por torre (MWh)'; salida='output.png'; fuente='source.dat'; color1='#FF420E'; color2='#3465A4'; limite1='1800.96'; limite2='945.36'" script.sh
I think that is quite obvious what I am pretending, can someone help me?
Lots of thanks in advance.
Your script has several problems, the missing ti col is only one of them. (You can also use set key auto columnheader, then you must not give that option every time).
Don't use both y1 and y2 axis if you want to compare the values! Otherwise the correct bar heights are only a matter of luck...
Understand, how gnuplot positions the histogram bars, then you can exactly locate the top center of each bar. If you only use offset with char values (which is the case when you give only numbers), then your script will break as soon as you add or remove a data row.
The histogram clusters start at x-position 0, and are positioned centered at integer x values. Since you have two bars in each cluster and a gap of 1, the center of the first bar is at ($0 - 1/6.0) (= 1/(2 * (numberOfTorres + gapCount))), the second one at ($0 + 1/6.0):
set terminal pngcairo nocrop enhanced size 600,400 font ",8"
set output 'output.png'
set title 'Energía consumida por torre (MWh)' font ",20"
set boxwidth 0.8 absolute
set border 1
set style fill solid 1.00 border lt -1
set style histogram clustered gap 1 title textcolor lt -1
set style data histograms
set xtics border scale 1,0 nomirror autojustify norangelimit
unset ytics
set key off auto columnheader
set yrange [0:*]
set offset 0,0,graph 0.05,0
set linetype 1 lc rgb '#FF420E'
set linetype 2 lc rgb '#3465A4'
# dx = 1/(2 * (numberOfTorres + gap))
dx = 1/6.0
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels,\
'' u ($0 + dx):3:3 with labels
Now, starting at the bars center you can safely use offset to specify only the offset relative to the bars top center:
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels offset -1,1 ,\
'' u ($0 + dx):3:3 with labels offset 1,1
A second option would be to use the label's alignment: The labels of the red bars are right aligned at the bars right border, the labels of the blue bars are left aligned at the bars left border:
absoluteBoxwidth = 0.8
dx = 1/6.0 * (1 - absoluteBoxwidth)/2.0
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels right offset 0,1 ,\
'' u ($0 + dx):3:3 with labels left offset 0,1
In any case, both options make your script more robust against changes of the input data.
This looks better :
plot fuente using 3:xtic(1) ls 1 ti col axis x1y1, '' u 3 ls 2 ti col axis x1y2, '' u ($0-1):3:3 with labels offset -3,1 , '' u ($0-1):2:2 with labels offset 3,1
You had 2 plots commands: only the first one was displayed.
Also, script.sh should be a bash script. This is a gnuplot script, so it should have another extension.
The problem is the ti col tab. You need to put it in every option, including labels and not only in bars. The right code is:
plot fuente using 2:xtic(1) ls 1 ti col, '' u 3 ls 2 ti col, '' u 0:2:2 ti col with labels offset -3,1 , '' u 0:3:3 ti col with labels offset 3,1
And that's how the picture is displayed now:
You can also avoid ti col and that is how it would look:
I have a very simple chart like this
and I would like to add vertical error bars above and below the top of each bar.
my GNUPlot input is
set boxwidth 0.5
set style fill solid
set title 'title'
set key off
set ylabel 'ylabel'
set xtics font 'Arial, 24'
set ytics font 'Arial, 18'
set title font 'Arial, 24'
set ylabel font 'Arial, 16'
set terminal pngcairo size 1000,1000# gnuplot recommends setting terminal before output
set output 'pathfinder.png'
plot 'pathfinder.txt' every ::0::0 using 1:3:xtic(2) with boxes lc rgb 'red', \
'pathfinder.txt' every ::1::1 using 1:3:xtic(2) with boxes lc rgb 'green', \
'pathfinder.txt' every ::2::2 using 1:3:xtic(2) with boxes lc rgb 'blue', \
'pathfinder.txt' every ::3::3 using 1:3:xtic(2) with boxes lc rgb 'orange',
and my data
#x axis location, label, height of bar, low part of error bar, high part of error bar
0 A 209.3 200 219
1 B 4790.2 4700 4900
2 C 3771.2 3700 3900
3 D 170.3 150 200
I have seen similar posts, namely adding error bar to histogram in gnuplot and Adding error bars on a bar graph in gnuplot but I don't see how it applies with this case.
How can I modify my GNUPlot script to add error bars?
thanks so much!
The two links you mentioned basically contain the answer, however,
from you example it looks like you want filled bars with defined colors.
From help boxerrorbars:
The error bar will be drawn in the same color as the border of the
box.
So, you have several options:
(top left) "same color as the border of the box" of course doesn't make sense if you fill your bar, since the lower part of the error bar will disappear in the filled bar.
(top right) set the border e.g. "black", which will make the errorbar black as well
(bottom left) set the intensity of the solid fill, e.g. to 0.3, which will leave the border in intensity 1.0 and hence the errorbar as well.
(bottom right) split the plot in with boxes and with yerrorbars then your are completely independent for the colors. There is a point with the yerrorbar which you can let disappear by specifying ps 0 (or pointsize 0)
Script: (works with gnuplot>=5.0.0, Jan. 2015)
### filled bars with errorbars
reset session
$Data <<EOD
#x axis location, label, height of bar, low part of error bar, high part of error bar
0 A 25 17 33
1 B 50 40 60
2 C 85 71 91
3 D 40 33 47
EOD
set palette defined (1 "red", 2 "green", 3 "blue", 4 "orange")
unset colorbox
set key noautotitle
set yrange[0:100]
set grid y
set tics out
set offset 0.25,0.25,0,0
set multiplot layout 2,2
set style fill solid 1.0 noborder
plot $Data u 1:3:4:5:(0.5):0:xtic(2) w boxerrorbars lc palette
set style fill solid 1.0 border lc "black"
replot
set style fill solid 0.3 border
replot
set style fill solid 1.0
plot $Data u 1:3:(0.5):0:xtic(2) w boxes lc palette, \
'' u 1:3:4:5 w yerr pt 6 ps 1 lc "black"
unset multiplot
### end of script
Result:
I am using the following script to fit a function on a plot. In the output plot I would like to add a single value with etiquette on the fitting curve lets say the point f(3.25). I have read that for gnuplot is very tricky to add one single point on a plot particularly when this plot is a fitting function plot.
Has someone has an idea how to add this single point on the existing plot?
set xlabel "1000/T (K^-^1)" font "Helvetica,20"
#set ylabel "-log(tau_c)" font "Helvetica,20"
set ylabel "-log{/Symbol t}_c (ns)" font "Helvetica,20"
set title "$system $type $method" font "Helvetica,24"
set xtics font "Helvetica Bold, 18"
set ytics font "Helvetica Bold, 18"
#set xrange[0:4]
set border linewidth 3
set xtic auto # set xtics automatically
set ytic auto # set ytics automatically
#set key on bottom box lw 3 width 8 height .5 spacing 4 font "Helvetica, 24"
set key box lw 3 width 4 height .5 spacing 4 font "Helvetica, 24"
set yrange[-5:]
set xrange[1.5:8]
f(x)=A+B*x/(1000-C*x)
A=1 ;B=-227 ; C=245
fit f(x) "$plot1" u (1000/\$1):(-log10(\$2)) via A,B,C
plot [1.5:8] f(x) ti "VFT" lw 4, "$plot1" u (1000/\$1):(-log10(\$2)) ti "$system $type" lw 10
#set key on bottom box lw 3 width 8 height .5 spacing 4 font "Helvetica, 24"
set terminal postscript eps color dl 2 lw 1 enhanced # font "Helvetica,20"
set output "KWW.eps"
replot
There are several possiblities to set a point/dot:
1. set object
If you have simple points, like a circle, circle wedge or a square, you can use set object, which must be define before the respective plot command:
set object circle at first -5,5 radius char 0.5 \
fillstyle empty border lc rgb '#aa1100' lw 2
set object circle at graph 0.5,0.9 radius char 1 arc [0:-90] \
fillcolor rgb 'red' fillstyle solid noborder
set object rectangle at screen 0.6, 0.2 size char 1, char 0.6 \
fillcolor rgb 'blue' fillstyle solid border lt 2 lw 2
plot x
To add a label, you need to use set label.
This may be cumbersome, but has the advantage that you can use different line and fill colors, and you can use different coordinate systems (first, graph, screen etc).
The result with 4.6.4 is:
2. Set an empty label with point option
The set label command has a point option, which can be used to set a point using the existing point types at a certain coordinate:
set label at xPos, yPos, zPos "" point pointtype 7 pointsize 2
3. plot with '+'
The last possibility is to use the special filename +, which generates a set of coordinates, which are then filtered, and plotted using the labels plotting style (or points if no label is requested:
f(x) = x**2
x1 = 2
set xrange[-5:5]
set style line 1 pointtype 7 linecolor rgb '#22aa22' pointsize 2
plot f(x), \
'+' using ($0 == 0 ? x1 : NaN):(f(x1)):(sprintf('f(%.1f)', x1)) \
with labels offset char 1,-0.2 left textcolor rgb 'blue' \
point linestyle 1 notitle
$0, or equivalently column(0), is the coordinate index. In the using statement only the first one is taken as valid, all other ones are skipped (using NaN).
Note, that using + requires setting a fixed xrange.
This has the advantages (or disadvantages?):
You can use the usual pointtype.
You can only use the axis values as coordinates (like first or second for the objects above).
It may become more difficult to place different point types.
It is more involved using different border and fill colors.
The result is:
Adding to Christoph's excellent answers :
4. use stdin to pipe in the one point
replot "-" using 1:(f($1))
2.0
e
and use the method in 3rd answer to label it.
5. bake a named datablock
(version > 5.0) that contains the one point, then you can replot without resupplying it every time:
$point << EOD
2.0
EOD
replot $point using 1:(f($1)):(sprintf("%.2f",f($1))) with labels
6. A solution using a dummy array of length one:
array point[1]
pl [-5:5] x**2, point us (2):(3) pt 7 lc 3
7. Or through a shell command (see help piped-data):
pl [-5:5] x**2, "<echo e" us (2):(3) pt 7 lc 3
pl [-5:5] x**2, "<echo 2 3" pt 7 lc 3
8. Special filename '+'
pl [-5:5] x**2, "+" us (2):(3) pt 7 lc 3
It seems to be the shortest solution. But note that while it looks like a single point, these are like 500 points (see show samples) plotted on the same position.
To have only one point the sampling needs to be temporarily adjusted (see help plot sampling)
pl [-5:5] x**2, [0:0:1] "+" us (2):(3) pt 7 lc 3
9. Function with zero sampling range length
Shortest to type, but plotting as many points on top of each other as many specified with samples
pl [-5:5] x**2, [2:2] 3 w p pt 7 lc 3