Nice multiplots in Gnuplot

LTspice simulation results of the LED driver circuit

I really like Gnuplot. For the last 13 years I have made almost all plots with this great program which gives me full control…

…or at least almost…

You should not complain about short-comings in Gnuplot: it’s for free and you should be grateful for every single line of code which was put down by the volunteers of the Gnuplot-team!!!

For a long time it has been possible to create multiplots in Gnuplot, and lately this functionality was enhanced with additional functions. However, it simply did not do, what I expected. Perhaps my expectations and my understanding of the functionality were wrong – I don’t know. All I wanted originally was a stack of equally sized subplots were I easily could adjust the overall framing, the labeling and tic marks and so on.

So now I put down a template for my own purposes, but perhaps someone else might find it useful as well – if so, please leave a comment below… The template is based on the enhanced postscript terminal, but it should be possible to easily adjust it even to pixel-based terminals, such as PNG:

mpl_top    = 0.4 #inch  outer top margin, title goes here
mpl_bot    = 0.7 #inch  outer bottom margin, x label goes here
mpl_left   = 0.9 #inch  outer left margin, y label goes here
mpl_right  = 0.1 #inch  outer right margin, y2 label goes here
mpl_height = 1.5 #inch  height of individual plots
mpl_width  = 2.0 #inch  width of individual plots
mpl_dx     = 0.1 #inch  inter-plot horizontal spacing
mpl_dy     = 0.1 #inch  inter-plot vertical spacing
mpl_ny     = 3   #number of rows
mpl_nx     = 2   #number of columns

# calculate full dimensions
xsize = mpl_left+mpl_right+(mpl_width*mpl_nx)+(mpl_nx-1)*mpl_dx
ysize = mpl_top+mpl_bot+(mpl_ny*mpl_height)+(mpl_ny-1)*mpl_dy

# placement functions
#   rows are numbered from bottom to top
bot(n) = (mpl_bot+(n-1)*mpl_height+(n-1)*mpl_dy)/ysize
top(n)  = 1-((mpl_top+(mpl_ny-n)*(mpl_height+mpl_dy))/ysize)
#   columns are numbered from left to right
left(n) = (mpl_left+(n-1)*mpl_width+(n-1)*mpl_dx)/xsize
right(n)  = 1-((mpl_right+(mpl_nx-n)*(mpl_width+mpl_dx))/xsize)

set terminal postscript eps enhanced color dl 2.0 size xsize,ysize "Helvetica" 28
set encoding iso_8859_1
set tics scale 1.5

set output 'nxm_plot.eps'

set offsets
set autoscale fix
set size 1,1
set nokey

# define x-axis settings for all subplots
set xrange [-4:4]
set xlabel ''
set format x ''
set xtics pi
set mxtics 4

# start plotting
set multiplot

#-----------------------------------------------
# subplot  1-3
#  set horizontal margins for first column
set lmargin at screen left(1)
set rmargin at screen right(1)
#  set horizontal margins for third row (top)
set tmargin at screen top(3)
set bmargin at screen bot(3)

set title 'left'

set ylabel "amplitude"
set yrange [-1.5:1.5]
set format y "%-2.1f"
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
sin(x) \
axes x1y1 \
title '' \
with lines lt 1 lc 1 lw 2\
;

#-----------------------------------------------
# subplot  2-3
#  set horizontal margins for second column
set lmargin at screen left(2)
set rmargin at screen right(2)
#  set horizontal margins for third row (top)
set tmargin at screen top(3)
set bmargin at screen bot(3)

set title 'right'

set ylabel ""             # no label here
set yrange [-1.5:1.5]
set format y ""           # no tic labels
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
cos(x) \
axes x1y1 \
title '' \
with lines lt 1 lc 2 lw 2\
;

#-----------------------------------------------
# subplot  1-2
#  set horizontal margins for first column
set lmargin at screen left(1)
set rmargin at screen right(1)
#  set horizontal margins for second row (middle)
set tmargin at screen top(2)
set bmargin at screen bot(2)

