Gnuplot wouldn't reset (GIF) - animation

It is supposed to reset and make an animation.
I have tried all the suggestions from other previous posts, but I still have this result.
my datei.dat has 4 columns with an empty line seperating each block.
set autoscale
set datafile seperator ","
plot "datei.dat" index (i) u 1:2 t '1:2' with linespoints ,\
"datei.dat" index (i) u 1:3 t '1:3' with linespoints ,\
"datei.dat" index (i) u 1:4 t '1:4' with linespoints
replot
pause 1
i = i + 1
if(i<N) reread
animate.plt
reset
set term gif animate
set terminal gif animate delay 50
set output "plotalive.gif"
N = int(STATS_blocks)
i = 0
load "animate.plt"
set output
loop.plt

If n is the size of blocks you should use the every.
Index is used to separate datasets (two blank lines).
Here is a what might be done avoiding the reread (some change might be done):
set terminal dummy
plot "datei.dat"
N = int(STATS_blocks)
set terminal gif animate delay 50
set output "plotalive.gif"
set autoscale
set datafile seperator ","
do for [i=0:N] {
plot "datei.dat" u 1:2 every ::i::i t '1:2' with linespoints ,\
"" u 1:3 every ::i::i t '1:3' with linespoints ,\
"" u 1:4 every ::i::i t '1:4' with linespoints
}
set output

Related

How to keep alignment and line spacing with rotated labels in gnuplot?

