gnuplot: Joined axes with overlapping tics - plot

A while back I found a method to join Axes in a nice way. Now that I revisit the plot-making for a report I find that I'm not satisfied...
The reason for this is the overlap between the labels at the tics of my plot. Since I joined the axes, the last of the left and first of the right plot tics will overlap, shown in the below example with random sin and cos plotted.
How can I circumvent this in a general way. Please note that I will be plotting a lot of figures like these in series, figuring out each of these tics depending on the values of my data is not an option for me.
Thanks in advance!
My plot-file: JointAxes.gp
# Generic gnuPlot script for plotting multiple plots in a single figure
# Resetting all variables. Standard for all plots.
reset
# Setting (terminal) options.
set terminal pdfcairo color font ",8"
set output 'JointAxes.pdf'
# Option to plot multiple graphs in one picture, note the number of figs here is 4 (2 by 2).
set multiplot layout 2,2 rowsfirst
# Macro's needed to produce a figure with all plots 'touching'.
set macros
# Small plot labels
LABEL = "at graph 0.9,0.9"
# Axes adjustment
set format x "%.1f"
XAXE = 'set xlabel "Extent"; set xtics -2*pi,pi/3 # N.B. tics should be changed due to conjoined axes.
YAXE = 'set ylabel "Amplitude"; set ytics -1,0.25
NOX = "unset xtics;\
unset xlabel"
NOY = "unset ytics;\
unset ylabel"
# Locking the graphs at fixed points in the figure
# Margins for each row resp. column
TMARGIN = "set tmargin at screen 0.90; set bmargin at screen 0.55"
BMARGIN = "set tmargin at screen 0.55; set bmargin at screen 0.20"
LMARGIN = "set lmargin at screen 0.10; set rmargin at screen 0.50"
RMARGIN = "set lmargin at screen 0.50; set rmargin at screen 0.90"
# General plot markup
unset key
# Legend/key adjustment
# set key samplen 3 # length of legend colour-bar
# set key spacing 1 # spacing between samples
# Optional: Adjusting range
set yrange [-1:1]
set xrange [-pi:pi]
# Plotting the first of the 'sub'-plot
#YAXE; #NOX
#TMARGIN; #LMARGIN
set label 1 'a' #LABEL
plot sin(x)
# Plotting the second 'sub'-plot, i.e. a new plot command.
#NOX; #NOY
#TMARGIN; #RMARGIN
set label 1 'b' #LABEL
plot cos(x)
# Plotting 3rd
#YAXE; #XAXE
#BMARGIN; #LMARGIN
set label 1 'c' #LABEL
plot sin(x + 1.57)
#And Fourth
#NOY; #XAXE
#BMARGIN; #RMARGIN
set label 1 'd' #LABEL
plot cos(x + 1.57)
unset multiplot
set terminal wxt
set output
# OEF

Related

gnuplot: How to put legends outside of each plot in a multiplot?

