How to treat the first line of the data file as column labels in gnuplot? - gnuplot

I have a table like this:
A B C D E F G H I
10 23998 16755 27656 17659 19708 20328 19377 18925
20 37298 33368 53936 41421 44548 40756 40985 37294
I use this command to plot
plot "C:/file.txt" using 1:2 with lines smooth bezier, "C:/file.txt" using 1:3 with lines smooth bezier, ...
However, all the labels come out as the file name. Is it possible for gnuplot to read the first row and label the lines accordingly?

set key autotitle columnhead

plot for [n=2:12] 'vv.csv' u 1:(column(n)) w lines title columnhead(n)
n starts from 2 to skip the header.

I checked the documentation and I don't see a way to do it automatically, but you can manually set a title with
plot "file.txt" using 1:2 title "A" with lines smooth bezier ...

I once wrote a script to plot FM radio station frequencies along an axis from 87MHz to 108MHz, using the names of each radio station as vertical labels. This was not a pure gnuplot solution, the input file is processed with perl with make, but I suggest you have a look at it and see if you can use something like that.

You could also use a gnuplot toolkit such as this one for Python if you want have a lot of data to plot and you want to automate the extraction of the titles.

Related

Plotting 1D data as constant functions in 2D plot with gnuplot

I have a 2D plot and want to draw horizontal straight lines from a given data file, so that each data point of the file is represented as a horizontal straight line in the existing 2D plot.
My approach so far:
I've tried using the for command, but I don't know how to write the current data point into a formular like x = C where C is the value of the data point:
for [i=1:10] "data.dat" u 2 every ::i::i
... is not what I meant.
for [i=1:10] x = "data.dat" u 2 every ::i::i
... is not a valid gnuplot command.
And furthermore, the range of i is variable, so that is another problem I have to solve with this approach.
Using arrows:
Like this posts suggests: Adding Horizontal lines on 2D plot with gnuplot. But in that example the author didn't need to draw the lines from a data file.
Is there a good way to do this?

Plotting heatmaps in gnuplot

So, here I am trying to plot heatmaps in gnuplot. I have a matrix-formatted text file (with row and column headers), and the command I am using to plot it is
plot "file.txt" matrix rowheaders columnheaders using 1:2:3 w image notitle
The output is this graph:
Obviously, the X and Y labels are useless like this. I believe the problem here is that gnuplot is extracting all labels from the file and plotting them. How would I go about reducing the amount of clutter in here, e.g. plotting every 10th label or so?
Thanks in advance.
Or just make the picture resolution bigger... for instance like 1920,1080 or bigger... like this:
set term pngcairo size 1920,1080
or make the tics numbers like 1000000 smaller and make a label to show that the numbers written on the tics are 1000000 bigger... or both:)
Sorry for my english...

Performing calculations between multiple data files in gnuplot [duplicate]

I have 2 dat files:
a.dat
#Xs
100 25
200 56
300 75
400 67
b.dat
#Xs
100 65
200 89
300 102
400 167
I want to draw a graph in the gnuplot where the yy values are a ratio between the values of a.dat and b.dat respectively. e.g., 25/65, 56/89, 75/102, and 67/167.
How I do this? I only know make a plot like this, and not with the ratio.
plot "a.dat" using 1:2 with linespoints notitle
"b.dat" using 1:2 with linespoints notitle
You cannot combine the data from two different files in a single using statement. You must combine the two files with an external tool.
The easiest way is to use paste:
plot '< paste a.dat b.dat' using 1:($2/$4) with linespoints
For a platform-independent solution you could use e.g. the following python script, which in this case does the same:
"""paste.py: merge lines of two files."""
import sys
if (len(sys.argv) < 3):
raise RuntimeError('Need two files')
with open(sys.argv[1]) as f1:
with open(sys.argv[2]) as f2:
for line in zip(f1, f2):
print line[0].strip()+' '+line[1],
And then call
plot '< python paste.py a.dat b.dat' using 1:($2/$4) w lp
(see also Gnuplot: plotting the maximum of two files)
The short answer is that... you cannot. Gnuplot processes one file at a time.
The work-around is to use an external tool, e.g. using the shell if you have a unix-like, or gnuplot.
join file1 file2 > merged_file will allow you to merge your files quite easily if the first column is identical in both files. Options allow to join on other columns and manage data missing in either file.
In case there is no common column but hte line number is relevant, paste will do.
In case interpolation is required, because the grids in the two files differ, you have to code this. I have a command-line utility that I distribute as free open-source software and can help: datamerge.
There is a trick if the two datasets don't fit (different sampling in x), but you have a good mathematical model for at least one of them:
fit f2(x) data2 us 1:2 via ...
set table $corr
plot data1 using 2:(f2($1))
unset table
plot $corr using 1:2
This is of course nonsense if both datasets have the same set of independent variables, because you can simply combine them (see other answers).
Just for fun, there is a gnuplot-only and platform-independent solution.
For sure, the command plot '< paste a.dat b.dat' using 1:($2/$4)' from Christoph's answer is unbeatable short (and certainly efficient) in case you are working under Linux or installed the CoreUtils from GnuWin under Windows.
The solution below takes the detour via two long strings. This should work fine unless there is a length limit of strings in gnuplot. I tested only until 100'000 data lines, which will take quite a few minutes. The assumption is that the two files have equal lines with identical x-values. For gnuplot>=5.0 you could write into a datablock instead of a file on disk and do further optimizations.
Script: (works with gnuplot>=4.6.0, March 2012)
### get ratio of numbers from different files
reset
FILE1 = "SO20069641a.dat"
FILE2 = "SO20069641b.dat"
FILE = "SO20069641.dat"
# create some random test data
set samples 100
set table FILE1
plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
set table FILE2
plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
unset table
a = ''
b = ''
stats FILE1 u (a=a.' '.strcol(1).' '.strcol(2)) nooutput
stats FILE2 u (b=b.' '.strcol(1).' '.strcol(2)) nooutput
set table "SO20069641.dat"
set samples words(a)/2
splot '+' u (n=2*(int($0+1)),real(word(a,n-1))):(real(word(a,n))):(real(word(b,n)))
unset table
plot FILE u 1:($2/$3) w impulses
### end of script
Result:

