how to make several plots from the same standard input data in gnuplot? - gnuplot

I want to have a single .plt file storing both data and gnuplot commands. My data looks like
# x1 y1 x2 y2
1 2 3 4
5 6 7 8
and corresponds to two plots: (x1,y1) and (x2,y2).
I know I can use "-" like:
plot "-" using 1:2
# x1 y1 x2 y2
1 2 3 4
5 6 7 8
e
But that would generate only one plot, i.e., (x1,y1). I'm trying to do something like
plot "-" using 1:2, "-" using 3:4
# x1 y1 x2 y2
1 2 3 4
5 6 7 8
e
but obviously that doesn't work since gnuplot expects a new set of data from the standard input for the second "-".
Notes:
I cannot change the style of the data. It comes in four columns.
It seems that I can do it with reread but that requires two files. I really want only one file.

You can't do this without modifying something about the way you input the data. When feeding gnuplot data via standard input, it expects multiple data sets to be delimited with two blank lines between them, or to be interleaved on successive lines. The options are:
Feed the two data sets into different
plot commands altogether.
Change the
file format so that data sets have
blank lines between them, then
reference them all with index.
Change the file format so that
alternating lines represent different
data sets, then reference them all
with every.
Put the data into one
file, the plotting script into
another, and then reference the data
file more than once with different
using clauses each time.
There's an intro to the every and index commands starting at How do I plot several data sets in a single file? Those are the only facilities built into gnuplot for this sort of thing, and neither does exactly what you were asking about. it's good you've already modified the data formatting, because this wasn't ever going to work as you'd originally hoped.

I'm not sure how much you can edit the file, but the tidiest way is probably to put the whole thing in a shell script/batch script (are you on linux or windows?)
On linux I do something like this
#!/bin/bash
#put my data in a file
echo "
# x1 y1 x2 y2
1 2 3 4
5 6 7 8
" > my_dat.dat
#launch gnuplot
gnuplot<<EOF
#gnuplot commands here
set output "test.ps"
set term postscript
plot "my_dat.dat" u 1:2, \
"my_dat.dat" u 3:4
set term pop
set output
EOF
# cleanup
rm my_dat.dat
Then I chmod +wrx the file I put the above commands in and run.
Note: there also seems to be a similarity to this question:
gnuplot stdin, how to plot two lines?
So you might want to look there too

New option since gp5.0 (see also help inline data) :
$dataset << EOD
1 2 3 4
5 6 7 8
EOD
plot $dataset using 1:2, $dataset using 3:4

I know this is an old post, but I would like to point to another strategy in case someone else still struggles with this issue:
You could also use your plotting command and input the data twice, like:
plot "-" using 1:2, "-" using 3:4
# 1 2 3 4
5 6 7 8
e
1 2 3 4
5 6 7 8
e
Gnuplot will actually wait for two blocks in this case. I find this very useful when I don't want to change the commands and when I am feeding Gnuplot by pipe. In a real-time scenario (depending on the data-size) this is very likely to be still faster than buffering to a file on the hard-drive.
In my experience the amount of code required to buffer the data in your script, which is required to pipe it more than once, is very low.

Related

Using nested for loop in gnuplot

I am trying to plot a set of graphs to compare the simulation results with the experimental data. The simulation files are in ordered arrangement on 7X7X7 for various parameters. I need to plot all of those files using a nested for loop for each iXjXk file. The files are named thus : fibrilAll_i_j_k.dat
I have already tried some alternatives like using multiple for loop in the same line. But it doesn't seem to work.
set terminal eps size 1200,800
set output "all.eps"
set title "{/*2 Alternative rates}"
set ylabel "{/*2 fibril mass fraction}" offset 1.5,0,0
set xlabel "{/*2 Time(h)}"
set key left top
plot 'experiment.txt' using 1:6 ps 2 pt 5 title "EXP",\
for [i=1:7] for [j=1:7] for [k=1:7] 'fibrilAll'._i_j_k.'.dat' using 1:2 with lines title 'i,j,k'
replot
I get the following error message:
internal error : STRING operator applied to undefined or non-STRING variable
I see a few possible problems.
1) I take it you do not want to plot the same file fibrilAll_i_j_k.dat 343 times.
If the data files are named e.g. fibrilAll_1_5_3.dat then you can construct that name by saying plot ... sprintf("fibrilAll_%d_%d_%d.dat",i,j,k)
2) Probably you want something similar for the titles
3) The replot does not accomplish anything. Did you leave out something?

