2013-05-02 40 views
17

Có vẻ như cách tiêu chuẩn để tạo một hình trong matplotlib không hoạt động như tôi mong đợi trong python: theo mặc định, gọi fig = matplotlib.figure() trong vòng lặp sẽ giữ cho tất cả các số liệu được tạo, và cuối cùng hết bộ nhớ.Tạo một hình được tham chiếu tính

quiteafew bài đăng xử lý giải pháp, nhưng yêu cầu cuộc gọi rõ ràng đến matplotlib.pyplot.close(fig) có vẻ hơi đáng sợ. Những gì tôi muốn là một cách đơn giản để làm tài liệu tham khảo fig tính, vì vậy tôi sẽ không phải lo lắng về việc rò rỉ bộ nhớ. Có cách nào để làm việc này không?

+1

Nó thực sự giống như quản lý bộ nhớ sử dụng, trong trường hợp này, con số này là một nguồn tài nguyên bên ngoài (như một bộ mô tả tập tin) để hệ thống Windowing, và 'plt.figure()' là các nhà xây dựng, trong khi 'plt.close (fig) 'là hàm hủy. Mặc dù có nhiều mức độ hủy diệt do 'clf' và' cla' và những người khác. Trong trường hợp này, cách thích hợp để thực hiện việc này là sử dụng thành ngữ ngoặc đơn 'with' (" trình quản lý ngữ cảnh "). – CMCDragonkai

Trả lời

18

Nếu bạn tạo con số mà không sử dụng plt.figure, sau đó nó nên tham khảo tính như bạn mong đợi. Ví dụ (. Đây là cách sử dụng không tương tác AGG phụ trợ, cũng)

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas 
from matplotlib.figure import Figure 

# The pylab figure manager will be bypassed in this instance. 
# This means that `fig` will be garbage collected as you'd expect. 
fig = Figure() 
canvas = FigureCanvas(fig) 
ax = fig.add_subplot(111) 
+2

Không có 'FigureCanvas (fig)' Tôi nhận được một ngoại lệ khi tôi cố gắng lưu hình. Tôi lấy nó rằng một 'Hình' phải luôn được vẽ bằng một' HìnhCanvas'? – Shep

+2

Yep! Nếu không thì không có gì có thể được rút ra (các nghệ sĩ được tạo ra, nhưng bản vẽ không xảy ra cho đến khi bạn lưu/hiển thị cốt truyện). Đó là một mụn cóc trong API; lý tưởng là canvas sẽ được bắt đầu cùng với hình. Nó có thể có ý nghĩa hơn nếu bạn sử dụng 'canvas.print_figure (filename)' thay vì 'fig.savefig (filename)' (mà thực sự là những gì 'fig.savefig' làm đằng sau hậu trường). Đó là hoàn toàn cho sự hiểu biết của riêng bạn, mặc dù (vải là phần phụ trợ cụ thể xử lý vẽ/tiết kiệm). Kết quả cuối cùng là như nhau. –

+1

Hmm, vì vậy vải có tồn tại trước khi lưu không? Tôi tự hỏi nếu 'FigureCanvas (fig) .print_figure (tên tệp)' sẽ hoạt động như một chức năng in một dòng. – Shep

2

Nếu bạn sẽ chỉ được tiết kiệm nhân vật chứ không phải hiển thị chúng, bạn có thể sử dụng:

def savefig(*args, **kwargs): 
    plt.savefig(*args, **kwargs) 
    plt.close(plt.gcf()) 

Điều này được cho là không ít hacky, nhưng bất cứ điều gì.

+0

Cảm ơn, nhưng trong khi điều này cho tôi biết cách lưu hình và đóng nó lại không trả lời câu hỏi - nó giống như trả lời "làm cách nào để sử dụng con trỏ thông minh trong C++" bằng cách "cấp phát con trỏ thô và sau đó gọi 'xóa khi bạn hoàn thành nó ". – Shep

+0

Đó là công bằng, chỉ đề xuất một giải pháp thay thế cho "Làm thế nào tôi có thể không lo lắng về rò rỉ bộ nhớ" mà vẫn sử dụng API 'plt' chuẩn. –

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