You can rotate text labels as well as ticlabels.
However, if I have multiline labels, how can I keep alignment and line spacing with rotated labels which have a rotation angle other than 0°, 90°, 180° or 270°?
As you can see in the example below, aligment and line spacing are not kept with other than the above mentioned angles. What's going wrong there? I haven't checked yet whether this maybe depends on the aspect ratio of x- and y-axes? Any ideas how to fix this?
Script:
### how to keep alignment and line spacing with rotated labels?
reset session
$Data <<EOD
1 0 "multiline\nlabel"
2 30 "multiline\nlabel"
3 45 "multiline\nlabel"
4 60 "multiline\nlabel"
5 90 "multiline\nlabel"
EOD
set termoption font ",14"
set offset 1,1,2,2
set key noautotitle
plot $Data u 1:(1):3:2 w labels rotate var right , \
'' u 1:(2):3:2 w labels rotate var center, \
'' u 1:(3):3:2 w labels rotate var left
### end of script
Result:
Here another illustration that something does not work as expected:
I filed a bug report. Actually, 180° is not correct as well, line1 and line2 are swapped.
Here are two attempts to workaround the problem that apparently gnuplot rotates multiline labels around the anchor point for each line independently instead of a common anchor point for the whole label. Although, there are exceptions for 90° and 270° as you can see in the jumping text in the animation.
1. Attempt: split the multiline labels and plot them separately and add x- and y-offset depending on angle and line number. This seems to work for wxt terminal, but I haven't tested whether this works for all terminals and graph sizes.
Line(s,n) = ((c=strstrt(s,"\n"))==0 && n==2 ? '' : n==1 ? s[1:c-1] : s[c+1:strlen(s)] )
dx(n,a) = n==1 ? -sin(a) : sin(a)
dy(n,a) = n==1 ? 0.5*cos(a) : -0.5*cos(a)
2. Attempt: the first attempt will not work for ticlabels because you would create two shifted tics. Hence, in the second example, in addition to xtics with an offset for the first line, x2tics with an offset for the second line are used. However, depending on the graph height, you have to set the y-offset manually which is rather tedious. I haven't found yet a way to do this automatically (maybe with help of the GPVAL_ variables and a replot).
As a 3rd option, you could also play with multiplot and overlay differently shifted xtics, which I would consider a painful workaround as well.
I hope that there are (or will be) better solutions.
Script 1:
### rotated multiline labels (two lines)
reset session
set key noautotitle
set angle degrees
s = "multiline\nlabel"
dx(n,a) = n==1 ? -sin(a) : sin(a)
dy(n,a) = n==1 ? 0.5*cos(a) : -0.5*cos(a)
Line(s,n) = ((c=strstrt(s,"\n"))==0 && n==2 ? '' : n==1 ? s[1:c-1] : s[c+1:strlen(s)] )
set yzeroaxis ls 1
set term gif animate size 640,480 delay 10 font ",11"
set output "SO74000192_2.gif"
do for [a=0:355:5] {
s = sprintf("multi line:\nAngle: % 4d°",a)
set multiplot layout 1,2 ti "rotated multiline labels"
set title "as is"
plot 0, 1, 3, 5, 6, \
'+' u (0):(1):(s):(a) every ::0::0 w labels rotate var right, \
'+' u (0):(3):(s):(a) every ::0::0 w labels rotate var center, \
'+' u (0):(5):(s):(a) every ::0::0 w labels rotate var left
set title "workaround"
plot 0, 1, 3, 5, 6, \
for [j=1:2] '+' u (0):(1):(Line(s,j)):(a) every ::0::0 \
w labels rotate var right offset dx(j,a), dy(j,a), \
for [j=1:2] '+' u (0):(3):(Line(s,j)):(a) every ::0::0 \
w labels rotate var center offset dx(j,a), dy(j,a), \
for [j=1:2] '+' u (0):(5):(Line(s,j)):(a) every ::0::0 \
w labels rotate var left offset dx(j,a), dy(j,a)
unset multiplot
}
set output
### end of script
Result 1:
Script 2:
### rotated multiline xticlabels (two lines)
reset session
set angle degrees
set key noautotitle
$Data <<EOD
1 2 label
2 5 "multiple\nlines"
3 4 "another label"
4 7 "another two\nline label"
5 4 "single line again"
6 3 "multiline\nagain"
EOD
Line(s,n) = ((c=strstrt(s,"\n"))==0 && n==2 ? '' : n==1 ? s[1:c-1] : s[c+1:strlen(s)] )
dx(n,a) = n==1 ? -sin(a) : sin(a)
dy(n,a) = n==1 ? 0.5*cos(a) : -0.5*cos(a)
set boxwidth 0.8
set style fill solid 0.3
set yrange[0:]
a = 65
set xtic out nomirror rotate by a right offset -sin(a),0.5*cos(a) font ",11"
set multiplot layout 1,2 title "rotated multine labels"
set title "as is"
plot $Data u 1:2:xtic(3) w boxes
set title "workaround"
set link x2 via x inverse x
set x2tics rotate by a right font ",11" offset sin(a), graph -1.14 # manually adjust y-offset depending on graph
plot $Data u 1:2 w boxes, \
'' u 1:(-1):xtic(Line(strcol(3),1)), \
'' u 1:(-1):x2tic(Line(strcol(3),2))
unset multiplot
### end of script
Result 2:

Animation with gnuplot : only one cruve plotted in an animation whereas 2 expected

I have the following script which is expected to produce the animations of 2 curves :
#!/bin/bash
for i in {1..397}; do
gnuplot -p <<-EOFMarker
set terminal png;
set output "pic$i.png";
set title "power spectrum";
set xlabel "scale (k)";
set ylabel "P(k)";
set key top left;
set grid;
set ytics out nomirror;
set xtics out nomirror;
set logscale x;
set logscale y;
set format x "10^{%L}";
set yrange [0:30000];
plot "CAMB-1.3.5/matter_camb$i" u 1:2 w l;
replot "EFTCAMB_v3_beta/matter_eftcamb$i" u 1:2 w l;
EOFMarker
done
# Build movie with ffmpeg
ffmpeg -start_number 1 -i pic%d.png movie.mpeg
Every works fine excepted the fact that only one curve is plotted in animation (CAMB-1.3.5) :
Here is an example of frame :
Why the "replot" command is not taken into account in the generated image ?
Just for the sake of the SO-rule "no answer in comments":
Check help plot:
Syntax:
plot {<ranges>} <plot-element> {, <plot-element>, <plot-element>}
Examples:
plot sin(x)
plot sin(x), cos(x)
plot f(x) = sin(x*a), a = .2, f(x), a = .4, f(x)
plot "datafile.1" with lines, "datafile.2" with points
plot [t=1:10] [-pi:pi*2] tan(t), \
"data.1" using (tan($2)):($3/$4) smooth csplines \
axes x1y2 notitle with lines 5
plot for [datafile in "spinach.dat broccoli.dat"] datafile

