2009-07-10 16 views
7

Ich verwende Matplotlib in einer Django-App und möchte das gerenderte Bild direkt zurückgeben. Bis jetzt kann ich plt.savefig(...) gehen, dann den Speicherort des Bildes zurückgeben.Matplotlib-Bild als Zeichenfolge zurückgeben

Was ich tun möchte, ist:

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

Irgendwelche Ideen?

Antwort

16

Djangos HttpResponse Objekt unterstützt datei wie API und Sie können eine Datei-Objekt zu savefig passieren.

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

Daher können Sie das Bild direkt zurück in den HttpResponse.

+0

Es gibt ein paar andere Vorschläge, die aussehen, als ob sie funktionieren würden, aber dieses DEFINITIVE sieht für mich am einfachsten aus. Ich muss nur etwa 2 oder 3 Zeilen Code hinzufügen! Vielen Dank – DarwinSurvivor

0

Beschäftigen Duck-Typing und ein Objekt der eigenen Pass, in der Verkleidung von Dateiobjekt

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

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

können Sie Meinedat verwenden = StringIO.StringIO() statt in echtem Code und geben Daten in reponse z.B.

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

Das würde recht gut funktionieren, aber wie bereits erwähnt, unterstützt HttpResponse bereits Dateizugriff (was ich nicht realisiert habe). Sie können also Ihre eigene Klasse erstellen. Wer etwas ähnliches außerhalb des Django tut, sieht dies definitiv als eine gute Idee. – DarwinSurvivor

+0

eigentlich bin ich nicht meine eigene Klasse erstellen, die nur eine Möglichkeit war, wie ich Benutzer StringIO sagte, und ja mit respose Objekt selbst ist am besten. –

6

was ist mit 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, das würde für andere Systeme funktionieren, aber ich denke nicht, dass Django das direkte Drucken sehr gut handhaben würde, da es HttpResponse-Objekte für all seine abgehende Kommunikation verwendet. – DarwinSurvivor

+0

@darwinsuvivor, stimme zu, ich möchte nur zeigen, dass savefig in ein cStringIO.StringIO() -Objekt ist das gleiche wie savefig in PNG-Datei. Danach brauchen Sie hier nicht mehr drucken. Es sieht so aus, als ob die Antwort von @ istob für unsere gegenwärtige Situation völlig geeignet ist. – sunqiang

2

Es gibt ein Rezept in der Matplotlib Cookbook, die genau dies tut. Im Kern sieht es so aus:

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 

Setzen Sie, dass in Ihren Ansichten Datei, zeigen Sie Ihre URL, um es, und du bist weg und läuft.

Edit: Wie bereits erwähnt, ist dies eine vereinfachte Version eines Rezepts im Kochbuch. Es sieht jedoch so aus, als ob es einen Unterschied zwischen dem Aufruf von print_png und savefig gibt, zumindest beim ersten Test, den ich gemacht habe. Rufen Sie fig.savefig(response, format='png') gab ein Bild mit dem war größer und hatte einen weißen Hintergrund, während das Original canvas.print_png(response) gab ein etwas kleineres Bild mit einem grauen Hintergrund. So würde ich die letzten paar Zeilen weiter oben mit ersetzen:

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

Sie müssen noch die Leinwand instanziiert haben, though.

+0

Gibt es einen Unterschied (Geschwindigkeit, Effizienz usw.) zwischen der Verwendung von canvase.print_png und einfach eine save_fig() auf der HttpResponse? – DarwinSurvivor

+0

Sie müssten den Unterschied in der Geschwindigkeit messen, aber es gibt einen Unterschied in der Darstellung, wie in der Bearbeitung erwähnt. Dies hängt auch nicht von den pylab/pyplot-Wrapper-Funktionen ab, die ich für diese Art von Anwendung mag. –

Verwandte Themen