在没有移动位置的情况下重复使用matplotlib中的补丁对象

时间:2011-11-17 11:24:18

标签: python canvas matplotlib patch figure

我想自动生成一系列剪辑到修补程序的图。如果我尝试重用补丁对象,它会在画布上移动位置。

此脚本(基于对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)

第一个情节如下:Correct position of patch - first time plotted

但是在第二个'1.png'中,补丁已经移动了...... Wrong position of the patch

然而,再次重新绘制不会移动补丁。 '2.png'和'3.png'看起来与'1.png'完全相同。

有人能指出我正在做错的方向吗?

实际上,我正在使用的补丁相对复杂并且需要一些时间来生成 - 如果可能的话,我宁愿不必每帧都重新制作它们。

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:2)

unutbu的答案的替代方法是使用copy包,它可以复制对象。在调用add_patch之后很难看出事情是如何变化的,但它们是。修补程序的axesfigureextentsclip_boxtransformwindow_extent属性已更改。不幸的是,每个属性的表面打印都会产生相同的字符串,所以看起来它们并没有改变。但是,部分或全部这些属性的基础属性,例如extentsBbox,可能已更改。

复制调用将允许您为每个人物制作一个独特的补丁,而不知道它是什么类型的补丁。这仍然无法回答为什么会发生这种情况,但正如我上面所写,这是解决问题的另一种方法:

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调用会保存当前数字,这恰好是您想要的数字。