How to use axes programmatically in Gnuplot?

If you need to draw some graphs against x1y1 or x1y2 axes, depending on the maximum y value of each graph, what would be the proper syntax for that?
My data file has several columns. The first one contains x values, the others y1, y2 and so on.
After using the stats command, I could easily define each axis value for each graph:
stats '$data_file' u 1:2 nooutput;
y1max = STATS_max_y;
if (y1max > ymax) { y1axis = 'x1y2' } else { y1axis = 'x1y1' };
stats '$data_file' u 1:3 nooutput;
y2max = STATS_max_y;
if (y2max > ymax) { y2axis = 'x1y2' } else { y2axis = 'x1y1' };
...
After that, I can draw the graphs with this plot cmd
plot '$data_file' using 1:2 axes x1y1 notitle with lines lc rgb 'black' lw 1,\
'' using 1:3 axes x1y2 notitle with lines lc rgb 'green' lw 1;
which works, but it is not programmatically at all.
But this one doesn't works
plot '$data_file' using 1:2 axes #y1axis notitle with lines lc rgb 'black' lw 1,\
'' using 1:3 axes #y2axis notitle with lines lc rgb 'green' lw 1;
where I used the Substitution of string variables as macros (The character # is used to trigger substitution of the current value of a string variable into
the command line...) which is written in the docs.
Nor the eval command likes to work for me.
Could you please provide an example for that purpose, which is working or any a good advise. THX!
I got two errors/warnings when using the above code in a bash script as an oneliner the following way
echo "gnuplot cmds;plot ..." | gnuplot
warning: y3axis is not a string variable
axes must be x1y1, x1y2, x2y1 or x2y2
As written in the docs, the macro could not be expanded the same time as it is defined, what is the case if written on the same line.
To avoid the above mistake we have to use only
echo -e "gnuplot cmds;\nplot ..." | gnuplot
and it works like it should.
Credits to #Christoph and #Ethan who put me on the right track.

gnuplot animation 2D vector fields

I'm trying to animate 2D vector with gnuplot. I want to show one line i.e, one vector at a time.
My Data Structure is as follows: They x,y,u,v
2.24448 0.270645 1.00 1.00
3.24448 0.270645 0.500 1.20
I'm able to create a static plot sing following command:
plot "datam.dat" using 1:2:3:4 with vectors filled head lw 3
Here is the output:
Here is my question: I would like to animate and show one row (i.e,) one vector at a time, how to accomplish this in GNU plot using GIF?
Thanks
Animated GIFs are created with set terminal gif animate. Check help gif for details.
Below is a simple example (tested with gnuplot 5.2). You have to make a new plot for each frame. So, put your plot command into a do for-loop. With every ::i::i you are plotting only the ith line (check help every). If you don't know the total number of lines of your datafile, do stats "YourFile.dat" and the variable STATS_records will tell you this number.
Code:
### animated graph with vectors
reset session
set term gif size 300,300 animate delay 12 loop 0 optimize
set output "AnimateVectors.gif"
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
do for [i=0:N-1] {
plot $Data u 1:2:3:4 every ::i::i w vectors lw 2 lc rgb "red" notitle
}
set output
### end of code
Result:
Addition:
This would be the non-animated version, e.g. in a wxt-terminal.
Code:
### non-animated graph with vectors
reset session
set term wxt size 400,400
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
plot $Data u 1:2:3:4 w vectors lw 1.5 lc rgb "red" notitle
### end of code
Result:
Addition2:
Do you maybe mean something like this? A "semi"-animated arrow? By the way, as you can see the arrow look quite different in gif and wxt terminal.
Code:
### "semi"-animated graph with vectors
reset session
set term gif size 300,300 animate delay 12 loop 0 optimize
set output "AnimateVectorsSemi.gif"
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
do for [i=0:N-1] {
plot $Data u 1:2:3:4 every ::0::i w vectors lw 1.5 lc rgb "red" notitle
}
set output
### end of code
Result:

