Matplotlib to Django Template

Im using python 3.4 and Django 1.8. I want to "print" the matplotlib result in a Django template. I achieve this a few days ago, so I continue in other things of my Django application. Now I don’t know why, I'm going to show the result to a friend, and my matplotlib chart template now shows a big code! I do not know why this is happening, because my view does not change anything when he showed the correct schedule! Please help me!

This is my opinion!

from django.shortcuts import render from matplotlib import pylab from pylab import * import PIL import PIL.Image import io from io import * def graphic(request): 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('Popularity') ylabel('Hashtags') title('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") content_type="Image/png" buffercontent=buffer.getvalue() graphic = (buffercontent ,content_type) pylab.close() return render(request, 'graphic.html',{'graphic':graphic}) 

Of course, in my graphics.html there is a variable called {{graphic}} inside blockcontent!

This showed the correct result in my template! What's happening? Now sometimes, when I run my template, it shows large code or just shows me this django error:

Exception value:
main thread is not in main loop

Exception Location: C: \ Python34 \ lib \ site-packages \ matplotlib \ backends \ tkagg.py in blit, line 17

Help!

+7
source share
5 answers

Edit:

try

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

You must indicate that your image is a binary string:

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

Or actually save it to the file system and specify the path.

Alternatively, you can use bokeh http://bokeh.pydata.org/en/latest/ , which can give you html + javascript to insert a direclty plot into the template, then it is dynamically generated and brings nice features.

It is built by continuum analytics, guys from the anaconda distribution.

+4
source

The final solution was to create a custom view that returns the matplotlib template in an empty template, for example:

 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 as follows:

 <img src="url_of_the_graphic_view"> 

And all this!

+2
source
 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}) 
+1
source
  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

+1
source

After using the answers above, I also had a damaged icon image, and I fixed it by removing b' and ' from the base64 binary graphical representation:

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

0
source

Source: https://habr.com/ru/post/988172/


All Articles