Non-linear secondary xlabel - gnuplot

I want to plot a function/dataset, where the secondary x-axis is a function of the primary x-axis, e.g. 1/x (non-linear). The reason for this is that they are both meaningful parameters. I can set the range correctly by using my "function", however, values in between are different. The following figure shows what is wrong:
What is wrong here, is that the x2-axis get linearly ticced (is that proper English?). Example: the tic opposite to 1.6 is now 0.7, but should be 0.625 for this case.
Script to reproduce this:
xmin=1.
xmax=2.
set xlabel "x"
set xrange [xmin:xmax]
set x2tics
set x2label "1/x"
set x2range [1/xmin:1/xmax]
plot x
Is a fancy general way to change the axis-scaling/labeling, other than logarithmic?

You can use a do for approach to loop through a manual label setting (set x2tics add). Here's the edited minimal example you provided (see comments in the script for explanations):
xmin=1.
xmax=2.
inc=0.2 # for more control over the tics
f(x)=1./x # Function that defines the secondary axis
fplot(x)=x # Function that is plot
set xlabel "x"
set xrange [xmin:xmax]
set xtics xmin,inc,xmax # specify the actual location for xtics, too
ntics = (xmax-xmin)/inc + 1 # calculate the number of tics
inc2 = (f(xmin)-f(xmax))/(ntics-1) # calculate increment for x2tics
fmin=f(xmin); fmax=f(xmax)
set x2tics fmin,-1*inc2,fmax # set x2tics, labels will be rewritten
# the following loops through the number of tics
# the <set x2tics add ("x2" x2)> command will be repeated
# use arithmetic to calculate the values and the locations
# you need <sprintf> to convert the tic label number into a string
do for [i=1:ntics+1] {
xtic=xmin+(i-1)*inc
x2ticpos=f(xmin)-(i-1)*inc2
set x2tics add (sprintf("%.3g",f(xtic)) x2ticpos)
}
set x2range [f(xmin):f(xmax)]
set yrange[fplot(xmin):fplot(xmax)] # you should also specify the yrange, to avoid surprises
plot fplot(x)
And the plot you'll get is this:

Related

Gnuplot use two different scales in the same axis

I am trying to create a graphic using gnuplot 5.0 with two scales in the same x axis. I have managed to create one using the multiplot option with the following code:
reset
set terminal pngcairo
set output "test.png"
unset key
set ylabel "Temperature (C)"
set ytics nomirror
set yrange[0:7]
set multiplot layout 1,2
set xrange [0:5.99] #Avoid plotting the last xtics in the first graphic
set xlabel "Heating time (minutes)"
set rmargin at screen 0.7
plot x
set xrange [0:4]
set xlabel "Seconds after stop"
set rmargin
set lmargin at screen 0.7
set xtics 1
unset ylabel
unset ytics
set y2tics nomirror
set format y2 ''
f(x) = a * exp (-x*b)
a=6
b=1
plot f(x)
With this result:
I want to generate several images like this one and add them in a multiplot arrangement, but I am not sure if using nested multiplots will be easy. Is there an easier way to obtain each of the images without using multiplot, like splitting the xaxis in two components?
Thanks in advance.
Just in case this still might be of interest to the OP or somebody else... You don't explicitly write whether you want to plot functions or data from a datafile. In your examples you use functions.
You can do something without "nested" multiplots, which would certainly be possible as well, but probably getting a bit confusing.
So, maybe the following might be easier. You basically set the xtics "manually". In order to avoid typing the same code several times you can use macros (check help macros).
Code:
### multiplot graph with different x-axis scales
reset session
# define functions
Temperature(x) = x<t0 ? x*a/t0 : a*exp(-(x-t0)*b)
myColor(col) = column(col)<t0 ? 0xff0000 : 0x0000ff
myTic(x,t) = sprintf("%g", x<=t ? x : x-t)
# define macro
myPlot = "\
set xrange[0:t0+t1]; \
set arrow 1 from first t0, graph 0 to first t0, graph 1 nohead; \
set label 1 'heating' center at first t0/2., graph 0 offset 0,-2; \
set label 2 'cooling' center at first (t0+t1/2.), graph 0 offset 0,-2; \
set xtics (); \
do for [i=0:int(t0/dt1)] { set xtics add (myTic(i*dt1,t0) i*dt1) }; \
do for [i=0:int(t1/dt2)] { set xtics add (myTic(i*dt2,t1) i*dt2+t0) }; \
plot '+' u 1:(Temperature($1)):(myColor(1)) w l lc rgb var "
set samples 200
set key noautotitle
set bmargin 3
set ylabel "Temperature"
set grid x,y
set multiplot layout 2,2
t0=6; t1=4; dt1=1; dt2=1; a=6; b=1
#myPlot
t0=4; t1=10; dt1=1; dt2=2; a=4; b=0.5
#myPlot
t0=20; t1=30; dt1=5; dt2=10; a=2; b=0.1
#myPlot
t0=4; t1=4; dt1=1; dt2=1; a=10; b=1
#myPlot
unset multiplot
### end of code
Result:

Changing ytic font size in gnuplot epslatex (multiplot)

I have problems changing the font size of my ytics (xtics as well) in an epslatex gnuplot.
I tried set format y '\tiny{%g}'
It is only working for the first of the two plots.
This is my code:
set terminal epslatex
set output "w_alt_nsyB_multi.tex"
set multiplot layout 1,1
set xrange [-0.5:17]
set yrange [0:110]
set xlabel "days"
set ylabel "Survival (\\%)" offset 2.5
set key reverse
set xtics font 'Arial,4' s
et style histogram errorbars gap 2 lw 1
set style data histogram
set style fill solid 1 border lt -1
set boxwidth 0.8
plot 'w_alt_nsyB.dat' every ::::7 using 2:3:xticlabels(1) title 'w1118' lt rgb "#000000",\
'w_alt_nsyB.dat' every ::::7 using 4:5 title 'wtSYN' lt rgb "#FF0000",\
'w_alt_elav_endoG.dat' every ::::7 using 6:7 title '38085' lt rgb "#9400D3"
set origin 0.5, 0.25
set size 0.5, 0.5
set xrange [-0.5:6]
set yrange [0:110]
set xlabel "\\tiny{Time of $Mn^{2+}$ treatment}"
set ytics ('10'10,'50'50,'100'100) nomirror
unset border
set xtics nomirror
unset ylabel
unset key
plot 'w_alt_nsyB_100.dat' using 2:3:xticlabels(1) lt rgb "#000000",\
'w_alt_nsyB_100.dat' using 4:5:xticlabels(1) lt rgb "#FF0000",\
'w_alt_nsyB_100.dat' using 6:7:xticlabels(1) lt rgb "#9400D3"
unset multiplot
Can anyone help me please?
The format given in set format ... isn't applied if you give an explicit manual label like you do with
set ytics ('10'10,'50'50,'100'100)
You must either just give the locations of the labels
set format y '\tiny %g'
set ytics (10, 50, 100)
or include the font macro in every manual label
set ytics ('\tiny 10' 10, '\tiny 50' 50, '\tiny 100' 100)
Note also, that your syntax \tiny{%g} is wrong, \tiny is only a switch and doesn't take any arguments. In this case it doesn't matter, because every label is wrapped in an individual LaTeX box, but in other situations it makes a big difference. To wrap the tiny font you would usually need {\tiny %g}.
The same happens for the explicit labels which are set with xticlabel. Also here, the format from set format x doesn't apply. Instead of giving a column number to xticlabel (like xticlabel(1) in your example), you must give the complete label string including the macro:
xl(c) = sprintf('\tiny %s', strcol(c))
plot 'file.dat' using 2:3:xticlabel(xl(1))
Next time, please give a minimal example which allows others to reproduce your problem. We don't have your data files to run the script. And your problem isn't related to you specific data file, so you can as well construct an example using functions, which possibly leads you itself to the solution...

Remove thing from gnuplot's legend

I have to plot three implicit functions using gnuplot, I use this:
set contour
set cntrparam levels discrete 0
set view map
unset surface
set isosamples 1000,1000
set xrange [-5:7]
set yrange [-15:15]
set xlabel "x"
set ylabel "y"
splot y**2-x**3+15*x-13 t "t1", y**2-x**3+15*x-sqrt(4.*15.**3/27.) t "singular", y**2-x**3+15*x-30 t "t2", y**2-x**3+15*x-13 t "t3"
And the output is this:
The program is writing the 0 of the level of the surface in the legend but I just want the title parameter passed to the splot command. As the three surfaces are actually the same at a different height, I could change set cntrparam... line to draw the three of them, but what I want to do is to remove the numbers and make it write just text. How can I do that?
You cannot directly manipulate the contour level labels with any text. Just write out the contoured data to a temporary file using set table... and then plot this data file as usual. Here, you can now distinguish between different contour levels using index:
set contour
set cntrparam levels discrete 0
set view map
unset surface
set isosamples 1000,1000
set xrange \[-5:7\]
set yrange \[-15:15\]
set xlabel "x"
set ylabel "y"
set table 'contour.dat'
splot y**2-x**3+15*x-13 t "t1", y**2-x**3+15*x-sqrt(4.*15.**3/27.) t "singular", y**2-x**3+15*x-30 t "t2", y**2-x**3+15*x-13 t "t3"
unset table
set style data lines
plot 'contour.dat' index 0 title 't1', '' index 1 title 'singular', '' index 2 title 't2', '' index 3 title 't3'

