gnuplot low quality outputs - output

I have a problem with gnuplot's outputs. The produced plots are of low quality. When i export the plots from the gnuplot window as pdf, the images are crispy clear. If i export as png,the results are slightly blurry. Saving as either jpeg or png directly from the script, the images are even worse. Is there a way to produce clear jpeg or png images? The script and software i am using follow:
set title "Temperature-Specific entropy diagram"
set termopt enhanced
set grid
set key top left
set xlabel "Specific entropy [kJ/KgK]"
set ylabel "Temperature [^oC]"
set datafile missing '0.000000000000000000e+00'
plot "Ts_saturation_curve.txt" using ($1/1000.0):($2-273.15) title "saturation curve" with line lt 1 lw 1.5 lc rgb "black",\
"critical_point.txt" using ($1/1000.0):($2-273.15) title "critical point" with points pt 6 ps 1.5 lc rgb "orangered4",\
"isobaric_critical.txt" using ($1/1000.0):($2-273.15) title "isobaric critical" with line lt 1 lw 1.5 lc rgb "orangered4",\
"isobaric_0.1MPa.txt" using ($1/1000.0):($2-273.15) title "0.1 MPa" with line lt 1 dt 2 lc rgb "dark-red",\
"isobaric_0.2MPa.txt" using ($1/1000.0):($2-273.15) title "0.2 MPa" with line lt 1 dt 2 lc rgb "red",\
"isobaric_0.5MPa.txt" using ($1/1000.0):($2-273.15) title "0.5 MPa" with line lt 1 dt 2 lc rgb "orange",\
"isobaric_1.0MPa.txt" using ($1/1000.0):($2-273.15) title "1 MPa" with line lt 1 dt 2 lc rgb "yellow",\
"isobaric_2.0MPa.txt" using ($1/1000.0):($2-273.15) title "2 MPa" with line lt 1 dt 2 lc rgb "greenyellow",\
"isobaric_5.0MPa.txt" using ($1/1000.0):($2-273.15) title "5 MPa" with line lt 1 dt 2 lc rgb "green",\
"isobaric_10.0MPa.txt" using ($1/1000.0):($2-273.15) title "10 MPa" with line lt 1 dt 2 lc rgb "cyan",\
"isobaric_20.0MPa.txt" using ($1/1000.0):($2-273.15) title "20 MPa" with line lt 1 dt 2 lc rgb "blue",\
"isobaric_50.0MPa.txt" using ($1/1000.0):($2-273.15) title "50 MPa" with line lt 1 dt 2 lc rgb "violet",\
"isobaric_100.0MPa.txt" using ($1/1000.0):($2-273.15) title "100 MPa" with line lt 1 dt 2 lc rgb "purple"
set term png
set output "output.png"
replot
gnuplot 5.2,debian 10.5 (cinnamon de)
Thank you in advance.

For the sake of not letting this answer appear unanswered and furthermore according the SO "rule" "no answer in comments"...
Try this:
set terminal pngcairo size 1440,900
Apparently, term png and term pngcairo are using different libraries with different quality results.

Related

Gnuplot timecolumn with few measurements. One data with "day overflow"