Gnuplot shell script ROS data from multiple files

I'm trying to plot data from two different rosbag files using gnuplot. I'm trying to automate this as I have quite a few files that will need to be run.
I need to take the first element of the first column of each file and offset the data of the column w.r.t. that (and then divide by 10^9) to get the time in seconds. My issue is my script returns something different when I run it multiple times. It will either return the first, the second, or (occasionally) the third plot command, which is what I'm interested in.
The code I've cobbled together is below:
#!/bin/bash
gnuplot -persist <<-EOFMarker
set autoscale
set datafile separator ","
set key autotitle columnhead
plot "bag1" using (\$1):2 with linespoints
first=GPVAL_DATA_X_MIN
plot "bag2" using (\$1):3 with linespoints
second=GPVAL_DATA_X_MIN
plot "bag1" using ((\$1-first)/10**9):2, "bag2" using ((\$1-second)/10**9):3
EOFMarker
An example of the dataset is:
%time,field.1,field.2,field.3
1.50317427276591E+018,23,64,64
1.50317427281556E+018,232,74,64
1.50317427285689E+018,216,76,64
1.50317427287325E+018,183,85,64
1.50317427292519E+018,165,89,64
1.50317427298662E+018,129,96,64
1.50317427300161E+018,115,101,64
1.50317427309547E+018,102,112,64
And the second input file is:
%time,field.1,field.2,field.3,field.4
1.50317425501603E+018,55,45,229,98755
1.50317425501843E+018,55,45,229,98752
1.5031742550235E+018,51,43,229,98758
1.50317425502979E+018,51,43,229,98761
1.50317425504176E+018,55,41,231,98764
1.50317425504579E+018,55,41,231,98770
1.50317425504728E+018,50,42,232,98773
1.50317425504855E+018,50,42,232,98773
1.50317425505353E+018,55,41,229,98770
1.50317425506442E+018,55,41,229,98770
I've never experienced code where multiple runs produces different results. Can anyone point me in the right direction to fix this mess?
The outputs are the three plots below. No error message is output from the script at any time.
First output:
Third (and desired) output:
I don't know why you are sometimes getting different results; I always get the output of the last plot command. However, you seem to be using the first two plot commands only to get the minimum value of the first column for each of the two files. A better way that doesn't generate any plots would be
set datafile separator ","
set key autotitle columnhead
stats "bag1" using 1
first=STATS_min
stats "bag2" using 1
second=STATS_min
plot "bag1" using (($1-first)/10**9):2, "bag2" using (($1-second)/10**9):3

Creating an animation from multiple data files

I have some C++ code that generates data I want to create an animated gif (or equivalent) from. The data is output into .txt files with the names 1, 2, 3, 4 ..., N with 2 columns (x y data points). For simplicity say we use 100 files.
There seems to be 1 of 2 ways to do this, either create 100 png images from the 100 files then use GIMP to create a gif or create a gif automatically via GNUplot. The first I should be able to do with a loop, say;
set term png
for [i=1:100] {set output "data".i."png"; plot 'filepath/'.i.'.txt' with lines title ""; set output}
Which gives me the error: 'invalid complex constant'. This I suspect is just be being bad with GNUplot syntax.
As for the second, the examples I can find make it unclear how to use data to generate the plots.
Any help is much appreciated.
For gnuplot versions older than 4.6 you can use reread to do such kind of looping.
Consider the file looper.gp:
set output 'data'.i.'.png'
plot 'filepath/'.i.'.txt' with lines notitle
i = i + 1
if (i <= 100) reread
Call this with
i = 1
set terminal png
load 'looper.gp'
set output

Plotting on Gnuplot - skipping lines

