2013-01-10 19 views
11

Trước đây, tôi gặp sự cố với số interference between multiple Matplotlib figures. Cuối cùng tôi đã theo dõi rằng với một vấn đề mà một số chức năng pyplot không đính kèm với thể hiện con số của họ nhưng có thể được trả lại trong một số trường hợp hình khác được tạo song song.Làm cách nào để gắn một hàm pyplot vào một cá thể hình?

Dưới đây là một số mã ví dụ:

from django.http import HttpResponse 
from numpy import arange, meshgrid 
from matplotlib.mlab import bivariate_normal 

def show_chart(request): 
    delta = 0.025 
    x = arange(-3.0, 3.0, delta) 
    y = arange(-2.0, 2.0, delta) 
    X, Y = meshgrid(x, y) 
    Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) 
    Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) 
    Z = 10.0 * (Z2 - Z1) 

    from matplotlib.pyplot import figure, contour 
    fig1 = figure(figsize=(4, 4), facecolor='white') 
    contour(X, Y, Z) 

    response = HttpResponse(content_type='image/png') 
    fig1.savefig(response, format='png') 
    fig1.clear() 
    return response 

Chức năng pyplot đường viền trong ví dụ trên có thể nhận được kết xuất trong fig1, nhưng đôi khi cũng trong một số nhân vật khác được tạo ra song song. Điều đó rất khó chịu. Có cách nào để đính kèm các chức năng pyplot đường viền để fig1?

Trả lời

12

Bạn có thể tạo ra một âm mưu phụ và hơn gọi contour phương pháp của âm mưu phụ:

fig1 = figure(figsize=(4, 4), facecolor='white') 
ax = fig1.add_subplot(111) 
ax.contour(X, Y, Z) 

plt.subplots làm cho nó thuận tiện để tạo ra một nhân vật và ô phụ với một cuộc gọi duy nhất:

import matplotlib.pyplot as plt 

fig, ax = plt.subplots() 
+0

Đây là câu trả lời hoàn hảo: Hoạt động như một sự quyến rũ và chỉ cần tôi để thêm ba dấu hiệu 'rìu.' vào codebase của tôi. Cảm ơn nhiều! – Meilo

+0

cảm ơn bạn. Nếu nó là "hoàn hảo", bạn có thể xem xét để upvote nó ;-). – bmu

+0

Cảm ơn câu trả lời, rất hữu ích. –

20

Là một chút giải thích về những gì đang diễn ra ở đây, matplotlib có hai giao diện bán độc lập; máy trạng thái và giao diện OO.

Mã máy nhà nước được thiết kế để hoạt động trong trình bao tương tác (và bắt chước giao diện của MATLAB). Nó thực hiện điều này bằng cách gói giao diện OO trong một tập hợp các lệnh theo dõi những gì hiện tại figureaxes. Khi bạn sử dụng lệnh từ matplotlib.pyplot (Tôi nghi ngờ bạn có mã số from matploblib.pyplot import * trong mã của bạn) ít nhiều tương đương với việc thực hiện gcf().gca().contour(...). Khi bạn tạo một hình mới, nó sẽ tự động được tạo hiện tại (đó là những gì bạn muốn nếu bạn đang sử dụng nó trong một trình bao lặp) vì vậy hành vi mà bạn thấy là hành vi 'đúng'. Giao diện máy trạng thái cũng có mã trong nó để đảm bảo con số được vẽ lại khi cần, quản lý vòng lặp sự kiện gui, v.v. (tất cả những thứ bạn cần làm để làm cho giao diện tương tác hoạt động trơn tru). Như hayden được đề cập trong các ý kiến, chạy ipython --pylab sẽ tự động chạy from matplotlib.pyplot import *, cung cấp cho bạn một trình vỏ tương tác rất đẹp.

Giao diện OO được thiết kế để xử lý theo chương trình với matplotlib. Những gì nó cho biết thêm trong sự rườm rà (bây giờ bạn phải làm hầu hết công việc của máy trạng thái), nó làm cho rõ ràng. Trong mô hình OO, hầu hết (có lẽ tất cả) các chức năng âm mưu có liên quan đến Axes đối tượng (doc) (vì có thể có nhiều hơn một trục liên kết với một con số (ví dụ: subplots sử dụng gridspec)

Một cách thay thế để. giải quyết vấn đề của bạn là

ax = fig1.gca() 

mà sẽ lấy các trục hiện tại từ fig1, tạo ra một nếu cần thiết. Điều này có thể hữu ích nếu bạn theo dõi các đối tượng hình của bạn, nhưng không phải đối tượng rìu của bạn và muốn thêm đồ thị khác để

+0

Cảm ơn bạn đã giúp tôi hiểu rõ vấn đề này! – Meilo

+0

đáng chú ý khi chạy 'ipython --pylab' bao gồm' từ matploblib.pyplot import * ' –

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