Search code examples
gnuplotmargins

Setting margins in gnuplot with respect to graph coordinates and not screen


I am trying to plot a second plot inside of my main one. I have specific coordinates for where I would like to place my second plot with respect to the first plot. For example, I want the left margin of the second plot to be on the x=2 line, the right margin to be on the x=8 line and so on as seen on the example image. Currently, I accomplish this by trial and error. I place the margins of the second plot manually until I am satisfied with their locations. However this is time consuming and I am sure there is a smarter way of doing it.

enter image description here


Solution

  • You could impose prescribed margins (in screen units) on the parent plot and then calculate the margins (also in screen units) of the inset from known x/y ranges of the parent plot and required inset position:

    set terminal pngcairo enhanced font ",16"
    set output "fig.png"
    
    fig_lmargin = 0.2
    fig_rmargin = 0.9
    fig_bmargin = 0.2
    fig_tmargin = 0.9
    
    p1_xMin = 0.
    p1_xMax = 10.
    p1_yMin = 0.
    p1_yMax = 1.
    
    p2_xMin = 0.
    p2_xMax = 0.7
    p2_yMin = 0.
    p2_yMax = 1.
    
    inset_xMin = 2.
    inset_xMax = 8.
    inset_yMin = 0.25
    inset_yMax = 0.75
    
    set multiplot
    
    set lmargin at screen fig_lmargin
    set rmargin at screen fig_rmargin
    set tmargin at screen fig_tmargin
    set bmargin at screen fig_bmargin
    
    set xr [p1_xMin:p1_xMax]
    set yr [p1_yMin:p1_yMax]
    
    set linetype 42 lc rgb '#333333' dt 3
    set arrow from inset_xMin,p1_yMin to inset_xMin,p1_yMax nohead lt 42
    set arrow from inset_xMax,p1_yMin to inset_xMax,p1_yMax nohead lt 42
    set arrow from p1_xMin,inset_yMin to p1_xMax,inset_yMin nohead lt 42
    set arrow from p1_xMin,inset_yMax to p1_xMax,inset_yMax nohead lt 42
    
    plot x
    
    p1_widthScreen = fig_rmargin - fig_lmargin
    p1_widthPlot = p1_xMax - p1_xMin
    p1_heightScreen = fig_tmargin - fig_bmargin
    p1_heightPlot = p1_yMax - p1_yMin
    
    unset arrow
    
    set lmargin at screen fig_lmargin + (inset_xMin - p1_xMin)/p1_widthPlot*p1_widthScreen
    set rmargin at screen fig_lmargin + (inset_xMax - p1_xMin)/p1_widthPlot*p1_widthScreen
    set bmargin at screen fig_bmargin + (inset_yMin - p1_yMin)/p1_heightPlot*p1_heightScreen
    set tmargin at screen fig_bmargin + (inset_yMax - p1_yMin)/p1_heightPlot*p1_heightScreen
    
    plot x
    

    enter image description here

    EDIT:

    Using the technique outlined in the answer linked by @Christoph, one can simplify the script above as:

    set terminal pngcairo enhanced font ",16"
    set output "fig.png"
    
    xMin = 0.
    xMax = 10.
    yMin = 0.
    yMax = 1.
    
    inset_xMin = 2.
    inset_xMax = 8.
    inset_yMin = 0.25
    inset_yMax = 0.75
    
    set multiplot
    
    set xr [xMin:xMax]
    set yr [yMin:yMax]
    
    set linetype 42 lc rgb '#333333' dt 3
    set arrow from inset_xMin,yMin to inset_xMin,yMax nohead lt 42
    set arrow from inset_xMax,yMin to inset_xMax,yMax nohead lt 42
    set arrow from xMin,inset_yMin to xMax,inset_yMin nohead lt 42
    set arrow from xMin,inset_yMax to xMax,inset_yMax nohead lt 42
    
    plot x
    
    lmargin = GPVAL_TERM_SCALE * GPVAL_TERM_XMIN / (1.*GPVAL_TERM_XSIZE)
    rmargin = GPVAL_TERM_SCALE * GPVAL_TERM_XMAX / (1.*GPVAL_TERM_XSIZE)
    bmargin = GPVAL_TERM_SCALE * GPVAL_TERM_YMIN / (1.*GPVAL_TERM_YSIZE)
    tmargin = GPVAL_TERM_SCALE * GPVAL_TERM_YMAX / (1.*GPVAL_TERM_YSIZE)
    
    widthScreen = rmargin - lmargin
    heightScreen = tmargin - bmargin
    widthPlot = xMax - xMin
    heightPlot = yMax - yMin
    
    unset arrow
    
    set lmargin at screen lmargin + (inset_xMin - xMin)/widthPlot*widthScreen
    set rmargin at screen lmargin + (inset_xMax - xMin)/widthPlot*widthScreen
    set bmargin at screen bmargin + (inset_yMin - yMin)/heightPlot*heightScreen
    set tmargin at screen bmargin + (inset_yMax - yMin)/heightPlot*heightScreen
    
    set xr [0:0.7]
    set yr [0:1.0]
    
    plot x