How to combine and scatter plot with a parametric plot in gnuplot - gnuplot

I am trying to plot some data with en ellipse on top in gnuplot. I want to plot the ellipse parametrically, and not using set object ellipse.
The following code will plot the data:
plot "my_file.dat" u 1:2
The following code will plot the ellipse:
x0 = 1
y0 = 2
a = 3
b = 2
f(t) = x0 + a*cos(t)
g(t) = y0 + b*sin(t)
set parametric
plot [0:2*pi] f(t),g(t)
How do I combine these plots in a single plot?
I am running gnuplot 5.2.

Any plot command in parametric mode can be reformulated to produce the same plot in non-parametric mode using the pseudofiles '+' for one parametric variable or '++' for two parametric variables.
So your
set parametric
plot [0:2*pi] f(t),g(t)
is exactly equivalent to
unset parametric
plot sample [t=0:2*pi] '+' using (f(t)) : (g(t))
In this form it is trivial to mix it with other data plots.

Well, check the gnuplot manual or on the gnuplot console help plot.
Syntax:
plot {<ranges>} <plot-element> {, <plot-element>, <plot-element>}
Simply add a plot element separated by comma. For better readability you may want to put it into a new line using \ as last character of the previous line.
plot [0:2*pi] f(t),g(t), \
"my_file.dat" u 1:2

Related

gnuplot badly renders heat map on uneven grid

I am trying to plot a heat map of 3D results, a f(x,y) function, obtained on an uneven grid.
The plot I obtain gives me some ugly empty spaces at the top of the graph.
Below are minimal scripts to reproduce the issue I am facing.
#Generate some dummy data
f(x,y) = sqrt(x**2 + y**2)
set table
set samples 1000
set output "table.dat"
splot [0:10][0:10] f(x,y)
The plotting script :
# plot it
set term x11
set out
set pm3d map
splot [1:5] [0:2] "table.dat" u ($1):($2/$1):($3)
Since the y-axis value depends on the x-axis, the grid is now even. As can be seen in the following figure gnuplot fails to fill-up some space close to the top border of the plot. Changing the axis limits doesn't help.
sample impage plot
Any idea how to fill-up the white triangles and make this plot look nicer ?
Thanks for your help.
You can use dgrid3d for 2-d interpolation. With your using specification ($1):($2/$1):($3) the domain where you have data points is very irregular. It helps to tell dgrid3d that you are interested only in a small rectangle by setting all other values to NaN. For example:
set pm3d map
set dgrid3d 100,100 qnorm 4
splot [1:5] [0:2] "table.dat" u ($1 >= 1 && $1 <= 5 ? $1 : 1/0):($2/$1 > 0 && $2/$1 < 2 ? $2/$1 : 1/0):3
You will have to experiment with the various options of dgrid3d to get a reasonable interpolation.

Fitting graph and draw lines by selecting ranges in horizontal axis

I am trying to plot a graph and fitting it using a linear line.
f1(x)=a1+b1*x
fit [0:80] f1(x) 'diff-xy-bcmLyo25perS.dat' via a1,b1
f2(x)=a2+b2*x
fit [100:220] f2(x) 'diff-xy-bcmLyo25perS.dat' via a2,b2
And I tried to plot both the plots into the same graph using command:
f(x) = x < 60 ? f1(x) : f2(x)
plot 'diff-xy-bcmLyo25perS.dat' using 1:2 with lines linestyle 1 title "{/Symbol b}BCMal-C_{12}C_{8}", f(x) lw 3.0 lc rgb 'black'
I get a plot as above.
In that plot one could see that there are two lines intersecting at 80 (horizontal scale) and it makes shape like 'v'.
I wish to eliminate that 'v' shape intersection and I would like to get two separate lines, one from 0 to 80 and the other one from 100 to 220.
How I could get this?
Appreciate any help.
Thanks in advance.
You could exploit that gnuplot doesn't plot infinity and NaN values (as 1.0/0)
Using
plot_if_in_range(y,x,lower,upper) = (x>=lower && x<=upper)?(y):(1.0/0)
You could easily plot any function in given domain:
plot plot_if_in_range(exp(x) , x, -5, 2), \
plot_if_in_range(sin(x)+x, x, -2, 5)
With gnuplot 5.0 you can specify different range for different functions:
set style data lines
plot 'diff-xy-bcmLyo25perS.dat' using 1:2 ls 1, \
[0:80] f1(x) lw 3.0 lc rgb 'black',\
[100:220] f2(x) lw 3.0 lc rgb 'black'
Note, that this works only, because you first plot the data file. Plotting only
plot [0:80] f1(x), [100:220] f2(x)
wouldn't work, since the first range settings are equivalent to a global set xrange [0:80] (it has always been), so that the second function wouldn't be visible at all.
However, in your case it should work fine.
Edit:
Sorry, this is basically the same idea as Sergei Izmailov's answer which I missed.
Answer:
Use the special file "+", which provides x values for your plot that you can then sample using a function of your choice, including one that ignores input if it's outside of range. Then you can use your f1(x) and f2(x) directly:
plot "+" using ($1):(0 < $1 && $1 < 80 ? f1($1) : 1/0), \
"+" using ($1):(100 < $1 && $1 < 220 ? f2($1) : 1/0)

