【问题标题】:Matplotlib image not displaying in Django templateMatplotlib 图像未显示在 Django 模板中
【发布时间】:2019-11-25 19:57:36
【问题描述】:

我有一个 seaborn barplot 图像,我想在 django 模板中显示。

我查看了一些解决方案,并设法使用 HttpResponse 显示图像。但是,它显示的图像只是图像。我想要的是网页上的情节图像,您仍然可以单击导航栏和主页按钮等。

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
from io import BytesIO
from django.template.loader import render_to_string

在views.py中

def top_causal(request):
  # code for data manipulation
  f = plt.figure(figsize=(10, 5))
  ax = sns.barplot(data)
  # labels, title etc...

  FigureCanvasAgg(f)
  buf = BytesIO()
  plt.savefig(buf, format='png)
  plt.close(f)

  # this works
  response = HttpResponse(buf.getvalue(), content_type='image/png')
  return response

  # What I want which is to display the image inside a template(does not work)
  buffer = buf.getvalue()
  content_type="image/png"
  graphic = (buffer, content_type)
  rendered = render_to_string('top_causal.html', {'graphic': graphic})
  return HttpResponse(rendered)

在 top_causal.html 中

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

HttpResponse 将图像显示为页面。

使用 render_to_string 的响应返回 this 而不是网页内的图像。我仍然可以看到导航栏。

\x06\x1d\x00\x80kT\xb7n]eee\x95\x18\xff\xe1\x87\x1f$I\xf5\xea\xd5\xb3\x19\xcf\xce\xce.\x11\x9b\x9d\x9d-WWW999U\xb8~\xa7N\x9d$\xfd\xf6\x02\xb2\xb0\xb00IR\x9b6mt\xe4\xc8\x91\x12\xb1G\x8e\x1c\x91\xc5b\xb9\xea\xe7\xe1\xda\xb5k\xa7\xf7\xdf\x7f_\xc5\xc5\xc5:|\xf8\xb0V\xadZ\xa5\xe7\x9f\x7f^\xb5j\xd5\xd2\xd4\xa9S\xafx\xee\xdbo\xbf\xad\x81\x03\x07j\xc9\x92%6\xe3\xb9\xb9\xb9\xe5\xba\x9e\xbau\xeb\xcab\xb1h\xc2\x84\t\x9a0aB\xa91M\x9b6-W\xae\xab\xa9W\xaf\x9e\xaaU\xab\xa6\xbd{\xf7\xaaj\xd5\xaa%\xe6]\\\\\xecR\xe7\xb2;\xef\xbcSqqq\x92~{Q\xde\xbb\xef\xbe\xaby\xf3\xe6\xa9\xb8\xb8X\x8b\x16-\xb2k-\x00\x80\xe3b\x07\x1d\x00\x80k\xd4\xb7o_\xa5\xa4\xa4\x94x\x13w||\xbc\xaaT\xa9\xa2\x90\x90\x10\x9b\xf1\xf7\xdf\x7f\xdfz\x8b\xb5$\x9d;wN[\xb7n-\x11W^\x97o\x8do\xd6\xac\x99ul\xc8\x90!JIIQJJ\x8au\xec\xd7 ...

【问题讨论】:

    标签: django matplotlib


    【解决方案1】:

    我放弃了使用 matplotlib 的想法,转而使用 Highcharts https://www.highcharts.com/ 来绘制我的图表并显示在网页上。

    显示的数据是使用 Django 的 ORM 和 Query API 完成的。

    【讨论】:

      【解决方案2】:

      您需要将图像转换为字节数组,将其编码为 base64 并将其嵌入到您的模板中。以下是你的做法:

      <!DOCTYPE html>
      <!--my_template.html-->
      <html>
        <div class='section'>
          <div class='flex column plot mt15 mlr15 justify-left align-left'>
            <img src='{{ imuri }}'/>
          </div>
        </div>
      </html>
      
      from django.template.loader import get_template
      
      def top_causal(request):
      
          # .......................
          # Get your plot ready ...
          # .......................
      
          figure = plt.gcf()
          buf = io.BytesIO()
          figure.savefig(buf, format='png', transparent=True, quality=100, dpi=200)
          buf.seek(0)
          imsrc = base64.b64encode(buf.read())
          imuri = 'data:image/png;base64,{}'.format(urllib.parse.quote(imsrc))
          context = { 'plot': imuri}
      
          # Now embed that to your template
          template = get_template('my_template.html')
          html = template.render(context=context)
      
          # Your template is ready to go...
      

      【讨论】:

      • 我还需要在函数末尾添加return render(request, 'top_causal.html', context)吗?
      • 当然,剩下的就是你渲染一个普通的django模板时做的,我只是想说明点。
      • 我已将代码修改为您的外观,但图像仍未出现。我收到的警告是WARNING: QApplication was not created in the main() thread.QObject::~QObject: Timers cannot be stopped from another thread,它们出现在我的命令窗口中,但网站仍在正常运行。这是否意味着我需要重新启动并再次运行?
      • 嗯,你面临的问题是 matplotlib 使用 tkinter,它必须在主线程上运行。因此,如果您在主线程上绘制图像或使用多处理器作业库(例如 celery 等),这将起作用。
      • 我的后端正在使用 Agg。如何进入主线程并在那里绘图?
      猜你喜欢
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-16
      相关资源
      最近更新 更多