I would like to put the legend of each plot outside on the top of them.
I'm using multiplot ,so the problem is that when i try to do this all the legends end up at the top of the figure.
How can I put each legend on top of the corresponding plots ?
Hers is a sample of my code
reset
set datafile separator comma
set term pdfcairo enhanced font "Helvetica,7" size 4,7
set output "data.pdf"
set multiplot layout 6,2 margins 0.07, 0.95, 0.05, 0.97 spacing 0.1,0.05
set tics nomirror
set grid xtics ytics lt 1 lw 0.5 lc rgb "grey"
############################################ PLOT
set key outside horizontal
set ylabel "V [mV]"
set label "A" at graph -0.14,1.1
plot "data.txt" using "time":"V" with lines
unset label
plot "data.txt" using "time":"V" with lines
unset ylabel
############################################# PLOT
set key outside horizontal
set label "B" at graph -0.14,1.1
set ylabel "I_{tot} [pA/pF] "
plot "data.txt" using "time":"Itotal" with lines
unset ylabel
unset label
unset key
############################################ PLOT
set key outside horizontal
set label "G" at graph -0.16,1.1
set ylabel "J_{rel} [mM/s]"
plot "data.txt" using "time":"Jrel" with lines
unset ylabel
unset label
unset key
unset multiplot
And here is the image produced (by the complete code)
Check the following 3 variations of a minimal example.
Variation 1 has different sizes of the subplots, that's not what you wanted.
In variation 2, I would consider the behaviour of the key as unexpected and as a bug.
The third (cumbersome) variation probably comes close to what you expected.
Code:
### multiplot version with undesired auto margins but correct keys
reset session
set key out horizontal
set multiplot layout 3,3 spacing 0.1,0.1
do for [i=1:9] {
plot x**i title sprintf("x**%d",i) lc i
}
unset multiplot
pause -1 "Press Enter to continue"
### multiplot version with desired margins but wrong keys
reset session
set key out horizontal
set multiplot layout 3,3 margin 0.07, 0.93, 0.07, 0.93 spacing 0.1,0.1
do for [i=1:9] {
plot x**i title sprintf("x**%d",i) lc i
}
unset multiplot
pause -1 "Press Enter to continue"
### version with desired margins and correct keys (but cumbersome)
reset session
set key out horizontal
myLmargin = 0.07
myRmargin = 0.93
myBmargin = 0.07
myTmargin = 0.93
myXspacing = 0.1
myYspacing = 0.1
Rows=3 # rows
Cols=3 # columns
myWidth = (myRmargin-myLmargin-(Cols-1)*myXspacing)*1./Cols
myHeight = (myTmargin-myBmargin-(Rows-1)*myYspacing)*1./Rows
# myPosX(n) = myLmargin + n*(myWidth + myXspacing)
# myPosY(m) = myTmargin - (row+1)*myHeight - 0.5*myYspacing
myLmarg(row,col) = myLmargin + col*(myWidth + myXspacing)
myRmarg(row,col) = myLmargin + (col+1)*myWidth + col*myXspacing
myBmarg(row,col) = myTmargin - (row+1)*myHeight - row*myYspacing
myTmarg(row,col) = myTmargin - row*(myHeight + myYspacing)
set multiplot
do for [row=0:Rows-1] {
do for [col=0:Cols-1] {
set origin myLmarg(row,col), myBmarg(row,col)-0.5*myYspacing
set size 1,1./Rows
set lmargin screen myLmarg(row,col)
set rmargin screen myRmarg(row,col)
set bmargin screen myBmarg(row,col)
set tmargin screen myTmarg(row,col)
j = row*Cols + col + 1
plot x**j title sprintf("x**%d",j) lc j
}
}
unset multiplot
### end of code
Result 1: (undesired auto margins, i.e. different subplot sizes, but correct keys)
Result 2: (desired margins and equal subplot sizes, but wrong overlapping keys)
Result 3: (desired margins and sizes and correct keys, but "manual" settings)

Can I space a gnuplot grid differently than tics?

