在matplotlib中重复使用补丁对象而不改变位置
我想自动生成一系列图形,并且这些图形要被限制在特定的区域内。如果我尝试重复使用一个区域对象,它在画布上的位置就会移动。
这个脚本(基于Yann之前问题的回答)展示了发生了什么。
import pylab as plt
import scipy as sp
import matplotlib.patches as patches
sp.random.seed(100)
x = sp.random.random(100)
y = sp.random.random(100)
patch = patches.Circle((.75,.75),radius=.25,fc='none')
def doplot(x,y,patch,count):
fig = plt.figure()
ax = fig.add_subplot(111)
im = ax.scatter(x,y)
ax.add_patch(patch)
im.set_clip_path(patch)
plt.savefig(str(count) + '.png')
for count in xrange(4):
doplot(x,y,patch,count)
第一个图看起来是这样的:
但是在第二个图'1.png'中,区域的位置就移动了..
不过再次绘制时,区域并没有移动。'2.png'和'3.png'看起来和'1.png'完全一样。
有没有人能告诉我,我哪里做错了??
实际上,我使用的区域比较复杂,生成这些区域需要一些时间——如果可以的话,我希望每一帧都不必重新制作它们。
2 个回答
2
另一种方法是使用 copy
这个包,它可以用来复制对象。调用 add_patch
后,事情的变化很难看出来,但实际上是有变化的。比如,axes
、figure
、extents
、clip_box
、transform
和 window_extent
这些属性都发生了变化。不幸的是,直接打印这些属性的值时,结果都是一样的字符串,所以看起来好像没有变化。但实际上,这些属性的一些底层特征,比如 extents
是一个 Bbox
,可能已经改变了。
使用 copy
可以让你为每个图形创建一个独特的补丁,而不需要知道这个补丁具体是什么类型。虽然这仍然没有解释为什么会这样,但正如我上面所说的,这是一种解决问题的替代方法:
import copy
def doplot(x,y,patch,count):
newPatch = copy.copy(patch)
fig = plt.figure(dpi=50)
ax = fig.add_subplot(111)
im = ax.scatter(x,y)
ax.add_patch(newPatch)
im.set_clip_path(newPatch)
plt.savefig(str(count) + '.png')
另外,你可以使用 fig.savefig(str(count) + '.png')
。这个方法明确地保存了图形 fig
,而 plt.savefig
则是保存当前的图形,恰好是你想要的那个。
2
这个问题可以通过对每个图使用相同的坐标轴来避免。在每次绘图后,调用 ax.cla()
来清空图表。
import pylab as plt
import scipy as sp
import matplotlib.patches as patches
sp.random.seed(100)
patch = patches.Circle((.75,.75),radius=.25,fc='none')
fig = plt.figure()
ax = fig.add_subplot(111)
def doplot(x,y,patch,count):
ax.set_xlim(-0.2,1.2)
ax.set_ylim(-0.2,1.2)
x = sp.random.random(100)
y = sp.random.random(100)
im = ax.scatter(x,y)
ax.add_patch(patch)
im.set_clip_path(patch)
plt.savefig(str(count) + '.png')
ax.cla()
for count in xrange(4):
doplot(x,y,patch,count)