1

I've used the following script to generate a plot and the result is shown in the figure below. It is hard to see, but the xlabel, ylabel, title and tic numbers have actually been drawn over and over again each time a plot function was called while in multiplot. In ideas how I can avoid this and just plot the graph without anything else? If I unset the title, tics etc and then plot, then the graph does not plot in the same area as the frame and petrudes into where the left y-axis is.

#set datafile separator ' '
set samples 1000

set term tikz size 17cm,10cm dashed
set out 'MosfetClassAbPower.tex'

unset key

set border lw 2

set style fill transparent solid 0.5 noborder

set title 'MOSFET $\mathrm{I_D}$ Vs Time'
set ylabel 'Drain Current [$\mu$A]'
set xlabel 'Time [ms]'

set xrange [0:4]
set xtics 0,0.5,4
set mxtics 4

set yrange [-50:450]
set mytics 4

set rmargin 5
set label 1 '\SI{60}{\micro\ampere}' at 4.02,60


set multiplot

set grid mxtics mytics lt -1 lc rgb 'gray90'
plot NaN notitle
unset grid

set grid xtics ytics lt -1 lc rgb 'gray70'
plot NaN notitle
unset grid

plot NaN notitle

Id(x) = 347*sin(2*3.14*x) + 60
ID(x) = Id(x) >= 0 ? Id(x) : 0
plot    ID(x) w filledcurves above y1=0 lc rgb 'light-blue',\
        60 w lines lt 2 lw 3 lc rgb 'gray60',\
        ID(x) w lines lt 1 lw 5 lc rgb 'navy'

plot NaN notitle

unset multiplot


set out

result

My attempt at preventing the curve from protruding over the frame. Edit:

reset

#set term tikz size 17cm,10cm dashed standalone header '\usepackage{siunitx}'
#set out 'MosfetClassAbPower.tex'
#TSCALE = 1.0

set terminal pdfcairo dashed
set out 'MosfetClassAbPowerFixed.pdf'
TSCALE = 20.0 # use this value for e.g. pdfcairo or cairolatex

TITLE = 'MOSFET $I_D$ Vs Time'
YLABEL = 'Drain Current (in \si{\uA})'
XLABEL = 'Time (in \si{\ms})'

set style fill transparent solid 0.5 noborder

set xrange [0:4]
set xtics 0,0.5,4
set mxtics 4

set yrange [-50:450]
set mytics 4

set rmargin 5
LABEL = '\SI{60}{\uA}'
set label 1 LABEL at graph 1.01, first 60

unset key
set samples 1000

set multiplot

set title TITLE
set ylabel YLABEL
set xlabel XLABEL
unset border
set tics scale 0,0.001
set grid mxtics mytics lt -1 lc rgb 'gray90'
plot NaN
unset grid

# keep the current margins for all following plots
set lmargin at screen TSCALE*GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE)
set rmargin at screen TSCALE*GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE)
set tmargin at screen TSCALE*GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE)
set bmargin at screen TSCALE*GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE)

# unset almost everything
unset border
unset label
unset xlabel
unset ylabel
set format x ''
set format y ''
unset title

set grid xtics ytics lt -1 lc rgb 'gray70'
plot NaN
unset grid

Id(x) = 347*sin(2*3.14*x) + 60
ID(x) = Id(x) >= 0 ? Id(x) : 0
plot    ID(x) w filledcurves above y1=0 lc rgb 'light-blue',\
        60 w lines lt 2 lw 3 lc rgb 'gray60',\
        ID(x) w lines lt 1 lw 5 lc rgb 'navy'

# overdraw borders on left, right, top, bottom
set object 1 rectangle from screen 0, screen 0 to graph 0, screen 1 back \
  fillstyle solid noborder
set object 2 rectangle from graph 1, screen 0 to screen 1, screen 1 back \
  fillstyle solid noborder
set object 3 rectangle from screen 0, graph 1 to screen 1, screen 1 back \
  fillstyle solid noborder
set object 4 rectangle from screen 0, screen 0 to screen 1, graph 0 back \
  fillstyle solid noborder
plot NaN
unset object 1
unset object 2
unset object 3
unset object 4

set title TITLE
set ylabel YLABEL
set xlabel XLABEL
set label 1 LABEL at graph 1.01, first 60
set format x
set format y
set tics scale 1,0.5 front
set border
set border lw 2
plot NaN

