Returning Matplotlib image as string Returning Matplotlib image as string django django

Returning Matplotlib image as string


Django's HttpResponse object supports file-like API and you can pass a file-object to savefig.

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

Hence, you can return the image directly in the HttpResponse.


what about cStringIO?

import pylabimport cStringIOpylab.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


There is a recipe in the Matplotlib Cookbook that does exactly this. At its core, it looks like:

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

Put that in your views file, point your URL to it, and you're off and running.

Edit: As noted, this is a simplified version of a recipe in the cookbook. However, it looks like there is a difference between calling print_png and savefig, at least in the initial test that I did. Calling fig.savefig(response, format='png') gave an image with that was larger and had a white background, while the original canvas.print_png(response) gave a slightly smaller image with a grey background. So, I would replace the last few lines above with:

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

You still need to have the canvas instantiated, though.