How can I add an X grid with different spacing than the tics? My plot is a histogram showing # of patents (of a certain type) granted per year, and the year range is large (1807-1971). I'd like to tic/label each year but only add X grid lines every decade (and also use a different color for the matching decade labels).
I've been searching for an answer and trying things for hours and getting nowhere. Are either of these possible?
My current plot (with no X grid) looks like:
And the script is:
set style data histograms
set style histogram gap 1
set style fill solid
set title "Number of Prism Glass Patents Granted" font "fixed, 24" offset 0,-0.9
set xlabel "Year" font "fixed,18" offset 0,0.8
set nokey
set xtics out nomirror rotate font "fixed, 8" offset 0,0.4
set grid y
plot 'frequency.dat' using 2:xtic(1) linecolor 'blue'
I assume your data consists out of two columns: Year and number of patents.
Why do you use xitc(1), is it necessary to label every single year?
What about using minor and major xtics? I would use plotstyle with boxes.
Code:
### major and minor xtics
reset session
# generate some random data
set print $Data
do for [i=1807:1971] {
print sprintf("%d %d", i, int(rand(0)*100))
}
set print
set xlabel "Year"
set xtics out nomirror
unset x2tics
set xtics 10
set mxtics 10
set grid ytics
set grid xtics
set boxwidth 0.5
plot $Data u 1:2 with boxes fill solid 1.0 lc rgb "blue" notitle
### end of code
Result:
Addition:
Another version with grid every 10 years and label with different color. Labels are only shown when number of patents>0. Instead of using xtics it is done by plotting with labels.
Code:
### major and minor xtics
reset session
set term pngcairo size 1600,360
set output "tbGrid.png"
xmin = 1807
xmax = 1971
# generate some random data
set print $Data
do for [i=xmin:xmax] {
print sprintf("%d %d", i, int(rand(0)+0.4)*(int(rand(0)*100)))
}
set print
set xlabel "Year" offset 0,-1.5
set xrange[xmin-1:xmax+1]
set xtics 10 format "" out nomirror
set mxtics 10
set bmargin 5
set grid ytics
set grid xtics
set boxwidth 0.5
myTic(n,p) = p==0 ? "" : sprintf("%d",n)
myColor(n) = int(n)%10==0 ? 0xff0000 : 0x000000
plot $Data u 1:2 with boxes fill solid 1.0 lc rgb "blue" notitle, \
'' u 1:(0):(myTic($1,$2)):(myColor($1)) with labels \
tc rgb var rotate offset 0,-1.5 font ",8" notitle
set output
### end of code
Result:
The grid for each axis is generated from the tics for that same axis, so yes they always match. However if your plot uses only the x1 axis, you could define the range and tics for the x2 axis also and turn on the grid only for x2 and not for x1.
Recent gnuplot versions have a command set link x2 that ensures the x1 and x2 axes agree on the range and scale. If your version does not support this you can still set them to match explicitly:
set xrange [min:max]
set x2range [min:max]
set xtics <whatever> # these will label the actual plot
set x2tics <something else> # these will be used only for grid lines
set x2tics scale 0.0 format "" # show no x2 tics or labels on the plot
set grid x2 nox
plot ...
Thank you both-- here's my final plot:
...and its script:
# histogram of # of prism glass patents granted per year
###
set term png size 1800,600
xmin = 1807
xmax = 1971
set title sprintf("Prism Glass Patents Granted %d-%d", xmin, xmax) \
font "fixed, 24" offset 0,-0.5
set xlabel "Year" font "fixed,24" offset 0,-2
# x tic for each year
set xrange [xmin-1:xmax+1]
set xtics 1 out nomirror format ""
# x2 tic and gridline for each decade
set x2tics 1800,10,1970
set x2tics out font "fixed, 12" offset 0,-0.6
set grid x2 nox
set grid y # y axis is count
set boxwidth 0.5
set bmargin 5
set nokey
myTic(y,n) = n==0 ? "" : sprintf("%d",y) # only label year if count>0
myColor(y) = y==1897 ? 0x0000FF : 0x000000 # highlight 1897 (biggest year)
plot 'frequency.dat' using 1:2 with boxes fill solid lc rgb "blue", \
'' using 1:(0):(myTic($1,$2)):(myColor($1)) with labels \
tc rgb var rotate offset 0.1,-1.2 font "fixed,8"

Multiplot stacked over each other vertically, with same x axis in gnuplot

Following is the code I use and below that is my output. I want to remove all the spaces in between my subplots and the x labels. A sample of what I need is provided in the link at the end the only difference being I need all the boxes to be of same size.
set terminal jpeg
set output "mul.jpeg"
set multiplot
set xr[0:10]
set ylabel "y"
set format y ""
set key off
set size 1,0.25
set origin 0.0,0.0;
set xlabel "x"
plot sin(x)
replot sin(2*x)
set origin 0.0,0.25;
set format x ""
plot cos(x)
replot cos(2*x)
set origin 0.0,0.50;
set format x ""
plot sin(x)
set origin 0.0,0.75;
set format x ""
plot cos(x)
unset multiplot
What I actually need is something like this:
https://inspirehep.net/record/1345236/files/hada_fig2.png
Thank you for any help!
From gnuplot 5.0, you can use the solution offered by #Raphael_Roth of setting margins to zero, but should also use the margins option of multiplot, to allow space for the tic labels and xlabel at the bottom.
E.g,
set tmargin 0
set bmargin 0
set lmargin 1
set rmargin 1
set multiplot layout 4,1 margins 0.05,0.95,.1,.99 spacing 0,0
set xrange [0:10]
unset xtics
plot sin(x), sin(2*x)
plot cos(x), cos(2*x)
plot sin(x)
set xtics
plot cos(x)
unset multiplot
One way is to use multiplot layout, but it's a hassle to get it nice with the labels and tics (as they overlapp or don't fit into the canvas)
set terminal jpeg
set output "mul.jpeg"
set tmargin 0
set bmargin 0
set lmargin 1
set rmargin 1
unset xtics
unset ytics
set multiplot layout 4,1
set xr[0:10]
plot sin(x), sin(2*x)
plot cos(x), cos(2*x)
plot sin(x)
plot cos(x)
unset multiplot
The other possibility is to set the margins and/or origin of each plot separately as explained in these SO answers: multiplot - stacking 3 graphs on a larger canvas and How do gnuplot margins work in multiplot mode?