set title ''

set ylabel "amplitude"
set yrange [-1.5:1.5]
set format y "%-1.1f"
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
-sin(x) \
axes x1y1 \
title '' \
with lines lt 1 lc 3 lw 2\
;

#-----------------------------------------------
# subplot  2-2
#  set horizontal margins for second column
set lmargin at screen left(2)
set rmargin at screen right(2)
#  set horizontal margins for second row (middle)
set tmargin at screen top(2)
set bmargin at screen bot(2)

set title ''

set ylabel ""             # no label here
set yrange [-1.5:1.5]
set format y ""           # no tic labels
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
-cos(x) \
axes x1y1 \
title '' \
with lines lt 1 lc 4 lw 2\
;

#-----------------------------------------------
# subplot  1-2
#  set horizontal margins for first column
set lmargin at screen left(1)
set rmargin at screen right(1)
#  set horizontal margins for first row (bottom)
set tmargin at screen top(1)
set bmargin at screen bot(1)

set title ''

# now set a label and tic marks for the x-axis
set xlabel "phase angle"
set xtics add ("-{/Symbol p}" -pi, "0" 0, "{/Symbol p}" pi)

set ylabel "amplitude"
set yrange [0:1.5]
set format y "%-1.1f"
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
(sin(x))**2 \
axes x1y1 \
title '' \
with lines lt 1 lc 5 lw 2\
;

#-----------------------------------------------
# subplot  2-2
#  set horizontal margins for second column
set lmargin at screen left(2)
set rmargin at screen right(2)
#  set horizontal margins for first row (bottom)
set tmargin at screen top(1)
set bmargin at screen bot(1)

set title ''

set ylabel ""             # no label here
set yrange [0:1.5]
set format y ""           # no tic labels
set ytics mirror 1
set mytics 2

set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

plot          \
(cos(x))**2 \
axes x1y1 \
title '' \
with lines lt 1 lc 6 lw 2\
;
unset multiplot

And the output looks like this:
result of the multiplot template

