I need to plot a function on a coordinate system that has its origin at the center of the screen (or somewhere near the center, but not necessarily in the center) and I need to draw axes so that they cross at the origin. Axes should have labels and tics as well, and arrows.
I have no idea how to do this efficiently, so far in my code I manually set offsets for my tics, and draw arrows manually using offsets as well. I also set offsets on the axes labels. All this is very fragile, and offsets change depending on the terminal settings.
Would someone please help me with a sample code or an explanation how to do this the right way?
Well, using _zeroaxis is the "right" way to go to get the tics and labels in: setting the _range gives you the symmetry to make 0,0 centre ... and once you know the _range, you can draw arrows on manually.
set xzeroaxis
set xtics axis
set xrange [-10:10]
set arrow 1 from -9,0 to -10,0
set arrow 2 from 9,0 to 10,0
set yzeroaxis
set ytics axis
set yrange [-1:1]
set arrow 3 from 0,-.9 to 0,-1
set arrow 4 from 0,.9 to 0,1
set border 0
plot sin(x)
Hack attack!
set term pngcairo truecolor size 300,300 font "Arial,12"
set out 'plot.png'
# x,y min/max and center
xmin = -10
xc = 0
xmax = 10
ymin = -2
yc = 0
ymax = 2
# default borders
tm = 1
bm = 1
rm = 4
lm = 4
# arrow scale factor to cover last tic
af = 1.05
set arrow from xc,yc to xmin*af,yc filled size 0.6,30
set arrow from xc,yc to xmax*af,yc filled size 0.6,30
set arrow from xc,yc to xc,ymax*af filled size 0.6,30
set arrow from xc,yc to xc,ymin*af filled size 0.6,30
set multiplot layout 2,2
## Plot 1, top left
set key top left
set xr [xmin:xc]
set yr [yc:ymax]
set tmargin tm
set bmargin 0
set rmargin 0
set lmargin lm
set border 9
unset ytics
set xtics nomirror
plot sin(x)
## Plot 2, top right
unset key
set xr [xc:xmax]
set lmargin 0
set rmargin rm
set border 3
set ytics nomirror
replot
## Plot 3, bottom left
set xr [xmin:xc]
set yr [ymin:yc]
set bmargin bm
set tmargin 0
set lmargin lm
set rmargin 0
set border 12
unset tics
replot
## Plot 4, bottom right
set xr [xc:xmax]
set lmargin 0
set rmargin rm
set border 6
set ytics nomirror
replot
unset multiplot
I get this output:
That said, you might look into the zeroaxis option. There is a demonstration here. Sadly this option doesn't draw the axis at zero, but just puts a line at that position.
I would not say my method is 'efficient,' but there is probably not too much effort to modify this for your purposes apart from changing the function/data being plotted since most of the work is done by replot commands. I don't know an option to make gnuplot put arrows at the end of axes or change where the axes are drawn natively.
In addition to Jim's answer, if required the tics and axes can be brought to the front
# bring the grid over the plot
set grid front
# remove grid if not required
unset grid
Related
I am trying to make a wedge-shaped plot in polar coordinates spanning from 0 to 60 degrees. Something like the following figure: Wedge-plot I want
However, the command "trange" is used for the range of the plot, not of the grid itself, and I always end up with the full-circle grid, like this: Same plot but with full grid.
Is there a simple command to set the limits in the angle variable? Here is the code I used to plot the former figure in gnuplot 5.2
set terminal pngcairo enhanced font "arial,10" fontscale 1.0 size 600, 400
set output 'polar1.png'
unset key
set border 4096 lt black linewidth 1.000 dashtype solid
unset xtics
unset ytics
set size ratio 1 1,1
set raxis
set ttics 0.00000,30 font ":Italic"
set polar
set grid polar 30.0000 lw 1.5
plot cos(4*t) lt 3 lw 2
Thank you in advance!
I guess there is no "intended" way to limit the maximum angle in a polar plot.
So, there is a simpler (but ugly) workaround, which simply covers the unwanted part by a filled polygon.
Note: There will be an issue if your rmax is not an integer multiple of rtic 0.2, i.e. a plot with rmax=1.05 will not look as desired. Therefore, as a workaround an extra rtic at rmax is added.
Script:
### plot only part of polar plot
reset session
rmax = 1.05
amax = 60
set polar
set rrange [0:rmax]
set rtics 0.2 scale 0.5
set rtics add ('' rmax)
set grid r polar 10 lt black lw .3
set trange [0:2*pi]
set ttics 0,10 format "%g°" font ":Italic" scale 0.5,0.25 offset -1,0
set mttics 2
set xlabel "r-label"
set xrange [0:rmax]
unset xtics
set yrange [0:rmax]
unset ytics
set size square
set border 4096
set lmargin 0
set tmargin 0
unset title
unset key
set samples 300
set obj 1 polygon from graph 0,0 to first rmax*cos(pi/180*amax),rmax*sin(pi/180*amax) \
to first rmax*cos(pi/180*amax), screen 1.0 \
to first 0, screen 1 to screen 0,1 to screen 0,0 to graph 0,0 \
fc rgb 0xffffff fs solid 1.0 front
set arrow 1 from graph 0,0 to first rmax*cos(pi/180*amax),rmax*sin(pi/180*amax) lc "black" nohead front
plot cos(4*t) lt 3 lw 2
### end of script
Result:
gnuplot adds grid lines even on axes, it can cause unpleasant effects:
set logscale x
set xrange [0.01:100]
set xtics font ",12"
set x2tics font ",12"
set mxtics 10
set ytics font ",12"
set y2tics font ",12"
set grid xtics mxtics ytics lt 0 lw 3, lt 0 lw 0.5 behind
set grid
plot sin(x)
Especially if one then plots the above to eps, it looks like there are both logarithmically spaced and linearly spaced tics on the x-axis. Is there any nice way to get rid of the grid lines at axes? A workaround would be to make the axes thicker, but that is not the way I want. I really want to delete those grid lines.
To explain what I mean
The linearly spaced tics that are seen in the picture are actually the dotted grid, so it has nothing to do with tics...
As shown, there are both log and linear tics along x. That is because both the x axis and the x2 axis are contributing tics to both the top and bottom borders. You can turn that off with
set tics nomirror
Are you asking how to make the range of the tics smaller than the range of the axes? In the plot you show, that would be
set yrange [-1:1]
set ytics -0.8, 0.2, 0.8
set ytics add (-1 2, 1, 2)
The last command adds back explicit tics at y=-1 and y=1 without generating a corresponding grid line. See documentation for set xtics list
I want to display different tick color at 0.
For eg, the image below I want to set tick color at 0 in y axis to blue. Can it possible? Thanks.
I am not aware of a direct Gnuplot feature that would allow to do this, nevertheless one might use some workaround.
For example, one could unset the tic at position zero and place there a custom label instead:
set terminal pngcairo enhanced font ",14"
set output 'fig.png'
set multiplot
xMin = 0
xMax = 2*pi
set xr [xMin:xMax]
set yr [-1:1]
set xtics out nomirror
set ytics out nomirror
set ytics add ("" 0)
set label "0" at xMin,0 offset char -1.5,0 right textcolor rgb "blue"
plot sin(x) w l t 'sin(x)'
Alternatively, one could use a technique based on multiplot, where the strategy is basically first to plot the function/data of interest without the tic at position zero and then overlay this with a plot which is empty but for the customized tic at position zero:
set terminal pngcairo enhanced font ",14"
set output 'fig.png'
set xr [0:2*pi]
set yr [-1:1]
set xtics out nomirror
set ytics out nomirror
set ytics add ("" 0)
plot sin(x) w l t 'sin(x)'
set lmargin at screen GPVAL_TERM_SCALE * GPVAL_TERM_XMIN / (1.*GPVAL_TERM_XSIZE)
set rmargin at screen GPVAL_TERM_SCALE * GPVAL_TERM_XMAX / (1.*GPVAL_TERM_XSIZE)
set bmargin at screen GPVAL_TERM_SCALE * GPVAL_TERM_YMIN / (1.*GPVAL_TERM_YSIZE)
set tmargin at screen GPVAL_TERM_SCALE * GPVAL_TERM_YMAX / (1.*GPVAL_TERM_YSIZE)
unset border
unset key
unset xtics
unset ytics
set ytics ("0" 0) out nomirror textcolor rgb 'blue'
plot 1/0
Both approaches result in a nearly identical plot:
I want to plot two charts (reading the same data points) using multiplot. The purpose is to put the second (smaller) chart in the right of the first (bigger) chart.
The code is
set term post eps enhanced color blacktext size 4,4 solid "Times-Roman" 14
set output 'cla.ps'
set multiplot
# draw bottom and left lines
unset border
unset xtics
unset ytics
set border 3
# increasing the canvas size
set rmargin 50
set tmargin 2
# put the big chart, it will not use the whole space
set origin 0,0
set size 1.2,0.5
plot 'test.txt' u 1 with points lc rgb "black"
# put the small char in the right
set origin 0.6,0.2
set size 0.2,0.2
plot 'test.txt' u 1 with points lc rgb "black"
# always unset multiplot
unset multiplot
Problem is, the second chart is shown in a mirror fashion (horizontal flip). But I didn't such an option. How can I fix that?
That should give you a nice warning explaining that: warning: Terminal canvas area too small to hold plot. Check plot boundary and font sizes.
With set rmargin 50 you set the right margin to be 50 character widths. That applies also to the second plot unless you use e.g. set rmargin -1 to reset it to automatic calculation.
But I don't see any sense to set both the size and the rmargin. Setting the rmargin does not increase the canvas size, like you suggest in your comments.
Here is a working example:
set term post eps enhanced color blacktext size 4,2 solid "Times-Roman" 14
set output 'cla.ps'
set multiplot
# draw bottom and left lines
unset tics
set border 3
# put the big chart, it will not use the whole space
set origin 0,0
set size 0.8,1
plot x**2
# put the small char in the right
set origin 0.75,0.2
set size 0.25,0.3
plot x
# always unset multiplot
unset multiplot
That gives you the output (tested with 4.6.5):
I have been trying very unsuccessfully to stack 3 graphs together in a multi-plot layout on a canvas that is a ratio of 2:3(width by height).
set terminal postscript eps enhanced "Helvetica" 24 color
set output "data.eps"
set timefmt "%s"
#set size 1.0,1.5
#set bmargin 2
#set tmargin 2
set size 1.0,1.5
set multiplot layout 3,1
set size 1.0,0.5
set tmargin 2
set bmargin 0
set ylabel 'Distance'
set format x ""
set ytics nomirror font "Helvetica,10"
set key top
plot "trace1.dat" using 1:3 axes x1y1 title "distances" with lines lw 2 lc rgb 'blue'
set size 1.0,0.5
set bmargin 0
set tmargin 0
set ylabel 'Power (W)'
set format x ""
set ytics nomirror font "Helvetica,10"
set key top
plot "trace2.dat" using 1:2 axes x1y1 title "device" with lines lw 2 lc rgb 'red'
set size 1.0,0.5
set bmargin
set tmargin 0
set xdata time
set ylabel 'Power (W)'
set xlabel 'Time (EST)' offset 0,-2.8 font "Helvetica,32
set format x "%b %d, %H:%M"
set ytics nomirror font "Helvetica,10"
set xtics nomirror rotate by 90 offset 0,-2.0 out font "Helvetica,10"
set key top
plot "trace3.dat" using 1:2 axes x1y1 title "aggr" with lines lw 2 lc rgb 'blue'
unset multiplot
When I do something like above, I get the plot shown below, there's a lot of blank space at the top of the canvas and the 3 multiplot graphs seem to overlap each other.
Any kind of help or pointer will be greatly appreciated.
In order to use a bigger canvas, you must use the size option when setting the terminal, e.g.:
set terminal postscript eps enhanced size 10cm,15cm
set size just changes the plot size relative to your canvas. To see this, consider
set terminal wxt
set size 1.0,1.5
plot sin(x)
Parts of the plot disappear, because it is much too high with respect to the canvas.
To stack three plots with same heights, in my opinion its best to use fixed margins:
set terminal pngcairo size 600, 900
set output 'stacking.png'
set lmargin at screen 0.15
set rmargin at screen 0.95
TOP=0.98
DY = 0.29
set multiplot
set offset 0,0,graph 0.05, graph 0.05
set xlabel 'time'
set ylabel 'ylabel 1' offset 1
set tmargin at screen TOP-2*DY
set bmargin at screen TOP-3*DY
set ytics -1000,500,1000
plot 1150*cos(x) title 'First'
set xtics format ''
unset xlabel
set ylabel 'ylabel 2' offset 0
set tmargin at screen TOP-DY
set bmargin at screen TOP-2*DY
set ytics -100,50,100
plot 101*sin(x) title 'Second'
set ylabel 'ylabel 3' offset -1
set tmargin at screen TOP
set bmargin at screen TOP-DY
set ytics -8,4,8
plot 10*sin(2*x) title 'Third'
unset multiplot; set output
The result is (with 4.6.3):
In order to avoid overlapping labels of the ytics, you must change the range where the tics are drawn, e.g. with set ytics -100,50,100, which puts ytics between -100 and 100 in steps of 50. Using set ytics rangelimited doesn't work
To increase the distance between the plot curve and the border, use set offset with graph coordinates, like done in the above script.
I started with the lowest plot, because only that has x labels and an xlabel.
You need to use set origin, too.
set terminal postscript eps enhanced
set output "data.eps"
set size 1.0,1.5
set multiplot layout 3,1
set size 1.0,0.5
set origin 0,1
...
plot ...
set size 1.0,0.5
set origin 0,0.5
...
plot ...
set size 1.0,0.5
set origin 0,0
...
plot ...
unset multiplot