2

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.

Jean-Luc
  • 3,563
  • 8
  • 40
  • 78

1 Answers1

3

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)
....
Christoph
  • 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