Centering labels on a pie chart

I am following this post to make a pie chart using Gnuplot. The only problem with the approach is that I can't align my percentage labels. What am I missing here?
DATA FILE:
"Others" 1.085117e-01 3.904323e-02
"D_o" 2.894902e-01 6.145359e-01
"{/Symbol b}_o" 5.760601e-01 3.760299e-01
"O_h" 5.393108e-01 1.000000e+00
"D_p" 6.743313e-01 2.284404e-01
"{/Symbol a}_p" 1.000000e+00 1.271822e-01
"{/Symbol b}_f" 4.020115e-01 2.233656e-01
"D_m" 2.389996e-01 8.577689e-02
"{/Symbol a}_m" 3.601146e-01 1.033153e-01
"{/Symbol b}_m" 5.596836e-01 1.947165e-01
CODE:
#!/usr/bin/gnuplot
# Terminal & Encoding
set terminal epscairo enhanced color dashed rounded size 8.5, 4.5
set output 'mu_piechart.eps'
set termoption enhanced
set encoding utf8
# Get Status
filename = './datafile.dat'
stats filename u 2 noout
# Get Angles & Percentages
ANG(x)=x*360.0/STATS_sum
PER(x)=x*100.0/STATS_sum
# Square Canvas
set size square
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
# Remove Base Properties (Titles, Tics, Axis, Palette)
unset key
unset tics
unset border
unset colorbox
# Initial Angle, Mid Angle, Initial Color
A = 0.0; M = 0.0; i = 0;
# Palette
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
# Plot
plot for [i=0:STATS_records-1] filename u (0):(0):(1):(A):(A=A+ANG($2)):(i) every ::i::i with circle linecolor palette,\
filename u (M=A+ANG($2), A=2*M-A, M=M*pi/360.0, -0.5*cos(M)):(-0.5*sin(M)):(PER($2) > 8.00 ? sprintf('%.1f\%', PER($2)) : " ") every ::1 w labels center font ',10',\
for [i=0:STATS_records-1] filename u (1.45):(i*0.25)-1.11:($1) every ::i::i with labels left,\
for [i=0:STATS_records-1] '+' u (1.3):(i*0.25)-1.11:(i) pt 5 ps 4 lc palette
exit
OUTPUT:
The percentages positions are not correct in the figure generated by the script.
Your labels are at wrong positions, because your label plot starts at 1, i.e. you skip the first entry.
Also, what I don't understand is, why you plot the pie parts counterclockwise, and the labels clockwise.
Here is a working version of you script, without some parts which are superfluous for demonstration. Both labels and pie parts are plotted starting at an angle of A = 0 (note the second initialization between the two plots):
reset
# Get Status
filename = './datafile.dat'
stats filename u 2 noout
# Get Angles & Percentages
ANG(x)=x*360.0/STATS_sum
PER(x)=x*100.0/STATS_sum
# Y position of key point and label
YLBL(row) = 2.0 * (row - 0.5*(STATS_records - 1))/(STATS_records - 1)
# Square Canvas
set size square
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
# Remove Base Properties (Titles, Tics, Axis, Palette)
unset key
unset tics
unset border
unset colorbox
# Palette
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
# Plot
A = 0.0
plot filename u (0):(0):(1):(A):(A=A+ANG($2)):0 with circle linecolor palette,\
A = 0,\
filename u (M=A+ANG($2), A=2*M-A, M=M*pi/360.0, 0.5*cos(M)):(0.5*sin(M)):(PER($2) > 8.0 ? sprintf('%.1f\%', PER($2)) : "" ) w labels center,\
filename u (1.3):(YLBL($0)):1 with labels offset char 3 left ,\
filename u (1.3):(YLBL($0)):0 pt 5 ps 4 lc palette
The script contains some other improvements:
You don't need to iterate over STATS_records
The text and point for the key are plotted at the same position, the label is shifted with the offset parameter by three character units (offset char 3). That makes fine-tuning easier.

Resources