Is it possible to store the dimensions of the plotting space in gnuplot? I don't mean the whole canvas, rather, the area within the plotting frame.
1 Answers
After a plot
command several gnuplot-defined variables GPVAL_*
are available (type show variables all
) to see the values. Some of them can be used to get the margins of the previous plot:
plot sin(x)
TSCALE = 1.0
LMARGIN = TSCALE*GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE)
RMARGIN = TSCALE*GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE)
TMARGIN = TSCALE*GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE)
BMARGIN = TSCALE*GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE)
To restore the margins later, use
set lmargin at screen LMARGIN
set rmargin at screen RMARGIN
set tmargin at screen TMARGIN
set bmargin at screen BMARGIN
TSCALE
is a factor, which is terminal-dependent, because the GPVAL_TERM_*MIN
and GPVAL_TERM_*MAX
are scaled internally by an oversampling factor, but the GPVAL_TERM_*SIZE
values are not (at least with 4.6.0, 4.6.3 and 4.7 (2013-09-23)). For pdfcairo
this value must be 20
, while for wxt
it is 1
. A rather complete check for different terminals is:
if (GPVAL_TERM eq 'pdfcairo' || \
GPVAL_TERM eq 'cairolatex' || \
GPVAL_TERM eq 'pngcairo' || \
(GPVAL_TERM eq 'postscript' && strstrt(GPVAL_TERMOPTIONS, 'eps ') == 1)) {
TSCALE = 20.0
} else {
if (GPVAL_TERM eq 'svg' || GPVAL_TERM eq 'postscript') {
TSCALE = 10.0
} else {
TSCALE = 1.0
}
}
Since gnuplot 5.0 a separate variable GPVAL_TERM_SCALE
is available which already contains the appropriate value for the selected terminal and make this complex check obsolete.
Automating
There are many ways to automate this. You can e.g. write these definitions in strings and just call eval
on them when you need them:
save_margins = 'TSCALE = 1.0;'\
'LMARGIN = TSCALE*GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE);'.\
'RMARGIN = TSCALE*GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE);'.\
'TMARGIN = TSCALE*GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE);'.\
'BMARGIN = TSCALE*GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE);'
plot sin(x)
eval(save_margins)
print LMARGIN
and accordingly
restore_margins = 'set lmargin at screen LMARGIN;'.\
'set rmargin at screen RMARGIN;'.\
'set tmargin at screen TMARGIN;'.\
'set bmargin at screen BMARGIN'
eval(restore_margins)
Universal usage
To use these features as universal as possible, just put the following in a script e.g. fixed-margins.gp
:
save_margins = 'LMARGIN = TSCALE*GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE);'.\
'RMARGIN = TSCALE*GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE);'.\
'TMARGIN = TSCALE*GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE);'.\
'BMARGIN = TSCALE*GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE);'
restore_margins = 'set lmargin at screen LMARGIN;'.\
'set rmargin at screen RMARGIN;'.\
'set tmargin at screen TMARGIN;'.\
'set bmargin at screen BMARGIN;'
set_fixed_margins = save_margins . restore_margins
if (exists('GPVAL_TERM_SCALE')) {
TSCALE = GPVAL_TERM_SCALE
} else {
if (GPVAL_TERM eq 'pdfcairo' || \
GPVAL_TERM eq 'cairolatex' || \
GPVAL_TERM eq 'pngcairo' || \
(GPVAL_TERM eq 'postscript' && strstrt(GPVAL_TERMOPTIONS, 'eps ') == 1)) {
TSCALE = 20.0
} else {
if (GPVAL_TERM eq 'svg' || GPVAL_TERM eq 'postscript') {
TSCALE = 10.0
} else {
TSCALE = 1.0
}
}
}
To use this feature, just load
the script after having set the terminal, and then eval
the margin string at the appropriate positions in the plot:
set terminal ...
load 'fixed-margins.gp'
set multiplot
plot sin(x)
eval(set_fixed_margins)
....

- 47,569
- 8
- 87
- 187
-
gnuplot 4.4 introduced `GPVAL_TERM_*` variables. In gnuplot 5.0 there is also `GPVAL_TERM_SCALE`. I can confirm for pdfcairo `GPVAL_TERM_SCALE = 20` and for postscript `GPVAL_TERM_SCALE = 10`. – Hotschke May 08 '15 at 10:18
-
@Hotschke Yes, thanks for the addition. I already used this variable in http://stackoverflow.com/a/28888288/2604213 :) I updated the script for universal usage to use this variable, if available. – Christoph May 08 '15 at 10:37