Volviendo la imagen de Matplotlib como una cadena

Estoy utilizando matplotlib en una aplicación de django y me gustaría devolver directamente la imagen renderizada. Hasta ahora puedo ir a plt.savefig(...) y luego devolver la ubicación de la imagen.

Lo que quiero hacer es:

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

¿Algunas ideas?

El objeto HttpResponse de Django admite una API similar a un archivo y puede pasar un objeto de archivo a savefig.

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

Por lo tanto, puede devolver la imagen directamente en HttpResponse .

¿Qué hay de 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 

Hay una receta en el libro de cocina de Matplotlib que hace exactamente esto. En su esencia, se parece a:

 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 

Póngalo en su archivo de vistas, señale su URL hacia él y ya está listo.

Edición: Como se señaló, esta es una versión simplificada de una receta en el libro de cocina. Sin embargo, parece que hay una diferencia entre llamar a print_png y savefig , al menos en la prueba inicial que hice. Llamar a fig.savefig(response, format='png') dio una imagen que era más grande y tenía un fondo blanco, mientras que el canvas.print_png(response) original.print_png canvas.print_png(response) daba una imagen ligeramente más pequeña con un fondo gris. Entonces, reemplazaría las últimas líneas arriba con:

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

Sin embargo, todavía necesitas tener el canvas instanciado.

Emplee patitos y pase un objeto propio, disfrazado de objeto de archivo.

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

puede usar myfile = StringIO.StringIO () en lugar del código real y devolver los datos en respuesta, por ejemplo

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