【发布时间】:2015-07-22 22:54:08
【问题描述】:
如果我使用多个列来显示我的子图,如何动态地将新图添加到一堆子图中? This 为一列回答了这个问题,但我似乎无法修改那里的答案以使其动态添加到带有 x 列的子图中
我修改了Sadarthrion's answer 并尝试了以下操作。在这里,为了举例,我制作了number_of_subplots=11 和num_cols = 3。
import matplotlib.pyplot as plt
def plotSubplots(number_of_subplots,num_cols):
# Start with one
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3])
for j in range(number_of_subplots):
if j > 0:
# Now later you get a new subplot; change the geometry of the existing
n = len(fig.axes)
for i in range(n):
fig.axes[i].change_geometry(n+1, num_cols, i+1)
# Add the new
ax = fig.add_subplot(n+1, 1, n+1)
ax.plot([4,5,6])
plt.show()
plotSubplots(11,3)
如您所见,这并没有给我想要的东西。第一个图占据了所有列,其他图小于它们应有的值
编辑:
('2.7.6 | 64-bit | (default, Sep 15 2014, 17:36:35) [MSC v.1500 64 bit (AMD64)]'
我还有 matplotlib 1.4.3 版:
import matplotlib as mpl
print mpl.__version__
1.4.3
我在下面尝试了 Paul 的回答并收到以下错误消息:
import math
import matplotlib.pyplot as plt
from matplotlib import gridspec
def do_plot(ax):
ax.plot([1,2,3], [4,5,6], 'k.')
N = 11
cols = 3
rows = math.ceil(N / cols)
gs = gridspec.GridSpec(rows, cols)
fig = plt.figure()
for n in range(N):
ax = fig.add_subplot(gs[n])
do_plot(ax)
fig.tight_layout()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-f74203b1c1bf> in <module>()
15 fig = plt.figure()
16 for n in range(N):
---> 17 ax = fig.add_subplot(gs[n])
18 do_plot(ax)
19
C:\Users\user\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\figure.pyc in add_subplot(self, *args, **kwargs)
962 self._axstack.remove(ax)
963
--> 964 a = subplot_class_factory(projection_class)(self, *args, **kwargs)
965
966 self._axstack.add(key, a)
C:\Users\user\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\axes\_subplots.pyc in __init__(self, fig, *args, **kwargs)
73 raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
74
---> 75 self.update_params()
76
77 # _axes_class is set in the subplot_class_factory
C:\Users\user\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\axes\_subplots.pyc in update_params(self)
113 self.figbox, self.rowNum, self.colNum, self.numRows, self.numCols = 114 self.get_subplotspec().get_position(self.figure,
--> 115 return_all=True)
116
117 def is_first_col(self):
C:\Users\user\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\gridspec.pyc in get_position(self, fig, return_all)
423
424 figBottoms, figTops, figLefts, figRights = --> 425 gridspec.get_grid_positions(fig)
426
427
C:\Users\user\AppData\Local\Enthought\Canopy\User\lib\site-packages\matplotlib\gridspec.pyc in get_grid_positions(self, fig)
103 cellHeights = [netHeight*r/tr for r in self._row_height_ratios]
104 else:
--> 105 cellHeights = [cellH] * nrows
106
107 sepHeights = [0] + ([sepH] * (nrows-1))
TypeError: can't multiply sequence by non-int of type 'float'
【问题讨论】:
-
在这种情况下正确的输出应该是什么样的?
-
哦,对不起,我认为这很明显。我只想平铺所有地块并尽可能多地占用窗口空间。所以在上面的例子中,我希望出现在底部的图出现在第二列中。最后一组子图应显示为 4x3(4 行,3 列)网格,最后有一个空白区域(因为我们只有 11 个图)
-
你知道先验的列数和总图数吗?
-
图的总数是从一个全局且恒定的列表的长度得知的,但其长度可能因初始化而不同。列数由用户控制。这有什么改变吗?两者都是变量。我修改了问题。我觉得现在更清楚了
-
看我的回答。我担心关于列数或绘图总数的知识来自比如说,一个可能在绘图中途改变的 GUI 事件。那时事情会复杂得多。
标签: python matplotlib