将Matplotlib转换为Django Temp

2024-07-07 08:04:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Python3.4和Django1.8。我想在Django模板中“打印”matplotlib结果。我几天前就知道了,所以我继续我的Django应用程序中的其他内容。现在,我不知道为什么,我要把结果显示给一个朋友,我的模板和一个matplotlib图,现在显示一个大的代码!我不知道为什么会发生这种情况,因为我的观点在任何事情上都没有改变,从它显示正确的图表!请帮帮我!

这是我的观点!

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})

当然,在graphic.html中,blockcontent中有一个名为{{graphic}}的变量!

这在我的模板中显示了正确的结果!发生了什么事? 现在,有时当我运行模板时,它会显示一个大代码,或者只显示这个django错误:

异常值:
主线程不在主循环中

异常位置:C:\ Python34\lib\site packages\matplotlib\backends\tkagg.py in blit,第17行

救命啊!


Tags: django代码fromioposimageimport模板
3条回答

最终的解决方案是创建一个特殊视图,该视图在空模板中返回matplotlib绘图,如下所示:

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")

下一步是在模板中输入以下内容:

<img src="url_of_the_graphic_view">

就这些!

    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})

在模板中:

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

我有:

matplotlib==3.0.2和Django==2.1.4

编辑:

试一试

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

必须指定图像是二进制字符串:

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

或者实际将其保存到文件系统并提供路径。

或者,您可以使用Bokeh,它可以为您提供html+javascript来将绘图直接嵌入到模板中,然后它会动态生成并带来很好的特性。

相关问题 更多 >