I did a few measurements for discharging batteries.
Now i wanted to plot them with Gnuplot. The problem is, that one of the measurements startet very late, that I have an "overflow" from my 24hours-clock.
Here an example of my problem-.csv-measurement data:
Time;Voltage;Current;Charge;Power;Energy;Temperature
...
23:59:54;3.2387;0.6989;0.039;2.264;0.127;22.0
23:59:55;3.2387;0.6989;0.039;2.264;0.128;22.0
23:59:56;3.2387;0.6989;0.039;2.264;0.129;22.0
23:59:57;3.2387;0.6989;0.04;2.264;0.129;22.0
23:59:58;3.2387;0.6992;0.04;2.264;0.13;22.0
23:59:59;3.2386;0.6989;0.04;2.263;0.13;22.0
00:00:00;3.2386;0.6992;0.04;2.264;0.131;22.0
00:00:01;3.2386;0.6989;0.04;2.263;0.132;22.0
00:00:02;3.2386;0.6992;0.041;2.264;0.132;22.0
00:00:04;3.2386;0.6992;0.041;2.264;0.133;22.5
00:00:05;3.2386;0.6989;0.041;2.263;0.134;22.5
00:00:06;3.2386;0.6989;0.041;2.263;0.134;22.5
00:00:07;3.2386;0.6989;0.041;2.263;0.135;22.0
the other datas dont measured between two days.
With the following Gnuplot-code:
set grid
set title 'Entladungen der Batterie über Zeit'
set tics nomirror
set title font ",12"
set ylabel 'U/V' font ",12"
set key box font ",12"
set xtics time
set xlabel 'time' font ",12"
set border 11
set border lw 2
set xtics font ",8"
set term wxt size 1200, 460
myFmt = "%H:%M:%S"
set datafile separator ";"
set format x "%tH:%M:%S" #timedate
set yrange[2.6:3.7]
plot 'Entadung_4,2A_Temp_22,5C°.csv' u (t=timecolumn(1,myFmt), $0==0?t01=t:0, t-t01):2 every ::2::1061 lt 7 lc "blue" with lines ti "Entladung bei 3C", \
'Entadung_2,8A_Temp_22,5C°.csv' u (t=timecolumn(1,myFmt), $0==0?t02=t:0, t-t02):2 every ::2::1604 lt 7 lc "web-green" with lines ti "Entladung bei 2C", \
'Entadung_1,4A_Temp_22,0C°.csv' u (t=timecolumn(1,myFmt), $0==0?t03=t:0, t-t03):2 every ::2::3267 lt 7 lc "red" with lines ti "Entladung bei 1C",\
'Entadung_0,7A_Temp_22,0C°.csv' u (t=timecolumn(1,myFmt), $0==0?t04=t:0, t-t04):2 every ::2::6696 lt 7 lc "yellow" with lines ti "Entladung bei 0,5C", \
'Entadung_0,28A_Temp_22,0C°.csv' u (t=timecolumn(1,myFmt), $0==0?t05=t:0, t-t05):2 every ::2::16977 lt 7 lc "black" with lines ti "Entladung bei 0,2C",\
'Entadung_0,14A_Temp_22,5C°.csv' u (t=timecolumn(1,myFmt), $0==0?t06=t:0, t-t06):2 every ::2::33731 lt 7 lc "violet" with lines ti "Entladung bei 0,1C"
I got this output:
The plot takes the 23 hours and subtract ist from every timestep.
So i get negative time...
Anybody know, how i can use an offset just for this one data, that the others stay untouched?
I was expecting, that the yellow graph lays between the red and the black graph.
Unfortunately, you don't record the date as well. If you had you wouldn't have this problem.
But you can account for midnight crossings with a little addition.
assign t1=NaN and td=0 before the plot command
within the plot command (loop), assign t0=t1 and directly afterwards t1=timecolumn(...). So, t0 always holds the previous value and t1 the current value
every time t1<t0 (i.e. crossing midnight) add one day to td, i.e. td=td+secsPerDay (number of seconds per day) and add td to your plotting value.
furthermore, if you use %tH as x-timeformat, hours will not wrap at 24 hours, in case your measurement runs for longer than 24 hours (check help time_specifiers).
Script:
### account for midnight crossings
reset session
$Data <<EOD
23:59:00 3.7
01:59:00 3.6
12:00:00 3.5
23:00:00 3.4
02:30:00 3.3
13:00:00 3.2
23:00:00 3.1
03:00:00 3.0
14:00:00 2.9
EOD
myFmt = "%H:%M:%S"
secsPerDay = 3600*24
set xlabel "hours:min"
set format x "%tH:%M" timedate
set multiplot layout 2,1
plot $Data u (t=timecolumn(1,myFmt), $0==0? t01=t:0, t-t01):2 w lp pt 7 lc "red" ti "as is"
plot t1=(td=0,NaN) $Data u (t0=t1,t1=timecolumn(1,myFmt), $0==0? t01=t1:0, \
t1<t0?td=td+secsPerDay:0, t1-t01+td):2 w lp pt 7 lc "blue" ti "add day offset"
unset multiplot
### end of script
Result:

How can I make a bar graph displaying y-min and y-max data along with custom colors for each bar?

I would like to make a bar graph that displays each bar as the bottom of the bar being y-min and the top of the bar being y-max. In addition I'd like each bar to have its own color fill and custom tics where xtic(1). Thank you
Similar to this below:
How to make range bar graphs in gnuplot?
ex.
#number #y-min #y-max #rgb
1 2 5 1
2 2.5 5.4 2
3 4 6 3
4 4.3 7 4
Here is what I ended up doing in case someone else needs it
set termoption font ",22"
boxwidth = 0.5
set style fill solid
set xtics nomirror
set ytics nomirror
set xtics font "{/:Bold,22}"
set ytics font "{/:Bold,22}"
set xlabel "Structure"
set xlabel font "{/:Bold,30}"
set ylabel "Potential (V vs. RHE)"
set ylabel font "{/:Bold,30}"
set xrange [-1:4.5]
set yrange [0:7]
set arrow from -1,2.5 to 4.5,2.5 nohead lc rgb 'black' dt 3
plot 'poten-range-plot' u 0:(($2+$3)/2.):(boxwidth/2.):(($3-$2)/2.):4:xtic(1) w boxxyerrorbars notitle lw 3 lc variable, 1/0 t "Pt (111)" lt 1 lc rgb 'black'

Grouped bar plot with multiple labels in x-axis