I have some problems with reading my file in Gnuplot.
For example, I have a file like this:
___________________________________________
'#current'
month followed retweeted mentioned replied
Jan 395 29 35 28
Feb 380 28 32 31
'#previous'
month followed retweeted mentioned replied
Jan 381 30 38 32
Feb 378 25 42 30
Mar 374 28 46 40
______________________________________________________
I need to read only the second block, which starts with tag "#previous". How can I do it? I tried this command:
plot "data.txt" index 'previous' using 3:xticlabel(1) axes x1y1 with lines linecolor rgbcolor "red",\
but it doesn't work. Any ideas?
Check out the answer to this question
Gnuplot: Plotting several datasets with titles from one file
I think you need to add a 1 after index like so
plot "data.txt" index 1 using 3:xticlabel(1) axes x1y1 with lines linecolor rgbcolor "red"
edit:
Datasets are 0-indexed so the first block is indexed 0 and the second block (previous) has an index one. The error you mention regarding the bad line indicates a problem with our data file format.
Read about the data format at these links
http://www.gnuplotting.org/plotting-data/
http://lowrank.net/gnuplot/datafile2-e.html
Let us put everything together:
Following this link you can learn how to filter the file (so you can get everything after certain line)
So in our case:
sed -e '1,/previous/d' data.txt > gnuplot some_gnuplot_options
I write this from my windows devel machine so can't validate but this should give you some idea how can you do this.
I would also recommend defining gnuplot config file you feed to gnuplot. Just create settings.pg and put there something like this (that's my example from some work I have done for myself so it does not apply to your data format):
set terminal png size 1024, 360
set output "load.png"
set datafile separator "\t"
set timefmt "%Y-%m-%d %H:%M:%S"
set xdata time
set format x "%m/%d\n%H:%M"
set xrange["2012-04-29 11:00:00":"2012-05-01 11:58:00"] noreverse nowriteback
set autoscale y
set grid
set key left box
plot "chart.txt" using 1:2 t 'column_1' with lines, "chart.txt" using 1:3 t 'column_2' with lines
So then your gnuplot call would look something like this:
sed -e '1,/previous/d' data.txt > gnuplot your_pg_file.pg
You would also want to check time formating from gnuplot manuals here.
edit:
If that's your university homework you should not post your question here :-) I don't want to be boring or something but is it not the goal of homework that you find your solution following documentation study and trying different things eh? :-)

Is it possible to set the "linetype" in gnuplot while using "linecolor variable"?

I have a tab-separated data file containing a number of (double-blank-line-separated) datasets and I want to plot a line for each of them. I want to be able to set the linetype (by this I'm referring to solid/dashed/dotted). I want each line to be a different color.
I can plot them all different colors using this:
plot 'example.dat' using 1:2:(column(-2)) with lines linecolor variable
And I can set the linetype but plot them all the same color using this:
plot 'example.dat' using 1:2:(column(-2)) with lines linetype 5
But when I combine them, the linetype is not what I set it to (in this case I just get a solid line).
plot 'example.dat' using 1:2:(column(-2)) with lines \
linetype 5 linecolor variable
Is there a way to achieve this?
I'm using gnuplot 4.6, tried with the x11 and postscript terminals.
This looks like a bug to me. Unfortunately, I don't think too many gnuplot devs hang out on StackOverflow, so we might not ever find out. (I would encourage you to submit a bug report though and keep me updated on any progress that might be made)...
If you're really using column(-2) to pick out the colors, the problem becomes a lot easier and you should be able to do that using plot iteration (as long as you know an upper limit on the number of datasets).
NDSET=3 #This will issue a warning if NDSET is too big, but will still work.
plot for [IDX=0:NDSET] 'example.dat' index IDX using 1:2 with lines linetype 5 linecolor IDX+1
The indexing starts from 0 and corresponds to column(-2). Linecolor 0 isn't defined (I don't know why gnuplot uses two different conventions here -- I suppose because in theory the colors corresponding to any particular linestyle are terminal dependent, so it doesn't really matter too much anyway...)

Resources