18 comments

  1. It’s an extremely useful post. I helped me. I’m also trying to extend and adapt it to my case of 12 plots in a 4-rows by 3-columns layout. But still I’m not getting things right. I don’t know if you could help.

    1. …and I just made an example to accomodate for 3×4 plots…

      Uwe.

      mpl_top    = 0.4 #inch  outer top margin, title goes here
      mpl_bot    = 0.7 #inch  outer bottom margin, x label goes here
      mpl_left   = 0.9 #inch  outer left margin, y label goes here
      mpl_right  = 0.1 #inch  outer right margin, y2 label goes here
      mpl_height = 1.5 #inch  height of individual plots
      mpl_width  = 2.0 #inch  width of individual plots
      mpl_dx     = 0.1 #inch  inter-plot horizontal spacing
      mpl_dy     = 0.1 #inch  inter-plot vertical spacing
      mpl_ny     = 4   #number of rows
      mpl_nx     = 3   #number of columns

      # calculate full dimensions
      xsize = mpl_left+mpl_right+(mpl_width*mpl_nx)+(mpl_nx-1)*mpl_dx
      ysize = mpl_top+mpl_bot+(mpl_ny*mpl_height)+(mpl_ny-1)*mpl_dy

      # placement functions
      #   rows are numbered from bottom to top
      bot(n) = (mpl_bot+(n-1)*mpl_height+(n-1)*mpl_dy)/ysize
      top(n)  = 1-((mpl_top+(mpl_ny-n)*(mpl_height+mpl_dy))/ysize)
      #   columns are numbered from left to right
      left(n) = (mpl_left+(n-1)*mpl_width+(n-1)*mpl_dx)/xsize
      right(n)  = 1-((mpl_right+(mpl_nx-n)*(mpl_width+mpl_dx))/xsize)

      set terminal postscript eps enhanced color dl 2.0 size xsize,ysize "Helvetica" 28
      set encoding iso_8859_1
      set tics scale 1.5

      set output 'mptest.eps'

      set offsets
      set autoscale fix
      set size 1,1
      set nokey

      # define x-axis settings for all subplots
      set xrange [-4:4]
      set xlabel ''
      set format x ''
      set xtics pi
      set mxtics 4

      # start plotting
      set multiplot

      #========================================================
      #
      #-----------------------------------------------
      # subplot  1-4

      #  set horizontal margins for first column (left)
      set lmargin at screen left(1)
      set rmargin at screen right(1)

      #  set horizontal margins for fourth row (top)
      set tmargin at screen top(4)
      set bmargin at screen bot(4)

      set title 'left'
      set label 1 at graph 0.5, graph 0.5 "x1 - y4"

      #.....................................................
        set ylabel "amplitude"
        set yrange [-1.5:1.5]
        set format y "%-2.1f"
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          sin(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 1 lw 2\
        ;

      #-----------------------------------------------
      # subplot  2-4

      #  set horizontal margins for second column (middle)
      set lmargin at screen left(2)
      set rmargin at screen right(2)

      #  set horizontal margins for fourth row (top)
      set tmargin at screen top(4)
      set bmargin at screen bot(4)

      set title 'middle'
      set label 1 at graph 0.5, graph 0.5 "x2 - y4"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 2 lw 2\
        ;

      #-----------------------------------------------
      # subplot  3-4

      #  set horizontal margins for third column (right)
      set lmargin at screen left(3)
      set rmargin at screen right(3)

      #  set horizontal margins for fourth row (top)
      set tmargin at screen top(4)
      set bmargin at screen bot(4)

      set title 'right'
      set label 1 at graph 0.5, graph 0.5 "x3 - y4"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 2 lw 2\
        ;

      #========================================================
      #
      #-----------------------------------------------
      # subplot  1-3

      #  set horizontal margins for first column (left)
      set lmargin at screen left(1)
      set rmargin at screen right(1)

      #  set horizontal margins for third row (second from top)
      set tmargin at screen top(3)
      set bmargin at screen bot(3)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x1 - y3"

      #.....................................................
        set ylabel "amplitude"
        set yrange [-1.5:1.5]
        set format y "%-2.1f"
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          sin(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 1 lw 2\
        ;

      #-----------------------------------------------
      # subplot  2-3

      #  set horizontal margins for second column (middle)
      set lmargin at screen left(2)
      set rmargin at screen right(2)

      #  set horizontal margins for third row (second from top)
      set tmargin at screen top(3)
      set bmargin at screen bot(3)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x2 - y3"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 2 lw 2\
        ;

      #-----------------------------------------------
      # subplot  3-3
      #  set horizontal margins for third column (right)
      set lmargin at screen left(3)
      set rmargin at screen right(3)

      #  set horizontal margins for third row (second from top)
      set tmargin at screen top(3)
      set bmargin at screen bot(3)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x3 - y3"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 2 lw 2\
        ;

      #========================================================
      #
      #-----------------------------------------------
      # subplot  1-2

      #  set horizontal margins for first column (left)
      set lmargin at screen left(1)
      set rmargin at screen right(1)

      #  set horizontal margins for second row (third from top)
      set tmargin at screen top(2)
      set bmargin at screen bot(2)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x1 - y2"

      #.....................................................
        set ylabel "amplitude"
        set yrange [-1.5:1.5]
        set format y "%-1.1f"
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          -sin(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 3 lw 2\
        ;

      #-----------------------------------------------
      # subplot  2-2

      #  set horizontal margins for second column (middle)
      set lmargin at screen left(2)
      set rmargin at screen right(2)

      #  set horizontal margins for second row (third from top)
      set tmargin at screen top(2)
      set bmargin at screen bot(2)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x2 - y2"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          -cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 4 lw 2\
        ;

      #-----------------------------------------------
      # subplot  3-2

      #  set horizontal margins for third column (right)
      set lmargin at screen left(3)
      set rmargin at screen right(3)

      #  set horizontal margins for second row (third from top)
      set tmargin at screen top(2)
      set bmargin at screen bot(2)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x3 - y2"

      #.....................................................
        set ylabel ""             # no label here
        set yrange [-1.5:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          -cos(x) \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 4 lw 2\
        ;

      #========================================================
      #
      #-----------------------------------------------
      # subplot  1-1

      #  set horizontal margins for first column (left)
      set lmargin at screen left(1)
      set rmargin at screen right(1)

      #  set horizontal margins for second row (third from top)
      set tmargin at screen top(1)
      set bmargin at screen bot(1)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x1 - y1"

      #.....................................................
      # now set a label and tic marks for the x-axis

        set xlabel "phase angle"
        set xtics add ("-{/Symbol p}" -pi, "0" 0, "{/Symbol p}" pi)

        set ylabel "amplitude"
        set yrange [0:1.5]
        set format y "%-1.1f"
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          (sin(x))**2 \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 5 lw 2\
        ;

      #-----------------------------------------------
      # subplot  2-1

      #  set horizontal margins for second column (middle)
      set lmargin at screen left(2)
      set rmargin at screen right(2)

      #  set horizontal margins for first row (bottom)
      set tmargin at screen top(1)
      set bmargin at screen bot(1)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x2 - y1"

      #.....................................................
      # now set a label and tic marks for the x-axis

        set xlabel "phase angle"
        set xtics add ("-{/Symbol p}" -pi, "0" 0, "{/Symbol p}" pi)

        set ylabel ""             # no label here
        set yrange [0:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          (cos(x))**2 \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 6 lw 2\
        ;
      #-----------------------------------------------
      # subplot  3-1

      #  set horizontal margins for third column (right)
      set lmargin at screen left(3)
      set rmargin at screen right(3)

      #  set horizontal margins for first row (bottom)
      set tmargin at screen top(1)
      set bmargin at screen bot(1)

      set title ''
      set label 1 at graph 0.5, graph 0.5 "x3 - y1"

      #.....................................................
      # now set a label and tic marks for the x-axis

        set xlabel "phase angle"
        set xtics add ("-{/Symbol p}" -pi, "0" 0, "{/Symbol p}" pi)

        set ylabel ""             # no label here
        set yrange [0:1.5]
        set format y ""           # no tic labels
        set ytics mirror 1
        set mytics 2

        set arrow 1 from graph 0, first 0 rto graph 1,0 nohead lt 1 lw 1 lc 0
        set arrow 2 from first 0, graph 0 rto 0, graph 1 nohead lt 1 lw 1 lc 0

        plot          \
          (cos(x))**2 \
          axes x1y1 \
          title '' \
          with lines lt 1 lc 6 lw 2\
        ;
       
      #========================================================
      # The End
      #-----------------------------------------------
       
      unset multiplot
  2. brilliant post man. I’m going through your code to modify it for my needs – an animated gif containing disproportionate but aligned subplots.
    just wanted to say thanks, keep up the awesome work 🙂

  3. Thanks so much for this – my plots have turned out great 🙂 +1 gnuplot karma to you my good man.

    1. Thanks for your feedback!

      I now actually use it always and for every single plot myself! Whether multi- or single…

  4. Hi sir, your code is awesome ! This really plot very nice plot. Thank you so much for your effort to produce this script. Hope soon gnuplot come with GUI type of application.

    Best regards
    Vijay

  5. Thank you very much for this clean and easy to use solution! You’ve spared me a lot of tedious fiddling around.

  6. Man, this settings are awesome! I wrote something similar but without generalizing for the number of columns and rows. Simply stunning, thank you very much for sharing!!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.