I am trying to replicate something close to the following graph in gnuplot as I need to use it on a latex paper. I have tried a lot but I cannot make the two-line labels at the bottom. Could you please guide me? Also, how is it possible to have the % character as part of a label in the x-axis? Latex complains about it.
The data are in the following format (example). Each different color corresponds to different method. Blue is method 1 (m1), orange is method 2 (m2), and brown is method 3 (m3)
#% system1-m1 system1-m2 system1-m3 system2-m1 ...
0.5% 16 8 15 6
1% 15 17 16 8
2% 12 10 20 15
Thanks
Edit
My code so far is as follows:
set rmargin 0
set key outside tmargin center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5
set style data histograms
set label 1 at -0.3, -4 '|---------System 1------------|'
set label 2 at 2.7, -4 '|---------System 2------------|'
plot "./data/metrics.dat" using 2:xtic(1) title 'Method 1' ,\
"" using 3 title 'Method 2', \
"" using 4 title 'Method 3',
And I have modified the .dat file as
0.5 16 8 15
1.0 15 17 16
2.0 12 10 20
0.5 13 6 4
1.0 11 13 13
2.0 14 12 14
because I cannot make it print the % character. The output graph is
As you can see it is not scalable. I have to put labels by hand (trial and error) and also the labels below the x-axis do not contain the % character.
We've been close: set format x '%.1f\%%'. The following works for me with cairolatex terminal (check help cairolatex).
Code:
### percent sign for tic label in TeX
reset session
set term cairolatex
set output 'SO70029830.tex'
set title 'Some \TeX\ or \LaTeX\ title: $a^2 + b^2 = c^2$'
set format x '%.1f\%%'
plot x
set output
### end of code
Result: (screenshot)
Addition:
Sorry, I forgot the second part of your question: the labels.
Furthermore, in your graph you are using xtic(1) as tic labels, i.e. text format, so the command set format x '%.1f\%%' from my answer above will not help here. One possible solution would be to create and use your special TeX label like this:
myTic(col) = sprintf('%.1f\%%',column(col))
plot $Data using 2:xtic(myTic(1))
For the labels, I would use arrows and labels. Each histogram is placed at integer numbers starting from 0. So, the arrows have to go from x-values -0.5 to 2.5 and from 2.5 to 5.5. The labels are placed at x-value 1 and 4. There is certainly room for improvements.
Code:
### tic labels with % for TeX and lines/labels
reset session
set term cairolatex
set output 'SO70029830.tex'
$Data <<EOD
0.5 16 8 15
1.0 15 17 16
2.0 12 10 20
0.5 13 6 4
1.0 11 13 13
2.0 14 12 14
EOD
set rmargin 0
set key outside center top horizontal width 3
set border
set grid
set boxwidth 0.8
set style fill solid 1.00
set xtics nomirror rotate by 0
set format y '%1.f'
set yrange [0 to 22]
set ylabel 'Gain (\%)'
set ytics 0, 5
set style data histograms
set bmargin 4
set arrow 1 from -0.5, screen 0.05 to 2.5, screen 0.05 heads size 0.05,90
set label 1 at 1, screen 0.05 'System 1' center offset 0,-0.7
set arrow 2 from 2.5, screen 0.05 to 5.5, screen 0.05 heads size 0.05,90
set label 2 at 4, screen 0.05 'System 2' center offset 0,-0.7
myTic(col) = sprintf('%.1f\%%',column(col))
plot $Data using 2:xtic(myTic(1)) title 'Method 1' ,\
"" using 3 title 'Method 2', \
"" using 4 title 'Method 3',
set output
### enf of code
Result: (screenshot from LaTeX document)
As an alternative to the answer of #theozh there is already a build-in function called newhistogram that directly allows to place labels below the x-axis.
While working on an an answer that involves newhistogram I discovered a bug with horizontal key layout, which is now fixed thanks to Ethan. So, with the newest development version of gnuplot at hand I am able to offer a solution that allows for more finetuning like the ability to change the inter-group spacing.
set terminal cairolatex standalone colour header '\usepackage{siunitx}' size 25cm, 7cm
# generate some random data in your format
N = 7
set print $MYDATA
do for [i=1:N] {
print sprintf('0.5 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf('1.0 %f %f %f', rand(0)*20, rand(0)*20, rand(0)*20)
print sprintf("2.0 %f %f %f", rand(0)*20, rand(0)*20, rand(0)*20)
}
unset print
# define the look
set style data histograms
set style fill solid 1.00
set boxwidth 0.8
set key horizontal outside t c width 1
set xr [-1:27]
set xtics nomirror
set ytics out 5 nomirror
set grid y # I don't think vertical grid lines are needed here
set ylabel 'Gain/\%'
set rmargin 0.01
set bmargin 3
As for the tic marks, I adapted #theozh's answer a bit – since you are using LaTeX already, you might as well parse the numbers through siunitx, which will ensure correct spacing between numbers and the unit:
myTic(col) = sprintf('\SI{%.1f}{\%}',column(col))
The vertical separation marks like in the screenshot you provided can be created iteratively:
do for [i=1:N+1] {set arrow i from first -1+(i-1)*4, graph 0 to first -1+(i-1)*4, screen 0 lw 2 nohead}
Now for the actual plot command:
plot newhistogram "System 1" offset 0,-0.5 lt 1, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::0::2 title sprintf('Method %.0f',i), \
newhistogram "System 2" offset 0,-0.5 lt 1 at 4, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::3::5 not, \
newhistogram "System 3" offset 0,-0.5 lt 1 at 8, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::6::8 not, \
newhistogram "System 4" offset 0,-0.5 lt 1 at 12, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::9::11 not, \
newhistogram "System 5" offset 0,-0.5 lt 1 at 16, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::12::14 not, \
newhistogram "System 6" offset 0,-0.5 lt 1 at 20, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::15::17 not, \
newhistogram "System 7" offset 0,-0.5 lt 1 at 24, for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::18::20 not
That looks very nasty, what's going on here?
newhistogram creates a new group of histogram boxes, its first argument is a string that is put below the x axis. It is also told to reset the linetype counter to 1.
Then the three columns of the data are plotted iteratively, but not all lines at once, but only the first three lines, with corresponding key entries.
Then another newhistogram is created and it is told to start at the x value 4 (which would be the default anyway). Now the next three lines are plotted, and so.
Now, every time newhistogram is called an empty line is added to key, hence making trouble with the key placement. Therefore the new keyword introduced by Ethan is
set style histogram nokeyseparators
which will disable this behaviour.
As you see, the spaces between the groups are larger than inside. You might want to change the numbers in newhistogram at ... and adjust the calculation of vertical line positions accordingly.
The plot command is of course highly repetitive, and it would be nice to make it an iterative call. Unfortunately, iterations that span multiple objects are not possible within a plot call. However, it is possible to iteratively put the plot command string together (excessively using string concatenation .) and then plot it.
A = 'newhistogram "System '
B = '" offset 0,-0.5 lt 1'
C = 'for [i=1:3] $MYDATA using (column(i+1)):xtic(myTic(1)) every ::'
myplotstring = A.'1'.B.', '.C."0::2 title sprintf('Method %.0f',i),"
do for [i=2:N] {myplotstring = myplotstring.A.i.B.'at '.(4*(i-1)).', '.C.(3*i-3).'::'.(3*i-1).' not, '}
plot #myplotstring

Use column from CSV as a category label for plotting column chart using gnuplot

I have a CSV file looking like:
frameNo dataSeg paritySeg frameType
0 17 3 k
1 2 1 d
2 3 1 d
3 3 1 d
4 3 1 d
5 2 1 d
6 3 1 d
7 3 1 d
8 4 1 d
I'm able to plot stacked column diagram showing number of data and parity segments per frame. Looks like this:
What I'd like to add to it, however, is paint differently those columns (both data and parity) which have "k" marker in the last column. Basically, distinguish between two categories - "d" and "k".
Is that possible using gnuplot?
Here's the script I'm using:
set style histogram rowstacked;
set style data histograms;
set style fill solid;
set datafile separator "\t";
set terminal png size 2500,1500 enhanced font ",30";
set title "";
set tics font ",25";
set xlabel "Frame #" font ",25";
set ylabel "# of segments" font ",25";
set key outside;
set xrange [0:];
plot "segments.csv" using 2 t "Data", "" using 3 t "Parity";'
You could impose a custom condition on the columns being plotted and supply an invalid value (signaling to skip the particular data point) if this condition is not met:
set terminal pngcairo size 1200,600 enhanced font ",30";
set output 'test.png'
set style histogram rowstacked;
set style data histograms;
set style fill solid;
#set datafile separator "\t";
set title "";
set tics font ",25";
set xlabel "Frame #" font ",25";
set ylabel "# of segments" font ",25";
set key outside;
set xrange [0:];
fName = 'segments.csv'
plot \
fName using (strcol(4) eq 'd'?$2:1/0) t "Data d" lc rgb '#666666', \
fName using (strcol(4) eq 'd'?$3:1/0) t "Parity d" lc rgb '#ff0000', \
fName using (strcol(4) eq 'k'?$2:1/0) t "Data k" lc rgb '#000000', \
fName using (strcol(4) eq 'k'?$3:1/0) t "Parity k" lc rgb '#990000'
this would give (using the sample data in your question):

gnuplot ignores divisor of csv-column values

I am using gnuplot to draw a histogram of a series of RAM measurements I performed.
However, I want it to display the values that are stored in Bytes in CSV files in KB.
I divided the respective columns by 1024, but gnuplot simply ignores that.
Below you see the template that is changed by a script to have meaningful file names for CSVFILE and PSFILE and then fed into gnuplot.
set style data histogram
set style histogram errorbars gap 1
set xlabel "nodes"
set ylabel "memory (KB)"
set key left box
set datafile separator ","
set terminal postscript landscape
set output 'PSFILE'
plot 'CSVFILE' using ($2/1024):($3/1024):xtic(1) ti col lt -1 fs pattern 1,\
'' using ($4/1024):($5/1024):xtic(1) ti col lt -1 fs pattern 2,\
'' using ($6/1024):($7/1024):xtic(1) ti col lt -1 fs pattern 4,\
'' using ($8/1024):($9/1024):xtic(1) ti col lt -1 fs pattern 6,\
'' using ($10/1024):($11/1024):xtic(1) ti col lt -1 fs pattern 5,\
'' using ($12/1024):($13/1024):xtic(1) ti col lt -1 fs pattern 7,\
'' using ($14/1024):($15/1024):xtic(1) ti col lt -1 fs pattern 3
So what does not work is the /1024. Any ideas how to do that?
Changing the CSV files instead came to my mind, yes, but they are a lot, and I would have to write a script to change all cells, which I definitely do not fancy to do.
Okay, the solution was trivial. I just had to enclose the $2 values in extra braces, like ($2)/1024.