2009-07-10 37 views
7

Tôi đang sử dụng matplotlib trong ứng dụng django và muốn trực tiếp trả về hình ảnh được hiển thị. Cho đến nay tôi có thể đi plt.savefig(...), sau đó trả lại vị trí của hình ảnh.Trả lại hình ảnh Matplotlib thành chuỗi

Những gì tôi muốn làm là:

return HttpResponse(plt.renderfig(...), mimetype="image/png") 

Bất kỳ ý tưởng?

Trả lời

16

Đối tượng của Django là đối tượng tập tin để lưu.

response = HttpResponse(mimetype="image/png") 
# create your image as usual, e.g. pylab.plot(...) 
pylab.savefig(response, format="png") 
return response 

Do đó, bạn có thể trả lại hình ảnh trực tiếp trong HttpResponse.

+0

Có một vài gợi ý khác trông giống như chúng sẽ hoạt động, nhưng DEFINITELY này trông giống như dễ nhất để tôi sử dụng. Tôi chỉ phải thêm khoảng 2 hoặc 3 dòng mã! Cảm ơn bạn – DarwinSurvivor

0

dụng ducktyping và vượt qua một đối tượng của riêng bạn, trong ngụy trang của đối tượng tập tin

class MyFile(object): 
    def __init__(self): 
     self._data = "" 
    def write(self, data): 
     self._data += data 

myfile = MyFile() 
fig.savefig(myfile) 
print myfile._data 

bạn có thể sử dụng myfile = StringIO.StringIO() thay vì trong mã sản và trả lại dữ liệu trong phản ứng ví dụ

output = StringIO.StringIO() 
fig.savefig(output) 
contents = output.getvalue() 
return HttpResponse(contents , mimetype="image/png") 
+0

Điều này sẽ hoạt động khá tốt, nhưng như wierob đã đề cập, HttpResponse đã hỗ trợ truy cập tệp (mà tôi không nhận ra). Vì vậy, bạn có thể bỏ qua việc tạo lớp của riêng bạn. Bất cứ ai làm điều gì đó tương tự bên ngoài django, điều này chắc chắn trông giống như một ý tưởng hay. – DarwinSurvivor

+0

thực sự tôi không tạo ra lớp học của riêng tôi mà chỉ là một possiblity, như tôi đã nói người dùng StringIO, và có sử dụng đối tượng respose chính nó là tốt nhất. –

6

khoảng cStringIO?

import pylab 
import cStringIO 
pylab.plot([3,7,2,1]) 
output = cStringIO.StringIO() 
pylab.savefig('test.png', dpi=75) 
pylab.savefig(output, dpi=75) 
print output.getvalue() == open('test.png', 'rb').read() # True 
+0

Hmm, điều này sẽ làm việc cho các hệ thống khác, nhưng tôi không nghĩ rằng django sẽ xử lý in ấn trực tiếp rất tốt vì nó sử dụng các đối tượng HttpResponse cho tất cả các thông tin liên lạc bên ngoài của nó. – DarwinSurvivor

+0

@darwinsuvivor, đồng ý với u, tôi chỉ muốn hiển thị rằng savefig cho một đối tượng cStringIO.StringIO() là giống như savefig thành tệp PNG. sau đó, không cần phải sử dụng in ở đây. Có vẻ như câu trả lời của @ wierob hoàn toàn phù hợp với tình hình hiện tại của chúng tôi. – sunqiang

2

Có công thức trong Matplotlib Cookbook thực hiện chính xác việc này. Ở cốt lõi của nó, có vẻ như:

def simple(request): 
    from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas 
    from matplotlib.figure import Figure 

    fig=Figure() 
    ax=fig.add_subplot(111) 
    ax.plot(range(10), range(10), '-') 
    canvas=FigureCanvas(fig) 
    response=django.http.HttpResponse(content_type='image/png') 
    canvas.print_png(response) 
    return response 

Đặt điều đó vào tệp lượt xem, trỏ URL của bạn đến đó và bạn đang tắt và chạy.

Chỉnh sửa: Như đã lưu ý, đây là phiên bản đơn giản của công thức trong sách dạy nấu ăn. Tuy nhiên, có vẻ như có sự khác biệt giữa việc gọi số print_pngsavefig, ít nhất là trong thử nghiệm ban đầu mà tôi đã làm. Gọi số fig.savefig(response, format='png') cho hình ảnh lớn hơn và có nền trắng, trong khi hình ảnh gốc canvas.print_png(response) đã cho hình ảnh hơi nhỏ hơn với nền màu xám. Vì vậy, tôi sẽ thay thế một vài dòng cuối cùng ở trên bằng:

canvas=FigureCanvas(fig) 
    response=django.http.HttpResponse(content_type='image/png') 
    fig.savefig(response, format='png') 
    return response 

Bạn vẫn cần phải có canvas khởi tạo.

+0

Có sự khác biệt (tốc độ, hiệu quả, v.v.) giữa việc sử dụng canvase.print_png và chỉ cần thực hiện save_fig() trên HttpResponse không? – DarwinSurvivor

+0

Bạn sẽ phải đo sự khác biệt về tốc độ, nhưng có sự khác biệt trong bản trình bày như được ghi trong bản chỉnh sửa. Điều này cũng không phụ thuộc vào các hàm pylab/pyplot wrapper, mà tôi thích cho loại ứng dụng này. –

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