【问题标题】:Pass matplotlib graph to HTML template (Flask)将 matplotlib 图传递给 HTML 模板(Flask)
【发布时间】:2017-12-29 11:50:42
【问题描述】:

这是我正在生成绘图的代码部分:

graph = df.plot(x='date', y='close')
fig = graph.get_figure()
filepath = 'static/images/graph.png'
fig.savefig(filepath)

return render_template('search_result.html')

我在 Flask 文件的顶部定义我的静态路径,如下所示:

app = Flask(__name__, static_folder='path/to/static/folder')

这是我的文件目录设置:

Main Folder
  - Static
    -- Images
      --- Graph.png
  - Templates
  - app.py

在我的 HTML 模板中,我目前正在这样做:

<img src="{{ url_for('static', filename = 'graph.png') }}"> ...但是它只显示较旧的图像。每次调用该函数时,我都会重写图像。

我了解使用 jinja 将变量传递给 HTML,但是我不确定如何使用图像路径。

谁能帮帮我?

【问题讨论】:

标签: python


【解决方案1】:

您需要创建一个路由来连接到来自 Flask 的目录调用的发送。所以你基本上创建一个带有src 属性的图像到你的Flask 路由,它使用send_from_directory 发送图像。那是从默认静态文件夹之外的任意文件夹发送。当我发送 Matplotlib 图像时,我添加了一个查询字符串,即图像文件的文件修改时间。有一个 Python 库可以从路径中获取它,您可以在下面看到一些用法。有一个特殊的meta mode 用于 html 以在每次使用图像时强制刷新,但它对我不起作用,原因我无法解释,我最终使用 mod time 绕过浏览器缓存。

首先,我使用以下参数渲染一个模板...

# Acquire image modification times to use as query strings to bypass image caching.
modificationTime = os.path.getmtime( "%s/%s" % ( model.getImagesSubfolder( ) , imageFile ) )
return render_template( 'plotsPage.html' , fileName=imageFile , modTimes=modificationTime )

然后我的 plotsPage.html 模板文件有一个以下标签,它创建了必要的查询字符串,其中 mod 时间刚刚在服务器端查找...

<img src="{{ url_for( 'sendPlotImage' , filename=fileName , t=modTime ) }}">

然后,我要连接的 url 使用 send_from_directory 提供实际图像。我有一个视图模型,它为我提供了我的应用程序下的子文件夹,我的图像可以通过会话状态和所有其他用户逐个用户检索。

@flaskApp.route( '/Images/<filename>' , methods=['GET'] )
def sendPlotImages( filename ) :   
    # Image file not generated, send placeholder instead to denote file does not exist.
    if not os.path.isfile( "%s/%s" % ( model.getImagesSubfolder( ) , filename )  ) :
        return send_from_directory( "static" , placeHolderImage )

    return send_from_directory( model.getImagesSubfolder( ) , filename )

【讨论】:

  • 这不起作用。返回一个错误。是否可以编辑您的示例以适合我提供的代码?我还在为此苦苦挣扎。
  • 我提供的代码必须适应您的情况,例如 model.getImagesSubfolder()placeHolderImage 是特定于我的应用程序的,但提供这些代码是为了让您考虑根据您的情况构建这些东西有。你遇到了什么错误?
  • 我能够以不同的方式解决这个问题,谢谢!
【解决方案2】:

您应该将 img 作为字节传递。

%pylab
from io import BytesIO
x = np.linspace(0, np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
fig = plt.gcf()
buffer = BytesIO
fig.canvas.print_png(buffer)
buffer.seek(0)

你可以使用send_file发送img:

from flask import send_file
@app.route('/img')
def images():
    return send_file(buffer, mimetype="image/png")

【讨论】:

  • 嗯。所以我不会渲染模板?是否可以编辑您的示例代码以适合我提供的代码。我的功能目前没有路线。它只是一个处理函数。
  • 你可以使用 渲染图像。我更喜欢这种方式。
  • 我如何将图像发送到 HTML 模板。
猜你喜欢
  • 2011-03-13
  • 2013-12-05
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2023-01-11
相关资源
最近更新 更多