Define and use vector for graph ticks - gnuplot

I like to store everything I can in a variable since each gnuplot script I make generates tens of plots at once and it makes things easier to track. Here is a sample of one plot (variable of interest: ytics):
# Setup style
set terminal pngcairo dashed
unset key
set style line 1 pointtype 7 pointsize 0.3 linecolor rgb "black"
# Setup the plots' ytics
ytics_H2 = (0,0.002,0.004,0.006,0.008,0.010,0.012);
# Store the range for each variable
min_T = 200; max_T = 1800;
min_H2 = 0; max_H2 = 0.012;
# Plot
set output 'my_output_H2.png'
set ytics ytics_H2
set xrange [min_T :max_T ]
set yrange [min_H2:max_H2]
plot 'scatter.dat' using 1:2 with points linestyle 1
Here is the result:
As you can see, only the last tick gets printed. If I replace the variable ytics by the vector to which it is set to, everything works as expected.

For such use cases gnuplot has macros:
set macros # necessary only for v < 5.0
ytics = "(1, 5, 8)"
set ytics #ytics
plot x
In order to use macros, you must define a string variable which contains the command parts you want to use at a later point, here ytics = "(1, 5, 8)". Later you can use its content with #ytics.
The important fact here is, that gnuplot first replaces #ytics with the content of the string variable ytics, i.e. expands set ytics #ytics to set ytics (1, 5, 5) and only then executes the whole command.

Because your intervals are fixed and the same, you could also use start, incr, end form:
set ytic 0, 0.002, 0.012

Related

Gnuplot does not pop up the title(or legends)

I'm trying to get some eps files from the following lines. The problem is that legend (key) does not pop up when I follow the procedure for making output files. (In my case, \lambda=2 is not shown in ps files.)
Any idea or help will be appreciated.
filename0 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_plot/data_plot_result/Fp_index0_%d_%d,000000_%d,000000_%d_sOkP.tex',9, 5 ,2, 10)
set terminal epslatex size 8, 6 standalone color colortext 10
set output filename0
set xlabel '${\large E}$'
set ylabel '$p$' offset 2
set ylabel rotate by 0
set format '$%g$'
set key at 37, 0.9
filename1 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_refine/p_index0_%d_%f_%f_%d_sOkP',9, 5, 2, 10)
filename2 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_refine/p_index1_%d_%f_%f_%d_sOkP',9, 5, 2, 10)
color1 = '#FF0000'
color2 = '#FF9933'
plot filename1 u 1:2:3 with yerrorbars pt 6 ps 2 lc rgb color1 title '$\lambda = 2$',\
filename2 u 1:2:3 with yerrorbars pt 6 ps 2 lc rgb color2 notitle
I think the problem is that you manually place the key at (37, 0.9), but do not specify the x- and yrange – these are automatically adjusted. Without your data I can't verify, but supposedly your data lies within [-20:20] in x, then your key is placed far outside the graph and therefore not visible.
As a first step you could try deleting the line set key..., see whether the auto placement suits you, and only then fine tune it. Or alternatively, explicitly use set xrange ... and set yrange ...
By the way, you can directly define variables as strings, you don't necessarily need to call sprintf (although you might have reasons to do so):
filename0 = 'home/hyogeon/ETH/ETH_with_Pf.T/result/data_plot/data_plot_result/Fp_index0_9_5,000000_2,000000_10_sOkP.tex'

How to make dashed grid lines intersect making crosshairs in gnuplot?