GNUPLOT: GPVAL_Y_MIN and GPVAL_Y_MAX in MULTIPLOT environment

This being my first question here makes me a litte nervous. Here I go.
What I want to achieve is to plot four different data files in a multiplot (2x2, maybe more). So far I succesfully plotted this disregarding the different ranges in the y-axis on each, the x-axis is, however, homogenous to all subplots.
So, what I would like is to set to each y-axis 10 "ytics" with a number of minor tics (and, by extension, the x-axis as well). I believe this is done with GPVAL_X (or GPVAL_DATA_X) and GPVAL_Y (or GPVAL_DATA_Y) _MIN/_MAX. So far so good.
This however, does not achieve the result I was aiming for: http://postimg.org/image/uyavbtxn5/
On panel A) the y-axis is correctly divided in 10 segments, not so the x-axis.
Panel B) display correctly both axes.
Panel C) Display the x-axis correctly, whereas the y-axis no.
Panel D) Similar to C), but on the y-axis the tics appear disordered.
This poses the following questions:
1) How can I produce correctly this multiplot using GPVAL (or GPVAL_DATA)?
2) Why the plotted function appears in front of the corresponding label if it specified to otherwise?
This figure was produced with the following code:
reset
# Term
GNUTERM = "x11"
## Output
set t epslatex standalone color solid size 20in,12in font "ptm, 20"
set o "test.tex"
# Axes & Labels
set style line 11 lc rgb '#2F4F4F' lt 1
set border 3 back ls 11
set tics nomirror out
set format y "\\tiny $%2.2t \\cdot 10^{%S}$"
set format x "\\tiny $%1.1t$"
set xlabel "$\\rho$"
unset ylabel
unset key
# Grid
set style line 12 lc rgb'#2F4F4F' lt 0 lw 1.5
set grid back ls 12
# Border
set border 31 linewidth .75 # thin border
# Multiplot Files
set multiplot layout 2,2 columnsfirst
## UL
## Labels
LABEL = "A) $sin(x)$"
set obj 10 rect fill at graph 0.3, graph 0.75 size char strlen(LABEL), char 2
set label 10 at graph 0.3, graph 0.75 LABEL front center
plot sin(x)
## Tics
set xtics add GPVAL_X_MIN,(GPVAL_X_MAX-GPVAL_X_MIN)/10.,GPVAL_X_MAX
set ytics add GPVAL_Y_MIN,(GPVAL_Y_MAX-GPVAL_Y_MIN)/10.,GPVAL_Y_MAX
set mxtics 5
set mytics 5
## LL
## Labels
LABEL = "B) $cos(x)$"
set obj 10 rect fill at graph 0.3, graph 0.75 size char strlen(LABEL), char 2
set label 10 at graph 0.3, graph 0.75 LABEL front center
plot cos(x)
## Tics
set xtics add GPVAL_X_MIN,(GPVAL_X_MAX-GPVAL_X_MIN)/10.,GPVAL_X_MAX
set ytics add GPVAL_Y_MIN,(GPVAL_Y_MAX-GPVAL_Y_MIN)/10.,GPVAL_Y_MAX
set mxtics 5
set mytics 5
## UR
## Labels
LABEL = "C) $cos(x) sin(x)$"
set obj 10 rect fill at graph 0.3, graph 0.75 size char strlen(LABEL), char 2
set label 10 at graph 0.3, graph 0.75 LABEL front center
plot cos(x)*sin(x)
## Tics
set xtics add GPVAL_X_MIN,(GPVAL_X_MAX-GPVAL_X_MIN)/10.,GPVAL_X_MAX
set ytics add GPVAL_Y_MIN,(GPVAL_Y_MAX-GPVAL_Y_MIN)/10.,GPVAL_Y_MAX
set mxtics 5
set mytics 5
## LR
## Labels
LABEL = "D) $cos(x) / sin(x)$"
set obj 10 rect fill at graph 0.3, graph 0.75 size char strlen(LABEL), char 2
set label 10 at graph 0.3, graph 0.75 LABEL front center
plot cos(x)/sin(x)
## Tics
set xtics add GPVAL_X_MIN,(GPVAL_X_MAX-GPVAL_X_MIN)/10.,GPVAL_X_MAX
set ytics add GPVAL_Y_MIN,(GPVAL_Y_MAX-GPVAL_Y_MIN)/10.,GPVAL_Y_MAX
set mxtics 5
set mytics 5
unset multiplot
# Clean-up
set o
set t x11
reset
exit 0

