问题
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