unset multiplot
set out
Jean-Luc
  • 3,563
  • 8
  • 40
  • 78

1 Answers1

2

It is not possible, to set different layers for all plot elements and stack them arbitrarily. You must play around with set and unset for the various elements.

  1. In order to have the tics drawn only once, I set their scale to 0 (this works for the major tics, but not for the minor tics, where I use 0.001).

  2. I fix the margins after the minor grid lines are drawn (see Gnuplot: Store plot area dimensions for later use).

  3. Unset everything, which shouldn't be drawn again (label, object, arrow, tics labels etc). Do not unset tics, because we want to drawn them last, so just use set format x '' to draw the tics, but not their labels.

  4. Set the tics to their default scale, and set the border before the last plot, to have them drawn above the grid lines and above the plot.

    reset
    set term tikz size 17cm,10cm dashed standalone header '\usepackage{siunitx}'
    set out 'MosfetClassAbPower.tex'
    TSCALE = 1.0
    
    # set terminal pdfcairo
    # TSCALE = 20.0 # use this value for e.g. pdfcairo or cairolatex
    
    set style fill transparent solid 0.5 noborder
    
    set title 'MOSFET $I_D$ Vs Time'
    set ylabel 'Drain Current (in \si{\uA})'
    set xlabel 'Time (in \si{\ms})'
    
    set xrange [0:4]
    set xtics 0,0.5,4
    set mxtics 4
    
    set yrange [-50:450]
    set mytics 4
    
    set rmargin 5
    set label 1 '\SI{60}{\uA}' at graph 1.01, first 60
    
    unset key
    set samples 1000
    
    set multiplot
    
    unset border
    set tics scale 0,0.001
    set grid mxtics mytics lt -1 lc rgb 'gray90'
    plot NaN
    unset grid
    
    # keep the current margins for all following plots
    set lmargin at screen TSCALE*GPVAL_TERM_XMIN/(1.0*GPVAL_TERM_XSIZE)
    set rmargin at screen TSCALE*GPVAL_TERM_XMAX/(1.0*GPVAL_TERM_XSIZE)
    set tmargin at screen TSCALE*GPVAL_TERM_YMAX/(1.0*GPVAL_TERM_YSIZE)
    set bmargin at screen TSCALE*GPVAL_TERM_YMIN/(1.0*GPVAL_TERM_YSIZE)
    
    # unset almost everything
    unset border
    unset label
    unset xlabel
    unset ylabel
    set format x ''
    set format y ''
    unset title
    
    set grid xtics ytics lt -1 lc rgb 'gray70'
    plot NaN
    unset grid
    
    set tics scale 1,0.5 front
    set border
    set border lw 2
    
    Id(x) = 347*sin(2*3.14*x) + 60
    ID(x) = Id(x) >= 0 ? Id(x) : 0
    plot    ID(x) w filledcurves above y1=0 lc rgb 'light-blue',\
            60 w lines lt 2 lw 3 lc rgb 'gray60',\
            ID(x) w lines lt 1 lw 5 lc rgb 'navy'
    
    unset multiplot
    set out
    

Result:

enter image description here

Now the ordering is:

  1. minor grid lines
  2. major grid lines
  3. curve
  4. border, tics

Note, that I made some other tiny changes: You can use e.g. graph coordinates to set a label. And some tweaking of the label text.

EDIT:

Cairolatex or epslatex

The proceeding described above works well for any terminal which processes text and graphics together, but not for terminals like cairolatex and epslatex which also in multiplot mode know only two text layer:

  1. front layer, contains all text placed with front keyword.
  2. graphics, contains all graphical elements of all plot commands (also in multiplot mode).
  3. back layer, contains all text placed with back keyword.

This may become a problem, when one wants to cover parts of the graphic (protruding lines) with a white object, but cannot put e.g. the xlabel to the front. Here is an example, which works also with cairolatex:

reset

set terminal cairolatex pdf dashed color standalone header "\\usepackage{siunitx}" size 17cm,10cm
set output 'MosfetClassAbPowerFixed.tex'

TITLE = 'MOSFET $I_D$ Vs Time'
YLABEL = 'Drain Current (in \si{\uA})'
XLABEL = 'Time (in \si{\ms})'

