[Fixed]-Matplotlib into a Django Template

10πŸ‘

    from io import BytesIO
    import base64
    import matplotlib.pyplot as plt
    import numpy as np

    def graphic(request):

        pos = np.arange(10)+ 2 

        fig = plt.figure(figsize=(8, 3))
        ax = fig.add_subplot(111)

        ax.barh(pos, np.arange(1, 11), align='center')
        ax.set_yticks(pos)
        ax.set_yticklabels(('#hcsm',
            '#ukmedlibs',
            '#ImmunoChat',
            '#HCLDR',
            '#ICTD2015',
            '#hpmglobal',
            '#BRCA',
            '#BCSM',
            '#BTSM',
            '#OTalk',), 
            fontsize=15)
        ax.set_xticks([])
        ax.invert_yaxis()

        ax.set_xlabel('Popularity')
        ax.set_ylabel('Hashtags')
        ax.set_title('Hashtags')

        plt.tight_layout()

        buffer = BytesIO()
        plt.savefig(buffer, format='png')
        buffer.seek(0)
        image_png = buffer.getvalue()
        buffer.close()

        graphic = base64.b64encode(image_png)
        graphic = graphic.decode('utf-8')

        return render(request, 'graphic.html',{'graphic':graphic})

and in the template:

<img src="data:image/png;base64,{{ graphic|safe }}">

I have:

matplotlib==3.0.2 and Django==2.1.4

πŸ‘€Pawel Piela

6πŸ‘

Edit:

try with

graphic = cStringIO.StringIO()
canvas.print_png(graphic)
return render(request, 'graphic.html',{'graphic':graphic})

You have to specify that your image is a binary string:

<img src="data:image/png;base64,{{graphic|safe}}">

Or actually save it to the filesystem and provide the path.

Alternatively you could use Bokeh which can give you the html + javascript to embed the plot directly in the template, then it is dynamically generated and brings nice features.

πŸ‘€Maresh

3πŸ‘

The final solution was to create a special view that returns the matplotlib plot in an empty template, like this:

def grafico (rquest):
    pos = arange(10)+ 2 

    barh(pos,(1,2,3,4,5,6,7,8,9,10),align = 'center')

    yticks(pos,('#hcsm','#ukmedlibs','#ImmunoChat','#HCLDR','#ICTD2015','#hpmglobal','#BRCA','#BCSM','#BTSM','#OTalk'))

    xlabel('Popularidad')
    ylabel('Hashtags')
    title('GrΓ‘fico de Hashtags')
    subplots_adjust(left=0.21)

    buffer = io.BytesIO()
    canvas = pylab.get_current_fig_manager().canvas
    canvas.draw()
    graphIMG = PIL.Image.fromstring('RGB', canvas.get_width_height(), canvas.tostring_rgb())
    graphIMG.save(buffer, "PNG")
    pylab.close()

    return HttpResponse (buffer.getvalue(), content_type="Image/png")

The next step is to put in your template this:

<img src="url_of_the_graphic_view">

And thats all!

1πŸ‘

def show(request):

x = np.arange(10)
y = x
fig = plt.figure()
plt.plot(x, y)
canvas = fig.canvas
buf, size = canvas.print_to_buffer()
image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
buffer=io.BytesIO()
image.save(buffer,'PNG')
graphic = buffer.getvalue()
graphic = base64.b64encode(graphic)
buffer.close()
return render(request, 'graphic.html',{'graphic':graphic})
πŸ‘€navyern

1πŸ‘

I had a broken icon image as well, after using the answers above, and I fixed it by removing the b' and ' from the graphic base64 binary representation :

return render(request, 'graphic.html', {'graphic': str(graphic)[2:-1]})

πŸ‘€zeibou

Leave a comment