gnuplot: making axes numbers smaller in epslatex makes my axes label disappear offscreen

I'm writing a script to generate three plots in a column (using multiplot and setting margins). They all share an x-axis, so it's only necessary to label that on the bottom plot, but they have separate y-axes.
I'm using the epslatex terminal in gnuplot to generate the plots with latex labels and axes. Basically, I need the numbers on the axis to use a smaller font size than the actual axis labels. So far, I've been doing this using,
reset
set term epslatex standalone color solid 10
set output 'myplot.tex'
set multiplot;
#Common width for all three plots is set
set lmargin at screen 0.15;
set rmargin at screen 0.90;
set format x ""; #Removes xlabels from plots without removing tic marks
#First plot
set tmargin at screen 0.98;
set bmargin at screen 0.72;
set ylabel '$Label Name 1$';
set format y '\scriptsize{%g}';
plot "mydata.dat" u 1:3 w l lt 1 lw 3
#Second plot
set tmargin at screen 0.70;
set bmargin at screen 0.44;
set ylabel '$Label Name 2$';
set format y '\scriptsize{%g}';
plot "mydata.dat" u 1:11 w l lt 2 lw 3
#Third plot
set tmargin at screen 0.42;
set bmargin at screen 0.16;
set xlabel 'Common Label Name';
set format x '\scriptsize{%g}'; # Here I reset the x axis so it shows on
this plot
set ylabel 'Label Name 3';
set format y '\scriptsize{%g}';
plot "mydata.dat" u 1:5 w l lt 3 lw 3
unset multiplot;
So as you can see I use latex to format the numbers in a different size, specifically \scriptsize. For the xlabel at the end, everything works fine; the numbers are at a smaller font, and the xlabel prints just beneath it at the regular size. For the ylabels, however, the numbers DO appear smaller, but the actual label names don't appear on the plot.
At first I though they weren't being acknowledged somehow, but when I experimented with the margins, I found that if I move lmargin to the middle of the page, the ylabels reappear! It seems, for whatever reason, they're just being drawn some large distance from the axes themselves.
I've tried setting the labels with an offset, but that yields no joy.
The reason for this behaviour is, that gnuplot doesn't know, how the tics with LaTeX syntax will ultimately look like. The program tries to estimate the tic label length and adjusts the label positions accordingly.
If you have a format '\scriptsize %g', the tic labels seem to be very large:
set terminal epslatex standalone
set output 'label-offset.tex'
set format y '\scriptsize %g'
set ylabel 'ylabel'
plot x
set output
system('latex label-offset.tex && dvips label-offset.dvi && ps2pdf label-offset.ps')
Gnuplot version 4.2.6 doesn't consider the \scriptsize at all and you need a very large offset to compensate it: set ylabel 'ylabel' offset 14.
Since versoin 4.4 the behaviour is better, you need an much lower offset: set ylabel 'ylabel' offset 4.
Some remarks:
\scriptsize is a switch and doesn't take an argument. Consider set xlabel '\scriptsize{scriptsize} normal?'. To limit its effect, surround the text with brackets, like {\scriptsize %g}. But that is not necessary for tic labels, since they are in any case put in brackets.
To have italic text, use \textit{label name 1}, and not the math mode with $-signs.

Resources