I use this script Gnuplot :
set title "df -m command test"
set terminal png truecolor size 720,480 background rgb "#eff1f0"
set output "/xxx/xxx/xxx/test.png"
set grid
set style line 1 \
linecolor rgb '#0060ad' \
linetype 1 linewidth 2 \
pointtype 7 pointsize 1.5
set offsets 0.5,0.5,0,0.5
set datafile separator ","
set ylabel " MB BLOCK "
set xlabel " Date "
set format y "%g"
plot "/xxxx/xxx/xxx/TEST.txt" using 2:xtic(1) with linespoints linestyle 1 title "MB used"
With these data :
2019-08-28,384.00
2019-08-29,394.00
2019-08-30,354.00
2019-08-31,384.00
2019-09-01,484.00
2019-09-02,324.00
2019-09-03,384.00
To create this graph :
(source: noelshack.com)
Can you show me how I can put the value over each point ?
What about this? Also check help labels.
Code:
### plot with values as labels at datapoints
reset session
$Data <<EOD
2019-08-28,384.00
2019-08-29,394.00
2019-08-30,354.00
2019-08-31,384.00
2019-09-01,484.00
2019-09-02,324.00
2019-09-03,384.00
EOD
set datafile separator ","
set offsets 0.5,0.5,20,20
myLabel(n) = sprintf("%g",n)
plot $Data u 2:xtic(1) w lp pt 7 lc rgb "blue" title "MB used", \
$Data u 0:2:(myLabel($2)) w labels offset 0,1.5 notitle
### end of code
Result:
I am using the 32-bit version of GNUPlot in a Window 7 "Professional" OS Environment (...sadly!) and I want to do a "stack-plot" of boxes using ONLY ONE x-axis for ALL which is "TIME" in the format of a series of "Dates".
ALL of the GNUPlot Code works but, each of the plots uses its own individual x-axis which consumes a lot of graphing real estate.
I also need to be able to have variable y-axis scales for each of the stacked-plots...
Here is the "labeled" (CSV) data file:
Date,Time,Weight(kg),Height(cm),BMI,BP Max.(mmHg),BP Min.(mmHg),P/min,% Fat 09/09/2015,13:16:00,77.4,171,26.5,121,73,75,22.5 16/07/2015,09:14:34,76.9,170,26.6,111,70,76,23.5 26/06/2015,18:14:48,76.9,170,26.6,123,72,78,23.2 19/06/2015,08:45:42,77,172,26,96,60,89,22.1 15/06/2015,12:29:48,77.7,170,26.9,117,73,87,23.6 15/06/2015,12:15:58,77.8,170,26.9,127,76,77,23.7 15/06/2015,12:11:05,77.7,171,26.6,118,74,83,22.8 23/03/2015,16:39:55,78.6,170,27.2,119,72,78,24 20/03/2015,09:07:30,77.6,169,27.2,138,74,77,24.1 09/01/2015,14:30:00,79.2,170,27.4,114,71,75,24.1 07/10/2014,16:06:00,78.4,171,26.8,119,73,108,24.8 07/10/2014,16:08:00,78.4,170,27.1,109,72,75,25.1 15/09/2014,08:18:23,76.9,171,26.3,116,69,102,24.8 15/09/2014,09:20:27,76.7,172,25.9,132,76,91,21 04/09/2014,12:05:00,75.6,169,26.5,115,71,96,25.4 01/04/2014,11:18:00,76.2,171,26,115,69,70,22.9 19/03/2014,09:48:23,75.3,171,25.8,113,69,55,22.1 14/03/2014,10:39:29,75.6,170,26.2,108,69,78,22.5 05/03/2014,16:45:00,75.9,170,26.3,129,73,84,23.3 09/05/2013,17:31:00,74.5,171,25.5,135,75,92,21
And here is the "current" GNUPlot Code that I am using to generate the 5 stacked plots:
reset
set terminal windows size 1325, 625
set multiplot layout 5, 1 title "Individual Employee Biometric Data vs. Time"
set xlabel "DATE"
set timestamp
set key outside
set key center right
set pointsize 1.0
set grid lw 1
set timefmt "%d/%m/%Y"
set xdata time
set format x "%d/%m/%Y"
set xrange [ "09/05/2013\t0000" : "09/09/2015\t0000" ] noreverse nowriteback
set datafile sep ','
set arrow from 10.0,0 to 10.0, 0.5 lw 3
set label ' ' at 10.2,0.03
set label '(C) 2015' at 2050.0,-0.85
set border lw 2
set yrange [73.0:80.0]
set ylabel "(kg)"
plot 'K8.dat' using 1:3 title "BODY\nWEIGHT" with linespoints lw 2 lt rgb 'red'
set yrange [25.0:30.0]
set ylabel "kg/m^2"
plot 'K8.dat' using 1:5 title "BODY\nMASS\nINDEX" with linespoints lw 2 lt rgb 'green'
set yrange [50.0:150.0]
set ylabel "(mmHg)"
plot 'K8.dat' using 1:6 title "SYS" with linespoints lw 2 lt rgb 'blue', \ 'K8.dat' using 1:7 title "DIAS" with linespoints lw 2 lt rgb 'coral'
set yrange [40.0:120.0]
set ylabel "(bpm)"
plot 'K8.dat' using 1:8 title "HEART\nRATE" with linespoints lw 2 lt rgb 'purple'
set xlabel "DATE"
set yrange [15.0:30.0]
set ylabel "(%)"
plot 'K8.dat' using 1:9 title "BODY\nFAT" with linespoints lw 2 lt rgb 'orange'
PS - This code is from a previous GNUPlot routine so "excuse" the '#" commenting-out...
You can use multiplot to stack several plots on top of each other. You just have to switch off the plot borders appropriately for each, see help set border, and unset the abscissa xtics for all but the lowermost plot.
set multiplot
set origin 0.1, 0.1
set size 0.9,0.3
set xrange [a:b]
plot "first"
set origin 0.1,0.4
unset xtics
set border 2 # only plot left border
plot "second"
set origin 0.1,0.7
plot "third"
unset multi
Crucial is fixing the xrange for all plots, because after switching off the xtics for the following plots, you can't see if it is actually identical.
(too long for a comment)
Ok, I get what you mean by stacked plots now. To my knowledge, having several y-axes (more than 2) above a single x axis is not possible.
What you COULD however do is try to fake more than 2 axes by plotting all data in the roughly 30...150 range on the y(1)-axis, and all data in the 15...30 range on the y2axis. However, the lines would be all kind of overlapping and not as cleanly separated.
Another alternative would be to first normalize all data into an e.g. 0...10 range by subtracting the min value and dividing by max-min, then stacking these on top of each other by adding 0 for the first line, 10 for the second, and so on. However, you would then have to add hand-made y-axis tics (which is possible but somewhat bothersome).
Actually, here is a working template for the fancier solution I outlined above (implemented for three data sets, but can be extended to basically arbitrarily many)
reset
set datafile separator ","
inputfile = 'data0.txt'
stats inputfile using 3 name 'STATS_WEIGHT'
STATS_WEIGHT_range = STATS_WEIGHT_max - STATS_WEIGHT_min
stats inputfile using 4 name 'STATS_HEIGHT'
STATS_HEIGHT_range = STATS_HEIGHT_max - STATS_HEIGHT_min
stats inputfile using 9 name 'STATS_FAT'
STATS_FAT_range = STATS_FAT_max - STATS_FAT_min
# more stats for further data -- apparently needs to be BEFORE the date/time stuff
set timefmt "%d/%m/%Y"
set xdata time
set format x "%d/%m/%Y"
set xrange [ "09/05/2013\t0000" : "09/09/2015\t0000" ] noreverse nowriteback
# define the offset at which the fake y-axes start; decrease or increase offsetIncrease for spacing (effectively: blank labels) between 'graphs'
startYTicsOffset = 0
numberOfFakeYTicsPerData = 6
scalingFactor = 1.0/(numberOfFakeYTicsPerData - 1.0)
offsetIncrease = numberOfFakeYTicsPerData + 0.5
#to get rid of actual yrange numbering, set a dummy label that will be overwritten
set ytics ("dummy" 0)
#increase total actual yrange factor as needed for additional series
set yrange [0: 3 * offsetIncrease]
#add tics for weight, note that %.Xf prints the number with X decimals
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.0f kg", STATS_WEIGHT_min + i * scalingFactor * STATS_WEIGHT_range) startYTicsOffset+i)
}
#add tics for height
startYTicsOffset = startYTicsOffset + offsetIncrease
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.1f cm", STATS_HEIGHT_min + i * scalingFactor * STATS_HEIGHT_range) startYTicsOffset+i)
}
#add tics for fat - I couldn't figure out how to get gnuplot to print actual '%' character in sprintf directive (should be '%%' but doesn't appear to work)
startYTicsOffset = startYTicsOffset + offsetIncrease
do for[i=0:numberOfFakeYTicsPerData-1]{
set ytics add (sprintf("%.1f percent", STATS_FAT_min + i * scalingFactor * STATS_FAT_range) startYTicsOffset+i)
}
###### ... add further tics ...
plot inputfile using 1:( 0 * offsetIncrease + ($3 - STATS_WEIGHT_min)/ (STATS_WEIGHT_range * scalingFactor) ) w lp title "weight",\
inputfile using 1:( 1 * offsetIncrease + ($4 - STATS_HEIGHT_min)/ (STATS_HEIGHT_range * scalingFactor) ) w lp title "height",\
inputfile using 1:( 2 * offsetIncrease + ($9 - STATS_FAT_min) / (STATS_FAT_range * scalingFactor) ) w lp title "fat %"
### ... add further data ...
by the way: if you post or edit a question or an answer, try clicking the image icon above the editing window. It will open a little window where you can drag and drop images directly without needing a web hosting service. Like that:
I am currently working for a company where I have to evaluate a survey. Now do I have to make a plot of the data.
They want a table with the questions in the left column and a point in the right column with a distance to the question which symbolizes the average grade[0:4]. My first attempt is using gnuplot because I have used it before and now ran into the problem that if the length of the question(I already shortened them to a max. of 50 characters) is too long gnuplot is having problem displaying the plot correctly. The whole plot gets pushed to the right and you can't read it anymore.
My dataset looks like this
Eltern können sich über unsere Schule vielfä..., 2.2
Eltern werden über wichtige Entscheidungen inf..., 2.4
Eltern wissen über Projekte der Schule Bescheid, 2.4
Eltern erfahren Planung und Durchführung von F..., 1.5
Die Schule hat einen guten Ruf, 2.8
And here is my gnuplot file
set terminal pdfcairo enhanced font "Droid Sans,9" linewidth 4 rounded fontscale 1.0
set output "template.pdf"
set style line 80 lt rgb "#808080"
set border 3 back linestyle 80 #remove top and right border
set xtics nomirror
set ytics nomirror
set datafile sep ','
set xtics 0,1,4.
set ytics font ",4"
set xlabel "Note"
set style line 1 lc rgb "#0060AD" lt 1 lw 2 pt 7 pi -1 ps 1.0
set pointintervalbox 3
set xrange [0:4]
plot 'datafiles/adler_organisation.dat' using 2:0:ytic(1) notitle w lp ls 1
The result I currently get is
Here is an image how the rest of the evaluation looks like(made in LaTeX with datatool, loongtable and LTXtable).
Basically it is enough to fix the left margin with the command set lmargin at screen 0.5. Gnuplot isn't very good at estimating the margins based on the font type and font size. The result I get with this little change is:
Gnuplot cannot wrap long line automatically. You could use the epslatex terminal an put the labels in a \parbox with fixed length to achieve this, like with
label(s) = sprintf('\parbox{4cm}{\raggedleft %s}', s)
set ytics right
plot 'datafiles/adler_organisation.dat' using 2:0:ytic(label(strcol(1))) notitle w lp ls 1
But that would possibly give you problems getting the fonts. I haven't tried using epslatex together with Droid Sans.
As an other option you can use a python script to preprocess your datafile and insert line breaks. With the python script wraplabels.py:
from __future__ import print_function
import sys
import textwrap
with open(sys.argv[1], 'r') as f:
for line in f:
l, v = line.split(',')
print('"{}",{}'.format('\\n'.join(textwrap.wrap(l.strip(), 30)), v), end='')
and the gnuplot script
set terminal pdfcairo enhanced font "Droid Sans,9" linewidth 4 rounded fontscale 1.0
set output "template.pdf"
set style line 80 lt rgb "#808080"
set border 3 back linestyle 80 #remove top and right border
set tics nomirror
set datafile sep ','
set xtics 0,1,4.
set ytics font ",4" right
set xlabel "Note"
set style line 1 lc rgb "#0060AD" lt 1 lw 2 pt 7 pi -1 ps 1.0
set pointintervalbox 3
set xrange [0:4]
set lmargin at screen 0.3
plot '< python wraplabels.py datafiles/adler_organisation.dat' using 2:0:ytic(1) notitle w lp ls 1
you get a nice result
I have a data file with many columns of data and the first two lines look like this:
#time a1 b1 c1 d1 a2 b2 c2 d2
1 2 3 4 5 6 7 8 9
I would like to put a title on the graph which reads like this:
a1=2, a2=6, b1=3, b2=7, c1=4, c2=8, d1=5, d2=9
So, basically just taking the data from the first line and adding some text with it. Is this possible?
Thanks mgilson! Here is the script (the first part.)
#filename = "a6_a.txt"
//defining variables called ofac and residual
unset multiplot
set term aqua enhanced font "Times-Roman,18"
set lmargin 1
set bmargin 1
set tmargin 1
set rmargin 1
set multiplot
set size 0.8,0.37
set origin 0.1,0.08 #bottom
set xlabel "time" offset 0,1 #bottom
set ylabel "{/Symbol w}_i - {/Symbol w}_{i+1}"
set yrange [-pi:pi]
plot filename using 1:(residual($7 -$14)) ti "" pt 1 lc 2, \
"" using 1:(residual($14-$21)) ti "" pt 1 lc 3, \
"" using 1:(residual($21-$28)) ti "" pt 1 lc 4
set origin 0.1,0.36 #mid
set format x "" #mid, turn off x labeling
set xlabel "" #mid
set ylabel "P_{i+1}/P_i" offset 2,0
set yrange [*:*]
plot filename using 1:(($10/ $3)**1.5) ti "P_2/P_1" pt 1 lc 2, \
"" using 1:(($17/$10)**1.5) ti "P_3/P_2" pt 1 lc 3, \
"" using 1:(($24/$17)**1.5) ti "P_4/P_3" pt 1 lc 4
set origin 0.1,0.64 #top
set ylabel "semi-major axes"
set yrange [*:*]
plot filename using 1:($3):($4*$3) with errorbars ti "" pt 1 lc 1, \
"" using 1:($10):($10*$11) with errorbars ti "" pt 1 lc 2, \
"" using 1:($17):($17*$18) with errorbars ti "" pt 1 lc 3, \
"" using 1:($24):($24*$25) with errorbars ti "" pt 1 lc 4
unset multiplot
unset format
unset lmargin
unset bmargin
unset rmargin
unset tmargin
You probably could do this using gnuplot only (I think), but it would be painful. The easiest solution is to write an external script which will format the title for you -- e.g. in python (untested):
#python script formatTitle.py
import sys
fname=sys.argv[1]
with open(fname,'r') as f:
line1=f.readline().split()
line2=f.readline().split()
pairs=sorted(zip(line1,line2)[1:])
print (", ".join("%s=%s"%(p[0],p[1]) for p in pairs))
and then in gnuplot:
set title "`python formatTitle.py datafile.dat`"
EDIT
Your script above has a few problems. First, // is not a comment character in gnuplot -- so that will raise some sort of syntax error right away. Next, you're using filename as a string variable (which is OK) but you've not defined it anywhere. (the first line of your script would probably work except that it has been commented out). Finally, I can't check since I don't have your datafile, but your use of lmargin etc + set size + set origin is a little hard (for me) to track. Someone smarter would probably have no problem with it. When I want to explicitly align my plots however, I use the second form of margin.
#make plots go from 0.1 to 0.9 on the screen (screen range is 0-1)
# (0,0) is the lower left corner, (1,1) is the upper right.
set lmargin at screen 0.1
set rmargin at screen 0.9
And then for each of your sub-plots, you can do:
NPLOTS=3
SCREENSIZE=0.8 #leave .1 for the top and bottom border
DY=SCREENSIZE/NPLOTS #height of each plot
#bottom
set tmargin at screen 0.9-2*DY
set bmargin at screen 0.9-3*DY
#other commands
plot ...
#middle
set tmargin at screen 0.9-DY
set bmargin at screen 0.9-2*DY
#other commands ...
plot ...
#top
set tmargin at screen 0.9
set bmargin at screen 0.9-DY
#other commands ...
plot ...
Of course, you can play around with the positions as you see fit.