如何在Django网页中嵌入matplotlib图?

时间:2016-11-10 18:35:26

标签: python django matplotlib graph

所以,请耐心等待,因为我对Django,Python和Web开发都很陌生。我想要做的是显示我使用matplotlib制作的图表。我让它工作到主页自动重定向到图形的png(基本上是浏览器中显示图形的选项卡)。但是,现在我想要的是看到实际的主页与图形简单嵌入。换句话说,我想看到导航栏等,然后是网站正文中的图形。

到目前为止,我已经搜索过,而且我对如何实现这一目标有所了解。我在想的是有一个只返回图形的特殊视图。然后,以某种方式从我的模板中的img src标签访问此png图像,我将用它来显示我的数据。

图形代码:

from django.shortcuts import render
import urllib
import json
from django.http import HttpResponse
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import datetime as dt
import pdb

def index(request):
    stock_price_url = 'https://www.quandl.com/api/v3/datatables/WIKI/PRICES.json?ticker=GOOGL&date.gte=20151101&qopts.columns=date,close&api_key=KEY'

    date = []
    price = []

    #pdb.set_trace()
    source_code = urllib.request.urlopen(stock_price_url).read().decode()

    json_root = json.loads(source_code)
    json_datatable = json_root["datatable"]
    json_data = json_datatable["data"]

    for day in json_data:
        date.append(dt.datetime.strptime(day[0], '%Y-%m-%d'))
        price.append(day[1])

    fig=Figure()
    ax = fig.add_subplot(1,1,1)

    ax.plot(date, price, '-')

    ax.set_xlabel('Date')
    ax.set_ylabel('Price')
    ax.set_title("Google Stock")

    canvas = FigureCanvas(fig)
    response = HttpResponse(content_type='image/png')
    #canvas.print_png(response)
    return response

模板代码:

{% extends "home/header.html" %}
  {% block content %}
  <p>Search a stock to begin!</p>
  <img src="home/graph.py" />

  {% endblock %}

我现在得到的是什么:

Current Page

4 个答案:

答案 0 :(得分:3)

我进行了相当多的搜索,直到找到一种在Django页面上呈现matplotlib图像的解决方案。通常,仅打印一个长长的字符串,而不生成可视化效果。所以,最终对我有用的是:

首先,导入:

import matplotlib.pyplot as plt
from io import StringIO
import numpy as np

虚拟功能返回图形如下:

def return_graph():

    x = np.arange(0,np.pi*3,.1)
    y = np.sin(x)

    fig = plt.figure()
    plt.plot(x,y)

    imgdata = StringIO()
    fig.savefig(imgdata, format='svg')
    imgdata.seek(0)

    data = imgdata.getvalue()
    return data

可以使用其他功能并渲染return_graph()返回的图像来调用此功能:

def home(request):
    context['graph'] = return_graph()
    return render(request, 'x/dashboard.html', context)

dashboard.html文件中,图形是通过以下命令嵌入的:

{{ graph|safe }}

答案 1 :(得分:1)

我认为您不应该使用此行:

#canvas.print_png(response)

您可以使用django HttpResponse轻松返回绘图,而无需使用其他一些库。在matplotlib中,有一个FigureCanvasAgg,您可以通过它访问渲染图的画布。最后,您可以简单地将其返回为HttpResonse。这里有一个非常基本的示例。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg
from django.http import HttpResponse

def plot(request):
    # Data for plotting
    t = np.arange(0.0, 2.0, 0.01)
    s = 1 + np.sin(2 * np.pi * t)

    fig, ax = plt.subplots()
    ax.plot(t, s)

    ax.set(xlabel='time (s)', ylabel='voltage (mV)',
           title='About as simple as it gets, folks')
    ax.grid()

    response = HttpResponse(content_type = 'image/png')
    canvas = FigureCanvasAgg(fig)
    canvas.print_png(response)
    return response

答案 2 :(得分:0)

我知道这个问题被标记为matplotlib,但是我需要做同样的事情,而且我发现plotly更加易于使用和吸引人。您可以简单地绘制一个图,然后在视图中获得该图的html代码:

# fig is plotly figure object and graph_div the html code for displaying the graph
graph_div = plotly.offline.plot(fig, auto_open = False, output_type="div")
# pass the div to the template

在模板中执行:

<div style="width:1000;height:100">
{{ graph_div|safe }}
</div>

答案 3 :(得分:0)

如果要将matplotlib数字嵌入到django-admin中,可以尝试django-matplotlib字段。该字段不会在数据库中创建列,而是呈现为常规字段。您不需要自定义/子类化admin.ModelAdmin,只需在模型中使用此字段并定义如何生成图形即可。