2011-11-17 20 views
5

Tôi muốn tự động tạo một chuỗi các ô được cắt bớt thành các bản vá. Nếu tôi cố gắng và tái sử dụng một đối tượng vá, nó di chuyển vị trí trên khung hình.Sử dụng lại các đối tượng vá trong matplotlib mà không cần chúng di chuyển vị trí

Tập lệnh này (dựa trên câu trả lời cho câu hỏi trước của Yann) cho thấy những gì đang xảy ra.

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) 

Cốt truyện đầu tiên trông như thế này: Correct position of patch - first time plotted

Nhưng trong lần thứ hai '1.png', các bản vá đã chuyển .. Wrong position of the patch

Tuy nhiên replotting lại không di chuyển các miếng vá . '2.png' và '3.png' trông giống hệt như '1.png'.

Có ai có thể chỉ cho tôi đúng hướng những gì tôi đang làm sai không ??

Trong thực tế, các bản vá tôi đang sử dụng tương đối phức tạp và mất chút thời gian để tạo - Tôi không muốn phải làm lại chúng mỗi khung nếu có thể.

+1

Phần thực sự bizzare là điều này chỉ xảy ra nếu bạn gọi 'savefig', và không nếu bạn gọi' show' ... –

Trả lời

2

Có thể tránh sự cố bằng cách sử dụng cùng các trục cho mỗi ô, với ax.cla() được gọi để xóa ô sau mỗi lần lặp.

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) 
+0

Cảm ơn bạn @unutbu! Hoạt động hoàn hảo. –

+0

Tuyệt vời; mừng vì tôi có thể giúp! Xin vui lòng không chấp nhận câu trả lời này, như tôi muốn biết tại sao các bản vá được chuyển đổi trong mã ban đầu của bạn quá. – unutbu

2

Một thay thế cho câu trả lời unutbu của, là sử dụng copy gói, trong đó có thể sao chép các đối tượng. Rất khó để thấy mọi thứ đang thay đổi như thế nào sau khi một cuộc gọi là add_patch, nhưng chúng là như vậy. Các thuộc tính axes, figure, extents, clip_box, transformwindow_extent thuộc tính của bản vá được thay đổi. Không may là việc in bề ngoài của mỗi thuộc tính này dẫn đến cùng một chuỗi, vì vậy có vẻ như chúng không thay đổi. Nhưng các thuộc tính cơ bản của một số hoặc tất cả các thuộc tính này, ví dụ: extents là một Bbox, có thể đã thay đổi.

Cuộc gọi sao chép sẽ cho phép bạn nhận được bản vá duy nhất cho mỗi hình bạn thực hiện mà không biết loại bản vá đó là gì. Điều này vẫn không trả lời lý do tại sao điều này xảy ra, nhưng như tôi đã viết ở trên nó là một giải pháp thay thế cho các vấn đề:

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') 

Ngoài ra bạn có thể sử dụng fig.savefig(str(count) + '.png'). Điều này tiết kiệm một cách rõ ràng hình fig nơi mà các cuộc gọi plt.savefig lưu hình hiện tại, mà sẽ xảy ra là một trong những bạn muốn.

Các vấn đề liên quan