My question is very simple. Suppose I have a datafile with column headers, like as follows
first second
1 1
2 1
3 6
4 9
In gnuplot how do i make it so that the datafile is plotted using the column header as axis label? e.g. by calling
plot datafile using 1:2
i get the xaxis labeled first and the yaxis labeled second?
edit: I do know that I can use the column header as a key entry via set key auto title column head, however that's not quite what I'm looking for.
To elaborate the suggestion of #andyras, here is how you can do it:
datafile = 'filename.txt'
firstrow = system('head -1 '.datafile)
set xlabel word(firstrow, 1)
set ylabel word(firstrow, 2)
plot datafile using 1:2
You must plot with the explicit using statement, otherwise gnuplot will complain about bad data on line 1.
I don't think this feature is built in to gnuplot; you would probably have to use an awk-like utility to pull those labels out of a datafile.
You could try submitting a feature request on gnuplot's sourceforge site, and get feedback from the developers there.
Another question where people believe it can't be done with gnuplot. Here is a simple gnuplot-only solution without external tools, hence platform-independent.
Data: SO16089301.dat
first second
1 1
2 1
3 6
4 9
Script: (works with gnuplot 4.6.0, March 2012)
### extracting axes labels from datafile
reset
FILE = 'SO16089301.dat'
stats FILE u (myX=strcol(1), myY=strcol(2)) every ::0::0 nooutput
set xlabel myX
set ylabel myY
plot FILE u 1:2 w lp pt 7 lc rgb "red"
### end of script
Result:
I think it is supported. You are just supposed to be able to use "":
plot 'file' using "first":"second"
Although, if you want to do math in your using specification, you'll need the column("") function, too
plot 'file' using "first":(column("second")-(column("thrid"))
(Using only quoted header names with the math didn't work for me, anyway.)
Related
I'm trying to build a graph with a csv file.
It's supposed to have an undetermined number of data blocks inside.
My CSV looks like this :
year;amount;NAME1
year;amount;NAME1
year;amount;NAME1
year;amount;NAME2
year;amount;NAME2
year;amount;NAME2
So I want my graph to have two curves (or more if there's more blocks), one named NAME1 and the other NAME2.
The only way I've fount to retrieve the name is by using:
title columnhead(3)
But by using this, the first line of my csv is missing, and I can't figure why ...
Here's my script generating the image
gnuplot <<EOF
set terminal png
set title "Stages par professeur par années"
set output "stages_entr_ann.png"
set auto x
set key on outside left bmargin
set datafile separator ";"
set xtics 1
set ytics 1
stats 'fichier3_t.stat'
plot for [IDX=0:STATS_blocks-1] 'fichier3_t.stat' index IDX u 1:2 title columnhead(3) with linespoints ls IDX
EOF
(There's an unknow amount of blocks, so I'm using STATS_blocks)
The point is that columnhead expects something like this:
Year Amount Name
2013 5000 John
2014 8000 Max
2015 12000 Susanne
i.e. the first row of each colum is treated as label, not as data. While gnuplot extracts the name fine, it ignores the rest of the line.
There is no simple and direct solution for this, but you can do a workaround:
plot for [IDX=0:STATS_blocks-1] 'fichier3_t.stat' index IDX u 1:(1/0) title columnhead(3) with linespoints ls IDX, for [IDX=0:STATS_blocks-1] 'fichier3_t.stat' index IDX u 1:(1/0) notitle with linespoints ls IDX
To make it more clear:
plot 'fichier3_t.stat' ... u 1:(1/0) title columnhead(3) with linespoints ..., \
'fichier3_t.stat' ... u 1:2 notitle with linespoints ...
The first command is similar to yours, it just does not plot any data (because 1/0 is always invalid). It's only there to generate the entry in the legend (key).
The second command plots the data, but does not generate any entry in the legend. Just make sure the same line style is assigned to the two plots.
If the table is large and speed is a problem, you may also use every for the title generating command to reduce the number of points it trys to plot.
Finally, you may also get the message "No valid data in xrange" or similar. That's intended here but shouldn't be a problem.
I want to use gnuplot for real time plotting (Data gets appended to file which I use for plotting and I use replot for real time plotting). I also want to put a label for the latest entry which is plotted. So as to get a idea what is the latest value. Is there a way to do this?
If you are on a unixoid system, you can use tail to extract the last line from the file and plot it separately in whatever way you desire. To give a simple example:
plot\
"data.dat" w l,\
"< tail -n 1 data.dat" u 1:2:2 w labels notitle
This will plot the whole of data.dat with lines and the last point with labels, with the label depicting the value.
There is no need to use the Linux command tail, you can simply do it with gnuplot-only, hence platform-independently.
The principle: while plotting the data, you assign the values of column 1 and 2 to variables x0 and y0, respectively.
After the first plot command, x0 and y0 will contain the last values.
With this, you don't have to load the file a second time for extracting the last values.
For the label plotting, use these values and print the label with a sprintf() expression (check help sprintf).
The construct '+' u ... every ::0::0 is just one way of many ways to plot a single data point.
Data: SO28152083.dat
1 5.1
2 2.2
3 3.3
4 1.4
5 4.5
Script: (works with gnuplot 4.4.0, March 2010 or even with earlier versions)
### plot last value as label
reset
FILE = "SO28152083.dat"
set key noautotitle
set offsets 0.5,0.5,1,1
plot FILE u (x0=$1):(y0=$2) w lp pt 7 lc rgb "red" ti "data", \
'+' u (x0):(y0):(sprintf("%g",y0)) every ::0::0 w labels offset 0,1
### end of script
Result:
I am trying to make a plot in GNUplot using smooth csplines command. The data file can have many different sections to plot (not constant) and i wold like to use the lc variable option to differentiate them with different color. Am i wrong of is not supporting the lc variable option?
Correct, you cannot mix smooth and lc palette in a single plot command. You could write the smoothed data to an intermediate file with set table and then plot this data with lc palette.
Consider the example file test.txt:
1
3
2
5
4
6
Now plot this with:
set table 'tmp.txt'
plot 'test.txt' using 0:1 smooth cspline
unset table
And then plot the file tmp.txt with lc rgb variable or similar:
rgb(r,g,b) = 65536 * int(r) + 256 * int(g) + int(b)
plot 'test.txt' using 0:1 pt 7 t 'original', \
'tmp.txt' using 1:2:($2 < 4.2 ? rgb(255,0,0) : rgb(0,255,0)) with lines lc rgb var t 'smoothed'
Result with 4.6.4:
Note, that this doesn't allow you to use some criteria contained in an additional column of your original data for coloring (say, in the third column of test.txt). That would require much more fiddling.
I'd like to draw an impulse graph from a text file that looks like this:
II 5 0 0 288.40 1.3033e+14
II 6 0 0 289.60 1.5621e+14
II 1 4 0 302.70 3.0084e+13
II 2 4 0 303.40 4.0230e+13
II 1 5 1 304.40 3.4089e+13
The plot conceptually should be plot "datafile.dat" using 5:6 w impulses ls $2.
Basically, given a previously defined set of line styles, I'd like to input the line style number from column 2 for every couple of plotted points from column 5 and 6.
Also I'd like to create a text box, for every plotted point, taking strings from the first four columns.
Does somebody know if that's possible?
To use the data from column two as line style use set style increment user and linecolor variable:
set style increment user
plot "datafile.dat" using 5:6:2 with impulses lc var
In order to place a label, use the labels plotting style:
plot "datafile.dat" using 5:6:1 with labels offset 0,1
Putting everything together, you have:
set style increment user
set for [i=1:6] style line i lt i
set yrange [0:*]
set offsets 0,0,graph 0.1,0
plot "datafile.dat" using 5:6:2 with impulses lc var, "" using 5:6:1 with labels offset 0,1
The result with 4.6.3 is:
Thanks for the helpful answer above. It almost solved my problem
I'm actually trying to use a column from my data file to specify a linestyle (dot, squares,triangles, whatever as long as it's user-defined), and not a linecolor. Is there any way to do that?
This line works : I get points with different colors (specified in column 4), but the point style is the same.
plot "$file" u 1:2:4 w p notitle lc var, "" using 1:2:3 with labels offset 0,1 notitle
Replacing lc with ls after defining my own styles doesn't work (ls can't have variable as an option)
I can live without different linestyles, but it would be much prettier.
You only have to replace the lineset for [i=1:6] style line i lt i for set for [i=1:6] style line i lt i pt %, Where % can be any type of point you want
My data file looks like this
A 20120301 4
A 20120302 3
B 20120301 5
B 20120302 6
C 20120303 5
except there are many more than just A,B,C and I want to create a stacked graph with gnuplot (similar to the "Stacked histograms" from the gnuplot demos)
20120301 = (A:4 + B:5)
20120302 = (A:3 + B:6)
20120303 = (C:5)
So far I could not convince plot to read the data in that format. Do I have re-arrange the data file for this? Or is there a way for gnuplot to read the data in that format?
I think I've managed to beat it into a form that will work (you'll need at least gnuplot 4.3):
set boxwidth 0.75 absolute
set style fill solid 1.00 border lt -1
set datafile missing '-'
set style histogram rowstacked
set style data histograms
set yrange [0:]
plot for [i=2:4] 'test.dat' u i,'' u (0.0):xtic(1) notitle
and here's the datafile test.dat
#date A B C
#missing data is marked by a minus sign
20120301 4 5 -
20120302 3 6 -
20120303 - - 5
Phew! I've never been much good with gnuplot when it comes to histograms. Hopefully this will work for you (Sorry about the change to your datafile).