gnuplot: How to align multiplots relative to axes coordinates?

て烟熏妆下的殇ゞ 提交于 2021-02-05 11:21:22

问题


From this question it turned out that in some cases it might be desirable to align a subplot relative to another's plot axes coordinates.

If you check the gnuplot documentation, you will find that labels, arrows, objects (rectangles, polygons, circles, ...) can be positioned in different coordinate systems, i.e. axes, graph and screen (see help coordinates). Subplots in a multiplot environment, however, (as far as I know) can only be aligned and sized relative to the screen, see help origin and help size. Of course, you could always fiddle around with screen coordinates to find the desired positions, but when the size of the terminal or plot, axis labels or automargins might change you will have to start over again.

Question: How to align a subplot relative to the coordinates of another plot?


回答1:


Aligning a subplot relative to another's plot coordinates is basically a "simple" transformation of coordinates, however, it's not too obvious how to do this in gnuplot. I haven't found an example on the gnuplot homepage or elsewhere (this shouldn't mean it doesn't maybe exist somewhere), so I would like to share a way which should make life easier and somebody else might find it useful not to have to "reinvent the wheel".

Code:

### multiplots relative to other plots' axes coordinates
reset session

# function to store the current terminal values for later use
GetPlotParams(n) = sprintf("%g %g %g %g %g %g %g %g", \
                   GPVAL_X_MIN, \
                   GPVAL_X_MAX-GPVAL_X_MIN, \
                   GPVAL_Y_MIN, \
                   GPVAL_Y_MAX-GPVAL_Y_MIN, \
                   real(GPVAL_TERM_XMIN)/GPVAL_TERM_XSIZE*GPVAL_TERM_SCALE, \
                   real(GPVAL_TERM_YMIN)/GPVAL_TERM_YSIZE*GPVAL_TERM_SCALE, \
                   real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/GPVAL_TERM_XSIZE*GPVAL_TERM_SCALE, \
                   real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/GPVAL_TERM_YSIZE*GPVAL_TERM_SCALE ) \
                   # real() in order to avoid integer division

PosX(s,x)   = word(s,5)+word(s,7)*(x-word(s,1))/word(s,2)     # screen position of the subplot
PosY(s,y)   = word(s,6)+word(s,8)*(y-word(s,3))/word(s,4)
SizeX(s,dx) = word(s,7)*dx/word(s,2)                          # screen size of a subplot 
SizeY(s,dy) = word(s,8)*dy/word(s,4)

set multiplot 

    set title "First plot"
    set xtics 1
    set yrange[-100:100]
    set ytics 20
    set grid xtics, ytics
    plot 25*sin(2*x)/x+10 w l lw 2 notitle
    mp1 = GetPlotParams(0)      # store parameters of 1st plot

    # set white background for future plots
    set object 1 rect from graph 0, graph 0 to graph 1, graph 1 behind fc "white"
    set margins 0,0,0,0

    unset xlabel
    set format x ""
    unset ylabel
    set format y ""
    set grid x2tics, ytics

    # second plot
    set title "2^{nd} plot at -9,30 rel. to first plot" offset 0,-0.5
    set origin PosX(mp1,-9),PosY(mp1,30)        # relative to plot1
    set size SizeX(mp1,5),SizeY(mp1,50)         # relative to plot1
    plot 50*sin(x) w l lc "red" notitle
    mp2 = GetPlotParams(0)   # store parameters of 2nd plot

    # third plot
    set title "3^{rd} plot at 4,30 rel. to first"
    set origin PosX(mp1,4),PosY(mp1,30)         # relative to plot1
    set size SizeX(mp1,5),SizeY(mp1,50)         # relative to plot1
    set format y ""
    plot 50*cos(x)+20*sin(2*x) w l lc "magenta" notitle
    mp3 = GetPlotParams(0)   # store parameters of 3rd plot
    
    # fourth plot
    set title "4^{th} plot from 2^{nd} x=0 to 3^{nd} x=0"
    set origin PosX(mp2,0),PosY(mp1,-80)             # relative to plot1 and plot2
    set size PosX(mp3,0)-PosX(mp2,0),SizeY(mp1,60)   # relative to plot1, plot2 and plot3
    set xrange [*:*]
    set format x
    set yrange[*:*]
    set format y
    plot x**2 w l lc "green" notitle
    mp4 = GetPlotParams(0)   # store parameters of 4th plot
    
    # fifth plot
    set title "5^{th} plot" offset 0,-1
    set origin PosX(mp4,-4),PosY(mp4,20)     # relative to plot4
    set size SizeX(mp1,5),SizeY(mp4,60)      # relative to plot1 and plot4
    set format x ""
    set format y ""
    plot (int(2*x)%5)*8 w l lc "blue" notitle
    mp5 = GetPlotParams(0)
 
unset multiplot
### end of code

Result: (actually, a nonsense plot just for illustration. Terminal: set term wxt size 650,480)



来源:https://stackoverflow.com/questions/65640035/gnuplot-how-to-align-multiplots-relative-to-axes-coordinates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!