I am looking for a way to position tic marks in gnuplot between the axis, but so far I only found solution to put them in or out:
set tics in
puts all tic marks inside of the canvas
set tics out
puts all tic marks outide of the canvas
All I want is to place tic marks on both sides of the axis, somethink like
--l--l--
Thanks for a hint!
As said in the comments, it seems not possible to place the tics on both sides of the axis. A workaround would be to plot the axis twice, or to draw the tics by hand with the set arrow.
Drawing tics by hand:
Consider the following settings:
Xmin = -4.0 # range in x
Xmax = 4.0
Ymin = -1.2 # range in y
Ymax = 1.2
NXtics = 8 # number of Xtics
NYtics = 4 # number of Ytics
epsX = 0.05 # length of Xtics
epsY = 0.03 # length of Ytics
dX = (Xmax-Xmin)/NXtics # distance between Xtics
dY = (Ymax-Ymin)/NYtics # distance between Ytics
Next, we draw the bottom, top, left, and right tics:
# xtics and x2tics
do for [i=0:NXtics] {
posX = Xmin+i*dX
set arrow from posX,Ymin-epsY to posX,Ymin+epsY nohead front # bottom
set arrow from posX,Ymax-epsY to posX,Ymax+epsY nohead front # top
}
# ytics and y2tics
do for [i=0:NYtics] {
posY = Ymin+i*dY
set arrow from Xmin-epsX,posY to Xmin+epsX,posY nohead front # left
set arrow from Xmax-epsX,posY to Xmax+epsX,posY nohead front # right
}
Since you are drawing the tics by hand, you will need to configure the axis numbers and ranges:
set xtics Xmin,dX,Xmax scale 0 offset 0,-epsY
set ytics Ymin,dY,Ymax scale 0 offset -epsX,0
set xrange [XMIN:XMAX]
set yrange [YMIN:YMAX]
Finally, your highly complicated plot:
plot sin(x)
Result:
This method also allows you to break the axis
Drawing axis twice:
This method is easier; but you need to set set margins of the canvas, and to use the multiplot mode:
set tmargin at screen 0.9 # top margin
set bmargin at screen 0.2 # bottom
set lmargin at screen 0.2 # left
set rmargin at screen 0.9 # right
set yrange [-1.2:1.2]
set multiplot
set tics scale 0.5 # scale size of the tics
plot 2 notitle # a plot outside the canvas, just to draw the axis
set tics out # tics outside
set format xy '' # delete the numbers
unset border # delete the border
plot sin(x) # your awesome plot
unset multiplot
The result is similar :)
Quick & dirty approach:
set multi
set tics scale 0.5
plot sin(x)/x
set tics out
replot
unset multi
Beware this overprints your graph with a second one. Should be OK for bitmap output, but don't do it if you have vector output (pdf, eps), especially if your graph is complicated or contains a lot of datapoints. It blows up the resulting file to twice its size.
Gnuplot at the moment (v 5.0pl1) has no option to place the tics centered on the axis. You'll have to use one of the workarounds shown here.
Related
I have a polar plot in Gnuplot given by
set polar
set angles degrees
unset xtics
unset ytics
unset raxis
set ttics 0,30
set grid polar linestyle 1 dashtype 2 linecolor rgb 'grey'
set samples 200, 200
unset border
set xrange [-0.51:0.51]
set yrange [-0.51:0.51]
set size square
unset key
plot sin(2*t)*cos(2*t)
Which gives the following output:
However,
I want the rlabels (0, 0.1, 0.2, etc) at an angle of 45 degrees instead of them being placed on the x-axis, and
There should be no rtics
Any help will be appreciated.
In order to remove the rtics do set rtics scale 0.
You can set the starting angle for polar graph (check help theta), however, only to {right|top|left|bottom} and not to 45°, but this still wouldn't help you here.
So, probably you have to set the labels "manually". Maybe there is an automatic way which I am not aware of. Check the following example.
Code:
### set rtics on 45° "axis"
reset session
set polar
set angles degrees
unset xtics
unset ytics
unset raxis
set ttics 0,30
set grid polar linestyle 1 dashtype 2 linecolor rgb 'grey'
set samples 200, 200
unset border
set xrange [-0.51:0.51]
set yrange [-0.51:0.51]
set size square
unset key
set rtics scale 0
set format r ""
myRTics = "0.1 0.2 0.3 0.4 0.5"
do for [i=1:words(myRTics)] {
r = word(myRTics,i)
set label i sprintf("%s",r) at r*cos(45),r*sin(45) center
}
plot sin(2*t)*cos(2*t)
### end of code
Result:
I addition to #theozh's excellent answer, I realized I can generate the labels on the fly, by providing the start, end, and increment of the labels. So instead of
myRTics = "0.1 0.2 0.3 0.4 0.5"
do for [i=1:words(myRTics)] {
r = word(myRTics,i)
set label i sprintf("%s",r) at r*cos(45),r*sin(45) center
}
I will write
rangle = 45
rstart = 0.1 ; rend = 0.5 ; rinc = 0.1 ;
n = floor((rend-rstart)/rinc) + 1
do for [i=1:n] {
r = rstart + (i-1)*rinc
set label i sprintf("%g",r) at r*cos(rangle),r*sin(rangle) center
}
The rest of it will be as already answered by #theozh. The output doesn't change.
I am a bit surprised that Gnuplot doesn't have any inbuilt method to handle this.
I am trying to plot a simple linear surface of the equation x + y + 2z = 0. This is my file:
set xrange [-4:4]
set yrange [-4:4]
set zrange [-4:4]
set xlabel 'x'
set ylabel 'y'
set zlabel 'z'
set xyplane at -4.0
unset xzeroaxis
unset yzeroaxis
unset zzeroaxis
set border 1023-128
set xtics out nomirror
set ytics out nomirror
set ztics out
set xtics add ('' -4)
set label 1 "{/:Italic x} + {/:Italic y} + 2{/:Italic z} = 0" at 4,4.2,-2 font 'Times New Roman, 11'
set arrow 1 from 0,0,-4 to 0,0,4 filled
set arrow 2 from 0,-4,0 to 0,4,0 filled
set arrow 3 from -4,0,0 to 4,0,0 filled
set arrow 4 from 3.9,4.1,-2.1 to 3.6,3.6,-2.5
unset key
set pm3d lighting primary 0.5 specular 0.6
set style fill transparent solid 1 noborder
set palette defined (0 "cyan", 1 "green")
unset colorbox
set pm3d depthorder
splot -x/2-y/2 with pm3d
The result
I'm using arrows to show the axis, since they seem to be stuck to the xy plane, and moving it causes further issues with the tics and border. But now the problem is that they are completely occluded by the surface. Is there a setting which allows to appear in front when they "pierce" the surface? I'd like to make the surface semitransparent, but the problem is clearer with these settings.
I guess your original idea, i.e. "piercing" a 3D surface with an arrow or line does not work right away in gnuplot, because gnuplot will not calculate the piercing points automatically. Please correct me if I am wrong and let me know in case there might be a simple solution to this.
As you did in your simple case, you can just split the arrow at the origin, because you already know the piercing point. However, what do you do if the surface is irregular or has several piercing points?
Solution: take the effort to create a segmented 3D arrow and let gnuplot automatically show and hide the surfaces as needed. This is probably getting close to what you had in mind. However, this solution will show surprises when you want to change the color of the arrows. So, there is still room for improvement.
Code: (simple version with arrows just along x,y,z axes)
### arrows "piercing" a 3D surface
reset session
set view equal xyz
set xyplane relative 0.0
set xrange [-4:4]
set yrange [-4:4]
set zrange [-4:4]
# create 3D arrow
r = 0.01 # radius of arrow
rHead = 0.1 # radius of arrrowhead
n = 6 # corners of arrow
set print $myArrow
do for [h=-100:90] {
do for [a=360/n:360:360/n] {
print sprintf("%g %g %g",r*cos(a),r*sin(a), h/100.)
}
print ""
}
do for [h=90:100] {
do for [a=360/n:360:360/n] {
print sprintf("%g %g %g",rHead*(100-h)/10.*cos(a), \
rHead*(100-h)/10.*sin(a), h/100.)
}
print ""
}
set print
unset key
unset colorbox
set pm3d depthorder
set samples 100
set isosamples 100
set view 65,46,1.3
# function to demonstrate "piercing"
f(x,y) = (sin(x*3)/x + sin(y*3)/y - 3)/2
splot \
f(x,y) w pm3d, \
$myArrow u 1:2:($3*4):(0) w pm3d lc rgb var, \
$myArrow u 2:($3*4):1:(0) w pm3d lc rgb var, \
$myArrow u ($3*4):1:2:(0) w pm3d lc rgb var
### end of code
Result:
gnuplot> help layer
A gnuplot plot is built up by drawing its various components in a fixed order.
This order can be modified by assigning some components to a specific layer
using the keywords `behind`, `back`, or `front`. For example, to replace the
background color of the plot area you could define a colored rectangle with the
attribute `behind`.
set object 1 rectangle from graph 0,0 to graph 1,1 fc rgb "gray" behind
The order of drawing is
behind
back
the plot itself
the plot legend (`key`)
front
Within each layer elements are drawn in the order
grid, axis, and border elements
pixmaps in numerical order
So basically you need to add the "front" attribute to the objects you want to appear in front of the plot.
I have a sparse grid of data that I would like to plot with a log scale in the x and y axes, with colours and contours defining the z axis.
Using logscale xy results in a very different looking plot to when I plot a linear plot of the log of each axis.
I want the nice logarithmic axes and positioning of the contour legend of the first plot, with the nice central portion and colour scale of the second plot.
My current script is
set dgrid3d 50,50 splines
set pm3d
set pm3d map
set cntrparam levels auto
set contour surface
#set logscale xy
#splot "test_data.dat" using 1:2:3 with l nosurf lw 3
splot "test_data.dat" using (log10($1)):(log10($2)):3 with lines nosurf lw 3
where I change the comments to change which plots I make.
What am I doing wrong?
All suggestions will be gladly accepted.
edit: Through some more research, I think that the data is being gridded by dgrid3d in linear space, and then plotted in log space by logscale xy. I want the data to be gridded and plotted in log space.
Is there a gnuplot-only solution?
Two-fold solution. 1) the difference in the look of the plots was due to a bug in 5.2.2. Upgrade to 5.2.3 fixed it.
2) Solved the gridding issue by plotting the log of the data on linear axes and then bodging the axes to look logarithmic.
The plot needs to be improved by making the minor tics smaller than the major.
set pm3d
set pm3d map
set cntrparam levels auto
set contour surface
#set xrange [2:6] #setting this makes the image finish at the y2 tics, without changing the xtics
set xtics 2,1,6
unset xtics
# "major" tics
set xtics ("100" 2, "1000" 3, "10000" 4, "100000" 5, "1e6" 6)
# "minor" ticks
set for [i=2:6:1] xtics add ("" log10(2*10**i),"" log10(3*10**i),"" log10(4*10**i),"" log10(5*10**i), "" log10(6*10**i),"" log10(7*10**i),"" log10(8*10**i),"" log10(9*10**i))
set ytics -2,1,-1
unset ytics
set ytics ("0.01" -2, "0.1" -1)
set for [i=-3:0:1] ytics add ("" log10(2*10**i),"" log10(3*10**i),"" log10(4*10**i),"" log10(5*10**i), "" log10(6*10**i),"" log10(7*10**i),"" log10(8*10**i),"" log10(9*10**i))
splot "test_data.dat" using (log10($1)):(log10($2)):3
TL;DR
Is there a way to align corners of different plots in a multiplot setup?
Is there a way to convert axis coordinates to screen coordinates?
Detailed explanation
I'm trying to layout a quite complicated canvas with gnuplot. To achieve what I want, I need to stack different plots on each other exactly.
I did something like :
reset;
set samples 20;
set xrange [-pi:pi]; set yrange [-2:1];
set xlabel "x"; set ylabel "y";
unset key
set multiplot;
plot cos(x) w lp;
plot 2*cos(x+pi) w lp;
unset multiplot;
However, some components like the label, tics and borders are drawn twice. Then, when I do this with the cairolatex terminal the result is not as clear as if I don't stack plots.
Thus, I would like to draw these components for the first plot and then unset labels, tics and borders for the subsequent ones as shown in the snippet below:
set multiplot;
plot cos(x) w lp;
set border ls 4; # Just to distinguish it
unset xlabel; unset ylabel;
unset tics;
plot 2*cos(x+pi) w lp;
unset multiplot;
This generate an image where the next plots are not aligned (on left and bottom) with the first one, as no space is taken by the labels and tics.
To address this issue, I need to set the origin and size of the next plots manually. The bottom left corners must be aligned.
From the gnuplot documentation, it is possible the get the screen coordinated of an (X,Y) axis coordinate using:
GRAPH_X = (X - GPVAL_X_MIN) / (GPVAL_X_MAX - GPVAL_X_MIN)
GRAPH_Y = (Y - GPVAL_Y_MIN) / (GPVAL_Y_MAX - GPVAL_Y_MIN)
SCREEN_X = GPVAL_TERM_XMIN + GRAPH_X * (GPVAL_TERM_XMAX - GPVAL_TERM_XMIN)
SCREEN_Y = GPVAL_TERM_YMIN + GRAPH_Y * (GPVAL_TERM_YMAX - GPVAL_TERM_YMIN)
FRAC_X = SCREEN_X * GPVAL_TERM_SCALE / GPVAL_TERM_XSIZE
FRAC_Y = SCREEN_Y * GPVAL_TERM_SCALE / GPVAL_TERM_YSIZE
As we are trying to align the bottom left corner, (X,Y) == (GPVAL_X_MIN, GPVAL_Y_MIN). Thus, GRAPH_* = 0 and SCREEN_(*) = GPVAL_TERM_\1MIN. Thus:
# Multiply by 1.0 to promote variables to floats
FRAC_X = 1.0 * GPVAL_TERM_XMIN * GPVAL_TERM_SCALE / GPVAL_TERM_XSIZE
FRAC_Y = 1.0 * GPVAL_TERM_YMIN * GPVAL_TERM_SCALE / GPVAL_TERM_YSIZE
Resulting snippet:
set multiplot;
plot cos(x) w lp;
FRAC_X = 1.0 * GPVAL_TERM_XMIN * GPVAL_TERM_SCALE / GPVAL_TERM_XSIZE;
FRAC_Y = 1.0 * GPVAL_TERM_YMIN * GPVAL_TERM_SCALE / GPVAL_TERM_YSIZE;
set origin FRAC_X, FRAC_Y;
set border ls 4; # Just to distinguish it
unset xlabel; unset ylabel;
unset tics;
plot 2*cos(x+pi) w lp;
unset multiplot;
But as you can see, resulting plot is not better...
By the way, I did not find how to define the size to align the top right corners.
Questions
What is wrong with the origin computation? How to align top right corner as well?
Kind regards,
Alexis.
You can fix the margins to keep the automatic size after the first plot as follows (see also https://stackoverflow.com/a/19132068/2604213):
fix_margins = 'set margins '.\
'screen GPVAL_TERM_SCALE * GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE), '.\
'screen GPVAL_TERM_SCALE * GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE), '.\
'screen GPVAL_TERM_SCALE * GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE), '.\
'screen GPVAL_TERM_SCALE * GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE)'
set samples 20
set xrange [-pi:pi]; set yrange [-2:1]
set xlabel "x"; set ylabel "y"
unset key
set multiplot
plot cos(x) w lp
eval(fix_margins)
unset tics; unset xlabel; unset ylabel
plot 2*cos(x+pi) w lp
unset multiplot
In order to achieve an exact overlap, I think that an option would be to adjust the margin manually:
set terminal pngcairo
set output 'fig.png'
eps_h = 0.1
eps_w = 0.1
set multiplot
unset key
set lmargin at screen 2*eps_w
set tmargin at screen 1 - eps_h
set rmargin at screen 1 - eps_w
set bmargin at screen eps_h
plot cos(x) w lp lc rgb 'dark-red'
set border ls 4;
unset xlabel
unset ylabel
unset tics
plot 2*cos(x+pi) w lp lc rgb 'royalblue'
which gives:
I hope I don't get firebombed here, this is the first time I'm posting. Lol
So after a grueling simulation, I have this large data set of the form r, θ, and T(r,θ). I needed to plot a contour map for this data set. θ is in degrees.
So I ran to GNUPlot and I hoped that this will save me from my problems. I studied a bit about how it works, but I still cannot plot my 2D contour data.
I then researched about my problem then I saw this thread here in SE:
gnuplot 2D polar plot with heatmap from 3D dataset - possible?
I used both codes (that I assume to be working) in that post and NONE is working with my dataset. I hope someone can help me with my problem.
This is what I changed the code into:
reset
set terminal pngcairo size 800,800
set output '3d-polar.png'
set lmargin at screen 0.05
set rmargin at screen 0.85
set bmargin at screen 0.1
set tmargin at screen 0.9
set pm3d map
unset key
set multiplot
# plot the heatmap
set parametric
set isosamples 500
unset border
unset xtics
unset ytics
set angles degree
r = 0.05 # CHANGED THIS
set urange[0:r] # radius
set vrange[0:360] # angle
set xrange[-r:r]
set yrange[-r:r]
set colorbox user origin 0.9,0.1 size 0.03,0.8
splot 'data.dat' using 1:2:3 # CHANGED THIS
# now plot the polar grid only
set style line 11 lc rgb 'white' lw 2
set grid polar ls 11
set polar
set rrange[0:r]
unset raxis
set rtics format '' scale 0
unset parametric
set for [i=0:330:30] label at first (r+0.35)*cos(i), first (r+0.35)*sin(i)\
center sprintf('%d', i)
plot NaN w l
unset multiplot
So I had this little 'eureka' moment. Apparently I had to put dgrid3d and had to convert the coordinates from polar to cartesian.
Upon converting (and putting set dgrid3d) this ugly plot appeared:
reset
set terminal pngcairo size 800,800
set output '3d-polar.png'
set lmargin at screen 0.05
set rmargin at screen 0.85
set bmargin at screen 0.1
set tmargin at screen 0.9
set pm3d map
unset key
set multiplot
# plot the heatmap
set parametric
set isosamples 500
unset border
unset xtics
unset ytics
set angles degree
r = 0.05 # CHANGED THIS
set urange[0:r] # radius
set vrange[0:360] # angle
set xrange[-r:r]
set yrange[-r:r]
set colorbox user origin 0.9,0.1 size 0.03,0.8
set dgrid3d # ADDED THIS
splot 'data.dat' using 1:2:3 # CHANGED THIS
# now plot the polar grid only
set style line 11 lc rgb 'white' lw 2
set grid polar ls 11
set polar
set rrange[0:r]
unset raxis
set rtics format '' scale 0
unset parametric
set for [i=0:330:30] label at first (r+0.35)*cos(i), first (r+0.35)*sin(i)\
center sprintf('%d', i)
plot NaN w l
unset multiplot
The plot.
I'm at my limit here now. Three questions.
1. Am I correct to assume that I can use the mathematics in gnuplot to convert the coordinates from polar to cartesian? Or is there a way for me to use the polar coordinate data immediately?
2. How do I limit the 'colors' to the round polar plot?
3. What happened to the degree and radius readings? Where did they go?
Thanks!