undefined variable: GPVAL_DATA_Y_MIN (Gnuplot)

Based on this post (I am using gnuplot gnuplot 4.6 patchlevel 1):
gnuplot: max and min values in a range
I am trying to use set yr [GPVAL_DATA_Y_MIN:GPVAL_DATA_Y_MAX] in my .pg script that plots data from this .dat file:
100 2
200 4
300 9
But I get:
undefined variable: GPVAL_DATA_Y_MIN
This is my script:
set terminal png
set output 'img.png'
set xlabel 'x-label'
set ylabel 'y-label'
set boxwidth 0.5
set style fill solid
set yrange [GPVAL_DATA_Y_MIN:GPVAL_DATA_Y_MAX]
plot 'sample.dat' with boxes title ""
Any ideas?
The gnuplot-defined variables are available only after a plot command (In the question you linked to, a replot is used to plot again).
Basically you have different options:
First plot to terminal unknown, and then change to the real terminal, set the range (now the variables are available), and replot:
set xlabel 'x-label'
set ylabel 'y-label'
set boxwidth 0.5 relative
set style fill solid
set terminal unknown
plot 'sample.dat' with boxes title ""
set terminal pngcairo
set output 'img.png'
set yrange [GPVAL_DATA_Y_MIN:GPVAL_DATA_Y_MAX]
replot
Note, that I used the pngcairo terminal, which gives much better results, than the png terminal. And I used set boxwidth 0.5 relative.
Use set autoscale to fix the ranges instead of setting an explicit yrange. You can use set offset to specify a margin based on the autoscaled values:
set autoscale yfix
# set offset 0,0,0.5,0.5
plot 'sample.dat' with boxes title ''
Use the stats command to extract the minimum and maximum values:
stats 'sample.dat' using 1:2
set yrange[STATS_min_y:STATS_max_y]
plot 'sample.dat' with boxes title ''

Adjusting the position of countour base plane in gnuplot

I am trying to use gnuplot to plot the graphene band structure as both surfaces and a countour plot at the base, set with set contour base, but I can't get rid of some axis lines and the plane where the contour is drawn is too far away from the surfaces when I place them in the adequate viewing angle.
Here is the code to plot the graph
# Setting ranges and function parameters
set xrange [-.55:.55]
set yrange [-1:1]
t=-3.033 s=0.129 a=1.43 * sqrt(3)
# Auxiliary functions
kx(x,y) = (2*pi/a) * (cos(pi/6)*x + sin(pi/6)*y) ky(x,y) = (2*pi/a) * (cos(pi/6)*x - sin(pi/6)*y)
w(x,y) = sqrt(1+4*cos(0.5*sqrt(3)*kx(x,y)*a)*cos(0.5*a*ky(x,y)) + 4*(cos(0.5*ky(x,y)*a))**2)
#functions to be plotted
e(x,y) = (t*w(x,y))/(1+s*w(x,y))
e_estrela(x,y) = (-t*w(x,y))/(1-s*w(x,y))
# Setting up 3D plot appearance
set hidden3d
set contour base set cntrparam levels discrete 0,0.5,1,2,4,8
set view 75, 31, 0.601098, 1.4385
set isosamples 60
# Removing unwanted stuff
unset xtics
unset ytics
unset ztics
unset key
splot e_estrela(x,y), e(x,y)
And the output I get (with the pngcairo terminal, but that's not relevant, I guess) is:
Is it possible to draw the contour base plane closer to the surfaces? And how about removing those vertical black lines?
For the first part, I tried playing wioth set zrange with no success. The base plane seems to be drawn a certain z-distance below the lowest z-range limit everytime.
Ideas? Thanks in advance!
To adjust the distance between your data and the xy-plane use the option
set xyplane relative <value>
where <value> gives you the distance between the xy-plane and the minimal z-value in relative fraction of the hight of your plot. So <value>=0 sets the distance to zero, <value>=0.5 to half the hight.
To control the border use set border where each border line is represented by bits. Please refers to the documentation for more details. In your case I would suggest:
set border 127+256+512 # or set border 1023-128
set grid #forces borders from xy-plane to plot

Resources