Gnuplot: Use fit in log scale

I need to make a linear approximation. However it needs to be in a log scale.
Here is my gnuplot script:
f(x)= a*x+b
fit f(x) "d0.dat" via a,b
set logscale x
set logscale y
plot "d0.dat" with points lt rgb "#ff0000" title "Points", \
f(x) with lines lt rgb "#ff00ff" title "Approximation"
Clearly the approximation is wrong. Can anyone help me to fix it. I didn't find any thing in google.
Gnuplot is correctly fitting your data to the function you provided--a straight line.
The problem is that using a log scale for the y axis does not scale the data--just how the data are plotted.
Try fitting it to a power law:
f(x)= a*x**b
fit f(x) "d0.dat" via a,b
set logscale x
set logscale y
plot "d0.dat" with points lt rgb "#ff0000" title "Points", \
f(x) with lines lt rgb "#ff00ff" title "Approximation"
I actually recommend a fit in logscale directly:
fl(x) = a+b*x
fit fl(x) 'data.dat' u (log($1)):(log($2)) via a,b
replot exp(fl(log(x))) t 'log approx'
The difference is appreciable when (a few) values for large x are out of the fit. The cost-function is otherwise too strongly affected (because x and y are exponentially large).

Conditional execution of the plot command

I'm using gnuplot to create graphs of a rather simply structured file. In particular, the file contains 8 columns, the first 4 columns describe "measured" values, the second 4 "predicted" values. I want to create two plots, one comprising only measured values, one comprising both.
Since my gnuplot script is rather long, I would like to introduce a variable to set the flag whether predicted values should be contained or not. I want to use different line types, axis and labels, and hence, cannot use the "using" approach.
Here is what I use so far:
plot 'file.txt' using 2:xticlabels(1) title "Val1 (Measured)" with
lines axes x1y1, '' using 3:xticlabels(1) title "Val2 (Measured)"
with linespoints axes x1y2;
if (settingCompareToAggretagion == 1)
plot 'file.txt' using 4:xticlabels(1) title "Val1 (Aggregated)" with lines
axes x1y1, '' using 5:xticlabels(1) title "Val2" with linespoints axes x1y2;
There is obviously the problem that I get two plots but one. I also tried to "attach" the second set of plots to the command with an inline if condition (bool.exrp. ? x : y) but this is not working.
Thank you!
That can be done with the replot command:
plot x, x**2
replot x+5, x**2 + 5
That plots a single graph with four plots.
In your case the following should work:
plot 'file.txt' u 2:xtic(1) t "Val1 (Measured)" w l,\
'' u 3 t "Val2 (Measured)" w lp axes x1y2
if (settingCompareToAggregation == 1) {
replot 'file.txt' u 4 t "Val1 (Aggregated)" w l,\
'' u 5 t "Val2 (Aggregated)" w lp axes x1y2
}

How can I fix zero to be at the same place when using separate y axes in gnuplot?

I have a data file, with column 1 as the independent variable and columns 2 and 3 as dependent variables. I want to plot variables 2 and 3 on different y axes using something like this:
plot "file.out" u 1:2 axes x1y1, "file.out" u 1:3 axes x1y2
When I do this, the "0" for both axes are offset from one another. How can I fix the zero of one y-axis to the zero of the other y-axis, without explicitly setting yrange to be symmetric for both quantities?
It is possible form version 5 to use set link. However it does not autofit the ratios, so you're left with calculating them yourself
stat "file.out" u 1:2
MAX1=abs(STATS_max_y)
MIN1=-abs(STATS_min_y)
stat "file.out" u 1:3
MAX2=abs(STATS_max_y)
MIN2=-abs(STATS_min_y)
min(a,b)=(a<b)?a:b
set link y2 via min(MAX1/MAX2,MIN1/MIN2)*y inverse y/min(MAX1/MAX2,MIN1/MIN2)
plot "file.out" u 1:2 axes x1y1, "file.out" u 1:3 axes x1y2
Here is a solution which works without linking axes, hence it also works even with gnuplot 4.4 (the version from 2010).
Although, it doesn't need stats but as a disadvantage it requires to replot the data to get the proper scaling of the y2-axis.
Code:
### aligning zero on y1- and y2-axes
reset
set ytics nomirror
set y2tics nomirror
set xzeroaxis
set key top left
plot \
sin(x) axes x1y1 w l, \
cos(x)-0.5 axes x1y2 w l
R0 = -GPVAL_Y_MIN/(GPVAL_Y_MAX-GPVAL_Y_MIN)
y2_min_new = abs(GPVAL_Y2_MIN)>abs(GPVAL_Y2_MAX) ? GPVAL_Y2_MIN : R0*GPVAL_Y2_MAX/(R0-1)
y2_max_new = abs(GPVAL_Y2_MAX)>abs(GPVAL_Y2_MIN) ? GPVAL_Y2_MAX : (R0-1)*GPVAL_Y2_MIN/R0
set y2range[y2_min_new:y2_max_new]
replot
### end of code
Result:
Unfortunately, you can't (at least not in general). If the yrange has the same percent above and below 0, it should probably work, e.g.:
set yrange [-5:10]
set y2range [-10:20]
But if you don't want to do that, then I don't know that there's a better solution...

Resources