how to output dots/arrows at the ends of line - gnuplot

I am new to gnuplot, I need to plot my data and display a small circle or an arrow at each end of the line chart. how can I do that?
I use this command to display the line chart:
plot 'data.txt' with lines

I don't know if there is a way to make lines have something at the end automatically, but I found a workaround. With this data file:
1 1
2 3
3 2
and the following script:
set term png
set out 'plot.png'
stats 'data.dat' name 'a'
# plot line, then circle only if it is the last data point
plot 'data.dat' t 'data', \
'' u ($0==(a_records-1)?$1:1/0):2 with points pt 7 ps 2 t 'end'
I can make a plot like this:
The stats command is to find the number of data points, then the dual plot command draws the line connecting the data points, then a circle only on the last data point (determined with the a_records variable. An arrow would be trickier to draw...
To find more info about different point/line style options, the test command at the gnuplot command line is your friend.

Related

Plotting multiple files every file in separate graph using gnuplot

I have more than 1000 files named as "snap%d_beta800.dat" where %d is a number between 1 and 1000.
I want to plot every one of these files in a separate surface plot (splot function) (using three columns) , save the result in png format with the same name as the original file: e.g snap1.png
I want to write a script that can do this for all the 1000 files in just once by loading a gpl file
In addition to that i want to create an animation for the 1000 files.
I am appreciating if you can help with that and please have a look of what I tried
what I tried does not give me a separate plot for every file, it just accumulates the plots of all the files in only one plot
set term png
splot [][][-3:3] for [i=1:1000] 'snap'.i.'_beta800.dat' us\
($1)-($4)/2:($2)-($5)/2:($3*0)-($6)/2:\
($4)*1:($5)*1:($6):($6) w vec head filled size screen 0.015,10,30 lw 2 lc pal z
set output "snap".i.".png"
replot
set term x11
As #GRSousaJr wrote, put it into a do for loop.
I'm wondering why you are writing your plot command like this:
... using ($1)-($4)/2:($2)-($5)/2:($3*0)-($6)/2:($4)*1:($5)*1:($6):($6) ...
I would simply write:
... using ($1-$4/2):($2-$5/2):(-$6/2):4:5:6:6 ...
Code:
### Batch create PNG files
set term pngcairo size 600,600
do for [i=1:1000] {
fname_in = sprintf("snap%d_beta800.dat",i)
fname_out = sprintf("snap%d_beta800.png",i)
set output fname_out
splot fname_in u ($1-$4/2):($2-$5/2):(-$6/2):4:5:6:6 \
w vec head filled size screen 0.015,10,30 lw 2 lc pal z
}
set output
### end of code
I assume you want create your animation from these 1000 PNG files with some other software. Maybe you are aware that you can also create an animated GIF with gnuplot:
Code:
### Create animated file
set term gif size 600,600 animate delay 12 loop 0 optimize
set output "Animation.gif"
do for [i=1:1000] {
fname = sprintf("snap%d_beta800.dat",i)
splot fname u ($1-$4/2):($2-$5/2):(-$6/2):4:5:6:6 \
w vec head filled size screen 0.015,10,30 lw 2 lc pal z
}
set output
### end of code

gnuplot print column header with stats

The gnuplot stats command can be used to report stats for an input dataset. It creates a set of variables containing information about a specific column in the dataset. Here is an example of such use:
set print "StatDat.dat"
do for [i=2:9] { # Here you will use i for the column.
stats 'data.dat' u i nooutput ;
print i, STATS_median, STATS_mean , STATS_stddev # ...
}
set print
plot "StatDat.dat" us 1:2 # or whatever column you want...
It would be useful to include the reported column header, something like:
print STATS_columnheader, STATS_median, STATS_mean , STATS_stddev # ...
However gnuplot does not provide the required STATS_columnheader variable.
Is there an alternative way to achieve this ?
You can use an external tool such as awk to extract and return a column header. You can create a function like this:
columnheading(f,c) = system("awk '/^#/ {next}; {print $".c.";exit}' ".f)
which, given a file f and a column number c, will return the column header. You'd use it like this:
print columnheading('StatDat.dat',i).' ', STATS_median, STATS_mean , STATS_stddev # ...
The awk expression skips all lines until the first non-comment line, prints the word given by the c parameter and exits. The printed word is returned by gnuplots system command.
Workaround
A quick & dirty solution already expressed as comment to the answer here:
it is possible to store the header line once for all in a variable, then to call it when it is needed.
Under *nix it is possible to use head or a combination such head -n 10| tail -n 1 if it is in the 10th line...
Here the example modified:
firstrow = system('head -1 '.datafile) # you call here only one time
set print "StatDat.dat"
do for [i=2:9] { # Here you will use i for the column.
stats datafile u i nooutput ;
print word(firstrow, i), " ", STATS_median, STATS_mean , STATS_stddev
# or whatever you want...
}
set print
plot "StatDat.dat" us 1:2 # or whatever column you want...
Note that the gnuplot function word will return the nth word in string, so you may have problem if the header is composed from more than a word...
... problems that you can overcome with other tricks
Only a path to a hack/trick
The following doesn't works because gnuplot starts to process the file in the plot command after skipping the header and the commented lines...
Since a function can assume the form f(x) = (statement1, statement2, statement3, return value) executing the statements and returning the value (see, e.g.), you can image to build a function that stores the first line "field by filed" in an array (directly form gnuplot 5.1, via some other tricks before), maybe hiding the plot with set terminal unknown.
array MyHeader[4]
f(x,y,z) = (x == 0 ? (MyHeader[y]=z, z ) : z)
set terminal unknown # set terminal dumb
set key autotitle columnhead
do for [i=2:4] { # Here you will use i for the column.
plot datafile using 1:(f($0,i,column(i)))
}
print MyHeader
Unfortunately the above script stores only the 1st row values...
but for the moment I've finished the time I can dedicate to this problem :-(
(maybe someone can find useful some hint, or finish it).
What exactly do you want to do with the headers?
As you can see in the plot command, apparently gnuplot considers the first uncommented line as header line which is then for example used for the legend.
No need for external tools or scripts. With stats you can also easily extract any line, e.g. the second line via every ::1::1.
Since gnuplot 5.2.0 (Sep 2017) you can use arrays which you can also plot,e.g. for tables within the plot.
Script:
### extract header lines via stats
reset session
$Data <<EOD
# comment line
PosX PosY Density # header line
x/m y/cm g/cm2 # (sub)header line
1 1.1 2.1
2 1.2 2.2
3 1.3 2.3
4 1.4 2.4
5 1.5 2.5
6 1.6 2.6
7 1.7 2.7
8 1.8 2.8
9 1.9 2.9
EOD
array Headers[3]
array Units[3]
do for [i=1:|Headers|] {
stats $Data u (Headers[i]=strcol(i)) every ::0::0 nooutput
stats $Data u (Units[i] =strcol(i)) every ::1::1 nooutput
}
print Headers
print Units
set key top left
plot $Data u 1:2 w lp pt 7 lc "red" ti columnheader, \
'' u 1:3 w lp pt 7 lc "blue" ti columnheader, \
Headers u ($1+3):(2.1):2 w labels notitle, \
Units u ($1+3):(1.9):2 w labels notitle
### end of code
Result:
["PosX","PosY","Density"]
["x/m","y/cm","g/cm2"]

how to customise plot title in spatstat

How may I change the plot titles and subtitles when using plot command on linnet object. For example
library(spatstat)
first = runiflpp(10, as.linnet(chicago), nsim = 2)
plot(first)
This code above gives two realisations of a a point process and a plot with the plot command because we requested for nsim=2. But it plots the two realisations with plot title 'simulation 1' and 'simulation 2'.
How can I change the subplot titles for example from simulation 1 to experiment 1?
thank you
The simplest way would be to change the names of the items in the list:
names(first) <- paste("experiment", 1:2)
Alternatively you can change the argument main.panel in plot.solist (see ?plot.solist for all the options):
plot(first, main.panel = paste("experiment", 1:2))

Index number in plot

Given the following data file 'data.dat' composed of three data sets
-2.30368 2.44474
-2.22212 0.0250215
-2.13275 0.312357
-2.10241 0.13895
-2.63484 737.779
-2.44552 0.0156069
-2.1611 0.0360564
-1.98332 0.047829
-2.55816 1.91885
-2.45481 0.0410066
-2.27375 0.0593876
-1.95196 0.0220463
I want to plot all data sets on the same plot, by powering the second column to the index of the data set
pl 'data.dat' u ($1):(($2)**0) i 0, '' u ($1):(($2)**1) i 1, '' u ($1):(($2)**2) i 2
Is there a way to do this automatically for all indexes?
Yes, i think it's possible using a loop structure.
You can try, for instance, the command line
p for [k=0:MAX] 'data.dat' u ($1):($2**k) i k
where k is growing from 0 to your MAX number previously defined in gnuplot. If you want more about loop structure in plotting data with gnuplot you can take a look on this other question on Stack Overflow.

Gnuplot 3d time animation from data file

I realise this is perhaps trivial and if I had more time I'd probably easily deal with it myself, but I'm running out of time and I desperately need to get this animation working as soon as possible.
I have data file of the type
0 28.3976 25.1876 12.7771
0.03125 34.1689 21.457 9.70863
0.0625 35.7084 17.6016 5.03987
0.09375 34.3048 13.6718 1.45238
...
where the first column is meant to be treated as time (it is in fact a numerical solution to a certain ODE system). Now. what I need is an animation of a 3d plot of the last three columns tracing a curve as it moves around with time. Is that doable? If so, how? I'm a complete gnuplot beginner and googling around did not help much. I would hugely appreciate any help. Cheers!
The following should show you an animated plot:
# define fixed axis-ranges
set xrange [-1:1]
set yrange [0:20]
set zrange [-1:1]
# filename and n=number of lines of your data
filedata = 'data.dat'
n = system(sprintf('cat %s | wc -l', filedata))
do for [j=1:n] {
set title 'time '.j
splot filedata u 2:3:4 every ::1::j w l lw 2, \
filedata u 2:3:4 every ::j::j w p pt 7 ps 2
}
The first line of the splot command plots the trayectory, and the second line plots the point at the current time.
If you want a gif of this output, simply add the following before the for-loop:
set term gif animate
set output 'output.gif'
This is an example output:
Related:
StackOverflow: Gif Animation in Gnuplot
gnuplot-surprising: creating gif animation
gnuplotting: Animation IV – trajectory

Resources