Gnuplot multiplot: Convenient method for creating more complex layouts

冷暖自知 提交于 2020-01-14 15:06:54

问题


I want to place several plots with gnuplot in following way:

 +------------------------+
 |plot1                   |
 |                        |
 +------------------------+
 +----------++------------+
 |plot2     ||plot3       |
 |          ||            |
 +----------++------------+
 +----------++------------+
 |plot4     ||plot5       |
 |          ||            |
 +----------++------------+

Simple nxm layouts can be achieved via set multiplot layout n,m (see these demos for illustration on the official website).

matplotlib offers much more advanced possibilites as you can see in the documentation: Customizing Location of Subplot Using GridSpec.

Within gnuplot I have used set origin and set size to achieve this. However, it is rather cumbersome and requires recalculation of sizes and positions when you notice you want to change the layout afterwards.

Remark 1: Often it is also useful to set the margins to fixed sizes to achieve the correct plot sizes. The auto-calculation by varying xlabels and so on would make it otherwise even more difficult to achieve the correct layout.

Remark 2: Instead of origin/size gnuplot offers another possibility using set [lrbt]margin <> at screen which sets plot borders. The user has to make sure that there is enough space for titles and labels (see demo). Still not a perfect solution but sometimes more convenient.

Is there a possibility that I am not aware of or does possibly a tool exist to create layouts?


回答1:


You can get geometry from matplotlib. Create two file subplot2grid2gnuplot.py and subplot2grid.gp. test.gp is an example of usage.

subplot2grid2gnuplot.py

import matplotlib.pyplot as plt
import sys

if len(sys.argv)<6:
    sys.stderr.write("ERROR: subplot2grid2gnuplot.py needs 6 arguments\n")
    sys.exit(1)

shape = (int(float(sys.argv[1])), int(float(sys.argv[2])))
loc   = (int(float(sys.argv[3])), int(float(sys.argv[4])))
colspan = int(float(sys.argv[5]))
rowspan = int(float(sys.argv[6]))

ax = plt.subplot2grid(shape, loc, colspan, rowspan)
print "%f %f %f %f" % ax._position.bounds

subplot2grid.gp

# Return origin and size of the subplot
# Usage:
# call subplot2grid.gp shape1 shape1 loc1 loc2 colspan rowspan
# Sets:
# or1, or2, size1, size2

aux_fun__(shape1, shape2, loc1, loc2, colspan, rowspan) = \
   system(sprintf("python subplot2grid2gnuplot.py  %i %i %i %i %i %i %i", shape1, shape2, loc1, loc2, colspan, rowspan))

aux_string__= aux_fun__($0, $1, $2, $3, $4, $5)
or1=word(aux_string__,1)
or2=word(aux_string__,2)
size1=word(aux_string__,3)
size2=word(aux_string__,4)

test.gp

unset xtics
unset ytics

set multiplot

call "subplot2grid.gp" 3 3 0 0 1 3
set size size1, size2
set origin or1, or2
plot sin(x)

call "subplot2grid.gp" 3 3 1 0 1 2
set size size1, size2
set origin or1, or2
plot sin(x)

call "subplot2grid.gp" 3 3 1 2 2 1
set size size1, size2
set origin or1, or2
plot sin(x)

call "subplot2grid.gp" 3 3 2 0 1 1
set size size1, size2
set origin or1, or2
plot sin(x)

call "subplot2grid.gp" 3 3 2 1 1 1
set size size1, size2
set origin or1, or2
plot sin(x)

unset multiplot




回答2:


A working minimal example for the given layout as mentioned in the comment.

set term pngcairo size 5.0in,6.0in
set output "test_layout.png"
ROWS=3
COLS=2
set multiplot layout ROWS,COLS upwards
plot sin(4*x) # plot 4
plot sin(5*x) # plot 5
plot sin(2*x) # plot 2
plot sin(3*x) # plot 3
set size 1,(1.0/ROWS)
plot sin(1*x) # plot 1:
unset multiplot

This solution works as long as only the first (last) row is different, everything else follows the nxm scheme. But for example you cannot specify easily a different height for the first row.

$ gnuplot -d file.gp:

However, I am still interested in other methods tackling the problem in general.



来源:https://stackoverflow.com/questions/15904719/gnuplot-multiplot-convenient-method-for-creating-more-complex-layouts

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