Get ratio from 2 files in gnuplot

I have 2 dat files:
a.dat
#Xs
100 25
200 56
300 75
400 67
b.dat
#Xs
100 65
200 89
300 102
400 167
I want to draw a graph in the gnuplot where the yy values are a ratio between the values of a.dat and b.dat respectively. e.g., 25/65, 56/89, 75/102, and 67/167.
How I do this? I only know make a plot like this, and not with the ratio.
plot "a.dat" using 1:2 with linespoints notitle
"b.dat" using 1:2 with linespoints notitle
You cannot combine the data from two different files in a single using statement. You must combine the two files with an external tool.
The easiest way is to use paste:
plot '< paste a.dat b.dat' using 1:($2/$4) with linespoints
For a platform-independent solution you could use e.g. the following python script, which in this case does the same:
"""paste.py: merge lines of two files."""
import sys
if (len(sys.argv) < 3):
raise RuntimeError('Need two files')
with open(sys.argv[1]) as f1:
with open(sys.argv[2]) as f2:
for line in zip(f1, f2):
print line[0].strip()+' '+line[1],
And then call
plot '< python paste.py a.dat b.dat' using 1:($2/$4) w lp
(see also Gnuplot: plotting the maximum of two files)
The short answer is that... you cannot. Gnuplot processes one file at a time.
The work-around is to use an external tool, e.g. using the shell if you have a unix-like, or gnuplot.
join file1 file2 > merged_file will allow you to merge your files quite easily if the first column is identical in both files. Options allow to join on other columns and manage data missing in either file.
In case there is no common column but hte line number is relevant, paste will do.
In case interpolation is required, because the grids in the two files differ, you have to code this. I have a command-line utility that I distribute as free open-source software and can help: datamerge.
There is a trick if the two datasets don't fit (different sampling in x), but you have a good mathematical model for at least one of them:
fit f2(x) data2 us 1:2 via ...
set table $corr
plot data1 using 2:(f2($1))
unset table
plot $corr using 1:2
This is of course nonsense if both datasets have the same set of independent variables, because you can simply combine them (see other answers).
Just for fun, there is a gnuplot-only and platform-independent solution.
For sure, the command plot '< paste a.dat b.dat' using 1:($2/$4)' from Christoph's answer is unbeatable short (and certainly efficient) in case you are working under Linux or installed the CoreUtils from GnuWin under Windows.
The solution below takes the detour via two long strings. This should work fine unless there is a length limit of strings in gnuplot. I tested only until 100'000 data lines, which will take quite a few minutes. The assumption is that the two files have equal lines with identical x-values. For gnuplot>=5.0 you could write into a datablock instead of a file on disk and do further optimizations.
Script: (works with gnuplot>=4.6.0, March 2012)
### get ratio of numbers from different files
reset
FILE1 = "SO20069641a.dat"
FILE2 = "SO20069641b.dat"
FILE = "SO20069641.dat"
# create some random test data
set samples 100
set table FILE1
plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
set table FILE2
plot '+' u (int($0+1)*100):(int(rand(0)*100)+1)
unset table
a = ''
b = ''
stats FILE1 u (a=a.' '.strcol(1).' '.strcol(2)) nooutput
stats FILE2 u (b=b.' '.strcol(1).' '.strcol(2)) nooutput
set table "SO20069641.dat"
set samples words(a)/2
splot '+' u (n=2*(int($0+1)),real(word(a,n-1))):(real(word(a,n))):(real(word(b,n)))
unset table
plot FILE u 1:($2/$3) w impulses
### end of script
Result:

How to add custom label to Gnuplot graph legend?

In a graph I'm making with gnuplot I draw some grey lines (set arrow command), which represent the physical boundaries of my experiment (i.e., walls)
I would like to know how I can add this information on the legend of the graph, so it says "Walls" and have a grey line next to it.
I thought about creating a new series that contained this information, but I was wondering if it's possible to explicitly add it.
You can't add information directly to the legend. You can, however, either draw the legend explicitly, or plot a line which will not appear within the range of the plot, e.g.
plot [][0:1] 2 lc rgb 'gray' t 'Walls'
Or, if your x and y limits are already set:
...
[set x and y limits here]
...
plot 1e20 lc rgb 'gray' t 'Walls'
Just wanted to note: since plotting a single line tended to mess up a graph of mine, a better solution for me was to plot a single point; but as found in Plotting single points « Gnuplotting, that is kinda difficult (especially if insertion at arbitrary plot legend/key position is needed) - unless redirection is used... This is what worked for me:
plot "filename" using 1:8 \
,\
... # more plot lines here
,\
"<echo '-1 -1'" lc rgb 'white' with points title '---' \
,\
... # more plot lines here
One simple way is to make the name of the data file the legend which you want and then plot that data file.

Resources