2009-07-10 13 views
7

Używam matplotlib w aplikacji django i chcę bezpośrednio zwrócić renderowany obraz. Do tej pory mogę przejść plt.savefig(...), a następnie zwrócić lokalizację obrazu.Powracający obraz Matplotlib jako ciąg

Co chcę zrobić, to:

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

Jakieś pomysły?

Odpowiedz

16

Django HttpResponse obiekt obsługuje plikopodobny API i można przekazać plik-Object do savefig.

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

W związku z tym można zwrócić obraz bezpośrednio w numerze HttpResponse.

+0

Istnieje kilka innych sugestii, które wyglądają tak, jakby działały, ale to NA ZDECYDOWANIE wygląda na najłatwiejsze do użycia. Muszę dodać tylko 2 lub 3 linie kodu! Thank-You – DarwinSurvivor

0

Zatrudniamy Duck Typing i przekazać obiekt z własną rękę, w przebraniu obiektu pliku

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

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

można użyć myfile = StringIO.StringIO() zamiast w prawdziwym kodzie i zwraca dane w réponse np

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

To zadziałałoby całkiem dobrze, ale jak wspomniał już przewodniczący, HttpResponse już obsługuje dostęp do plików (czego nie zdawałem sobie sprawy). Możesz pominąć tworzenie własnej klasy. Każdy, kto robi coś podobnego poza django, zdecydowanie wygląda na dobry pomysł. – DarwinSurvivor

+0

Właściwie to nie tworzę własnej klasy, która była tylko możliwą, jak powiedziałem użytkownika StringIO, i tak samo użycie obiektu respose jest najlepsze. –

6

co z 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, działałoby to na inne systemy, ale nie sądzę, by django obsługiwał druk bezpośredni bardzo dobrze, ponieważ używa obiektów HttpResponse dla całej swojej komunikacji wychodzącej. – DarwinSurvivor

+0

@darwinsuvivor, zgadzam się z u, chcę tylko pokazać, że savefig do cStringIO.StringIO() obiekt jest taki sam jak savefig do pliku PNG. po tym nie ma potrzeby używania drukowania tutaj. Wygląda na @ @ roboba odpowiedź jest całkowicie dopasowana do naszej obecnej sytuacji. – sunqiang

2

Istnieje przepis w Matplotlib Cookbook, który robi dokładnie to. Zasadniczo wygląda to następująco:

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 

Umieść to w swoim pliku poglądów, wskaż adres URL i uruchom.

Edycja: Jak wspomniano, jest to uproszczona wersja przepisu w książce kucharskiej. Jednak wygląda na to, że istnieje różnica między wywołaniem print_png i savefig, przynajmniej w początkowym teście, który zrobiłem. Dzwonienie pod numer fig.savefig(response, format='png') dało obraz, który był większy i miał białe tło, podczas gdy oryginał canvas.print_png(response) dał nieco mniejszy obraz z szarym tłem. Tak, chciałbym zastąpić kilka ostatnich linii powyżej:

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

Nadal trzeba mieć utworzony materiał canvas.

+0

Czy istnieje różnica (szybkość, wydajność itd.) Między używaniem canvase.print_png a po prostu robienie save_fig() na HttpResponse? – DarwinSurvivor

+0

Trzeba zmierzyć różnicę prędkości, ale istnieje różnica w prezentacji, jak zauważono w edycji. Nie zależy to również od funkcji owijki pylab/pyplot, którą lubię dla tego rodzaju aplikacji. –