set style fill transparent solid 0.5 noborder

set xrange [0:4]
set xtics 0,0.5,4
set mxtics 4
set yrange [-50:450]
set mytics 4

RMARGIN=0.92
LMARGIN=0.1
set rmargin at screen RMARGIN
set lmargin at screen LMARGIN
set tmargin at screen 0.91
set bmargin at screen 0.11

unset key
set samples 1000

set multiplot

# first plot the minor grid lines
unset border
set tics scale 0,0.001 format ''
set grid mxtics mytics lt -1 lc rgb 'gray90'
plot NaN

# now plot the major grid lines
unset grid
set grid xtics ytics lt -1 lc rgb 'gray70'
plot NaN
unset grid

# plot the actual curve
# overdraw borders on left and right
set object rectangle from graph -0.005, graph 0 to screen LMARGIN, graph 1 front \
  fillstyle solid noborder
set object rectangle from screen RMARGIN, graph 0 to graph 1.005, graph 1 front \
  fillstyle solid noborder
Id(x) = 347*sin(2*3.14*x) + 60
ID(x) = Id(x) >= 0 ? Id(x) : 0
plot    ID(x) w filledcurves above y1=0 lc rgb 'light-blue',\
        60 w lines lt 2 lw 3 lc rgb 'gray60',\
        ID(x) w lines lt 1 lw 5 lc rgb 'navy'

unset object
# plot all tics and labels
LABEL = '\SI{60}{\uA}'
set label 1 LABEL at graph 1.01, first 60 front
set title TITLE
set ylabel YLABEL
set xlabel XLABEL
set tics scale 1,0.5 format
set border
set border lw 2

plot NaN

unset multiplot
set out

Because of the only three layer, I put thin white rectangles between the plot border and the tic labels. To have the objects drawn outside the plotting area, one needs to use at least one coordinate value in screen coordinates, otherwise they are clipped.

As opposed the the first example, I used fixed margins for the whole plot, which I prefer.

This gives:

enter image description here

Community
  • 1
  • 1
Christoph
  • 47,569
  • 8
  • 87
  • 187
  • I did the `multiplot` so that the major lines end up painted on top of the minor lines rather than the other way round. My question is actually specifically about how I can use `multiplot` and get it to work. `multiplot` lets me paint things in the order I want. I am aware of the way you did it, but it doesn't order the grid lines properly. Is there a way to draw a curve in multiplot without drawing all the labels (and without having to unset them all to avoid drawing all the labels)? – Jean-Luc Oct 02 '13 at 09:42
  • 1
    @user968243 See the edited answer. It requires a bit of fiddling to have all elements on different layers in custom order. It is not possible out-of-the-box to have all plot elements arranged in custom order. – Christoph Oct 02 '13 at 10:59
  • Okay great! Thanks! I think you forgot `unset title` after `# unset almost everything`. Also, I noticed that your solution doesn't seem compatible with other terminals, namely, `pdfcairo` and `cairolatex`. The graph draws in the bottom left-hand corner for some reason. Any idea how it could be made compatible with these terminals? Thanks so much again! – Jean-Luc Oct 02 '13 at 15:35
  • 1
    @user968243 Some terminals scale the `GPVAL_TERM_*MIN` and `GPVAL_TERM_*MAX` values by an oversampling factor, but not the `GPVAL_TERM_*SIZE` values. This factor is not accessible as `GPVAL_*` variable. It can be checked for, but becomes lengthy, see my edit to [Gnuplot: Store plot area dimensions for later use](http://stackoverflow.com/a/19132068/2604213). In your case (`pdfcairo` or `cairolatex`) you need to scale all margins by a factor `20`, see my edit. – Christoph Oct 02 '13 at 18:30
  • Thanks so much for this! As a last thing, I posted my attempt at making sure that thick curves do not protrude the frame, I did this using the advice from another question about creating an object to cover it. I've posted the code above. I don't really like the solution though, and was wondering if you knew of a better way; furthermore, it it doesn't work with the cairolatex terminal (but does work with TikZ and pdfcairo). Thanks so much again! I think this is the last picky question I'll have! – Jean-Luc Oct 06 '13 at 04:09
  • 1
    @user968243 `cairolatex` and `epslatex` terminal work a bit differently. This is important, when layering things, see my edit. – Christoph Oct 07 '13 at 10:55