I'm plotting some data and I want to use dashed grid lines.
Any dashed grid line would suffice, but I prefer a "long dash, short dash, long dash" format.
For example, given the following code
set grid lc rgb "#000000" lt 1 dt (50, 25, 20, 25)
plot x**2
I get this result
But I would rather the grid lines intersection to happen always at the middle of two dashes, like this
If I could make horizontal grid lines different to vertical grid lines and I could add some offset to each one, then I'd imagine there's a way to accomplish this. But I can't seem to do that either.
It looks like gnuplot cannot have two different dashstyles for x-grid and y-grid.
One workaround I see currently is to plot two identical plot on top of each other. One with appropriate x-grid lines and the other with appropriate y-grid lines.
If you want a dash pattern with proportions of (50-25-20-25), this correspond to (25-25-20-25-25-0) or (5-5-4-5-5-0) between two tics.
Furthermore, the dash and gap length numbers, e.g. in dt (50,25,20,25), seem to be in a fixed relation to the graph size. The "empirical" factor is 11 with good approximation (at least for the wxt terminal which I tested under gnuplot 5.2.6).
Edit: actually, the code below gives different results with a qt terminal. And it's not just a different factor. It's more complicated and probably difficult to solve without insight into the source code. So, the fact that the following seems to work with wxt terminal (maybe even just under Windows?) was probably a lucky strike.
With this you can create your dash lines automatically resulting in crosshairs at the intersections of the major grid lines.
Assumptions are:
your first and last tics are on the borders
you know the number of x- and y-intervals
You also need to know the graph size. These values are stored in the variables GPVAL_TERM..., but only after plotting. That's why you have to replot to get the correct values.
This workaround at least should give always crosshairs at the intersection of the major grid lines.
Edit 2: just for "completeness". The factors to get the same (or similar) looking custom dashed pattern on different terminals varies considerably. wxt approx. 11, qt approx. 5.6, pngcairoapprox. 0.25. This is not what I would expect. Furthermore, it looks like the factors slightly depend on x and y as well as graph size. In order to get "exact" crosshairs you might have to tweak these numbers a little further.
Code:
### dashed grid lines with crosshairs at intersections
reset session
TERM = "wxt" # choose terminal
if (TERM eq "wxt") {
set term wxt size 800,600
FactorX = 11. # wxt
FactorY = 11. # wxt
}
if (TERM eq "qt") {
set term qt size 800,600
FactorX = 5.58 # qt
FactorY = 5.575 # qt
}
if (TERM eq "pngcairo") {
set term pngcairo size 800,600
set output "tbDashTest.png"
FactorX = 0.249 # pngcairo
FactorY = 0.251 # pngcairo
}
set multiplot
set ticscale 0,0
Units = 24 # pattern (5,5,4,5,5,0) are 24 units
# set interval and repetition parameters
IntervalsY = 10
RepetitionsY = 1
IntervalsX = 4
RepetitionsX = 3
# initial plot to get graph size
plot x**2
gX = real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/IntervalsY/Units/FactorY/RepetitionsY
gY = real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/IntervalsX/Units/FactorX/RepetitionsX
# first plot with x-grid lines
set grid xtics lt 1 lc rgb "black" dt (gX*5,gX*5,gX*4,gX*5,gX*5,0)
replot
unset grid
# second plot with y-grid lines
set grid ytics lt 1 lc rgb "black" dt (gY*5,gY*5,gY*4,gY*5,gY*5,0)
replot
unset multiplot
set output
### end of code
Result:
Not really. The closest I can think of is
set grid x y mx my
set grid lt -1 lc "black" lw 1 , lt -1 lc bgnd lw 16
set ticscale 1.0, 0.01
set mxtics 4
plot x**2 lw 2
But that leaves the vertical grid lines solid.

Gnuplot with SI-prefixes: How do I get gnuplot not to display decimal zeros?

I'm plotting wavelength with a custom format for xtics in Gnuplot. What I want to achive are xtics like this:
200nm, 400nm, 600nm, 800nm, 1um, 1.2 um, 1.4um
I'm almost there with this code:
set xlabel "Wavelenth"
set format x "%3.1s%cm"
set xrange [1e-8:1.5e-6]
plot x lw 3
However, because of the %3.1s, Gnuplot appends a useless .0, where none is necessary. So Gnuplot's xtics in aboves range are:
200.0nm, 400.0nm, 600.0nm, 800.0nm, 1um, 1.2 um, 1.4um
That widens the tics, which is ugly. I can't figure out how to specify width and precision so that decimal places that are all zero are not displayed. Is there a way?
I think this is not possible other than specifying the tics manually:
set xtics ("200nm" 2e-7, "400nm" 4e-7, "600nm" 6e-7, "800nm" 8e-7, "1.2um" 1.2e-6, "1.4um" 1.4e-6)
If you use the postscript terminal, you me be able cut away the ".0nm" with sed
set term postscript eps
set out 'plot.eps'
set xlabel "Wavelenth"
set format x "%3.1s%cm"
set xrange [1e-8:1.5e-6]
plot x lw 3
set output
!sed -i 's/\.0nm/nm/g' plot.eps

increment of ytics in gnuplot

I plotted a graph and I'd like to show ytics as a function of x. For example:
I plot x^2 and I'd like to show ytics for 0,1,4,9... . Is there any way to do this automatically or I have to set manually every tic in y-axis? I tried to set a function when defining ytics but gnuplot doesn't accept it.
Thanks for any help
You can use a for loop. Of course, here you need to know your x-range in advance:
f(x)=x**2
set ytics ( sprintf('%f',f(-10)) f(-10) )
set for [i=-9:10] ytics add ( sprintf('%f',f(i)) f(i) )
plot f(x)
Here is my semiautomatic answer, using a for loop to build the ytics string:
#!/usr/bin/env gnuplot
set terminal pngcairo
set output 'test.png'
# x range
xmin = 0
xmax = 10
set xrange [xmin:xmax]
# define function of x to make plot, define tics
yfn(x) = x**2
# integer counting over tic positions
imin = int(xmin)
imax = int(xmax)
# build tics string
tix = '("'.sprintf('%d', yfn(imin)).'" '.sprintf('%d', yfn(imin))
do for [i=(imin+1):imax] {
tix = tix.', "'.sprintf('%d', yfn(i)).'" '.sprintf('%d', yfn(i))
}
tix = tix.')'
set macros
# set ytics using macro expansion
set ytics #tix
plot yfn(x)
This is the result:
i do not answer quite exactly to your question,
Although, that makes me think of customising the label of ytis.
Example :
f(x)=x**2
f1(x)=sqrt(abs(x))
set ytics format ""
set ytics scale 1
set t qt 0 enhanced font "Sans,9"
#set mytics 8
# ploting once the function for getting the GPVAL_ variable
plot f(x) t "f(x)=x**2"
# calculating function for the list of increment
linRg(start,end,increment)=system(sprintf("seq %g %g %g", start, increment, end))
# forcing the tics, otherwise, the tics of the first plot will still be marked
set ytics GPVAL_Y_MIN, (GPVAL_Y_MAX-GPVAL_Y_MIN)/8, GPVAL_Y_MAX
do for [i in linRg(GPVAL_Y_MIN, GPVAL_Y_MAX, (GPVAL_Y_MAX-GPVAL_Y_MIN)/8)] { pr i; set ytics add ('f(|'.gprintf("%.1s%c",f1(i)).'|)'.gprintf("=%.1s%c",i) i)}
replot
will produced :

Gnuplot: how to add y2 axis scale for different units

I'm plotting data from a file. The data points are in metric units. I want to show a second scale on the right (y2) that's in standard units.
The file represents rocket motor thrust over time. The data are in Newtons. I want to show newtons on the left (this happens by itself, naturally) and pounds force on the right. The conversion is a simple factor (multiply N by 0.2248 to obtain lbf).
I can set y2tics and if I set y2range manually, they appear on the right. What I don't know how to do is set y2range automatically to y1range * a factor.
My eventual solution is to plot twice, once in Newtons on y1 and once in pounds on y2, and make the y2 plot almost invisible:
plot '-' using 1:($2*0.2248) with dots axes x1y2 lc rgb 'white' notitle, \
'' using 1:2 with lines lc rgb '<color>' title '<title>'
The solution above often generates slightly different y scales: with autoragne, gnuplot rounds up the range so the top tick on each axis is a round number, and of course the rounding is different for different units.
Ultimately I end up with Python code that finds the highest thrust value in each graph, then I explicitly set yrange to that number and y2range to that number * 0.2248:
f.write("set yrange [0:%s]; set y2range[0:%s]\n" % (peak_thrust, peak_thrust*NEWTON_LBF));
Here's the end result: http://www.lib.aero/hosted/motors/cesaroni_12-15-12.html (sample graph below)
It seems to me that the easiest way to do this is to simply scale the data:
set y2tics
plot sin(x) w lines, 5*sin(x) w lines axes x1y2
Of course, you're plotting data from a file, so it would look something more like:
set y2tics
FACTOR=0.2248 #conversion factor from newtons to lbf
plot 'datafile' u 1:2 w lines, '' u 1:(FACTOR*$2) w lines
If you're setting the yrange explicitly (which you may need to do):
set yrange [ymin:ymax]
set y2range [ymin*FACTOR:ymax*FACTOR]
Finally, if you really want to rely on autoscaling, you're going to need to do some "gymnastics".
First, set a dummy terminal so we can plot without making a plot:
set term unknown
plot 'datafile' u 1:2 #collect information on our data
Now that we've collected information on the data, we can set our real y2range
FACTOR=0.2248
set y2range [FACTOR*GPVAL_Y_MIN : FACTOR*GPVAL_Y_MAX]
set y2tics nomirror
set ytics nomirror
Now set the terminal and plot the data:
set term ...
set output ...
plot 'datafile' u 1:2 w lines
Version 5.0 added support for this kind of relations between the y and y2 (or also x and x2) axis:
set xrange[0:370]
set ytics nomirror
set y2tics
set link y2 via 0.2248*y inverse y/0.2248
plot x
I know it's an old question and the answer has already been accepted, but I think it's worth sharing my approach.
I simply use modified labels for the x2axis. In your case, this would be
set y2tics ("10" 10/0.2248, "20" 20/0.2248 etc etc...
that can be looped this way
do for [i=0:1000:10] { set y2tics add (sprintf("%i",i) i/0.2248) }
where the for range should be adjusted according to your data (you could use stats and the variable GPVAL_DATA_Y_MAX for complete peace of mind).
Don't forget to
set ytics nomirror
This will give exactly what are you looking for, in (almost) a one liner:
If you want to use a grid and have the converted factors on the x2axis, so that for example to the label y=50 N would correspond y2=11.2 (it keeps things tidy if you use a grid) you can do
do for [i=0:1000:50] { set y2tics add (sprintf("%5.1f",i*0.2248) }
This is the result:

Resources