在Flask中显示新图表

时间:2019-11-21 21:36:03

标签: python html flask

我一直在努力寻找一种方法来更新Flask Web服务器上的图形。我将图像存储在目录的静态文件中,并通过{{url_for('static',filname = ph_plot.png)}}访问它们,但是每次我发送发布请求以获取新数据范围时,图形都不会在我的网络服务器上更新,但在我的文件系统上会更新。我知道每次保存文件都可以更改文件名以使其显示,但是我不知道这是否是显示动态变化的照片的最佳方法。 目前,我在flask中一直使用send_from_directory方法,但是它对我也没有用。下面是我的代码。 我已经为此工作了一段时间,希望能有所帮助!谢谢

注意:all_plots.ph_plot()正在从另一个python程序调用一个函数。 瓶装代码:

@app.route('/read_ph', methods=["GET", "POST"])
def ph_plot():
    if request.method == "POST":
        a = request.form['read_ph']
        all_plots.ph_plot(a)
        time.sleep(3)
        ph_plot = os.path.join(os.getcwd(), "images/ph_plot.png")
        return render_template('live_stream.html', image_name=ph_plot)


@app.route('/read_ph/<ph_plot>', methods=["GET", "POST"])
def send_ph(ph_plot):
    return send_from_directory("images", ph_plot)

HTML:

<html>
  <body>

    <h1>Data Monitoring Station</h1>

    <h2>PH</h2>
       <form method="POST" action="read_ph" >

          <input name="read_ph" placeholder="Instances" type="text">

        </form>

        <a href="read_ph"><button type="button">PH Graph</button></a>

        <img src="{{ url_for('send_ph',ph_plot=image_name) }}" id="plot" width ="220" height ="220">

    <hr>
    <h5> Return to main page <a href="/"class="button">RETURN</a></h5>
    <hr>

  </body>
</html>

1 个答案:

答案 0 :(得分:1)

send_from_directory通常用于实际上已从用户上载到目录中的文件。这实际上不是您要尝试执行的操作;你是

  1. 生成绘图数据
  2. 创建情节并花费时间matplotlib进行渲染
  3. 将此绘图图像保存到磁盘
  4. 将该图像从磁盘加载回并发送给用户

在此处删除磁盘存储的中间人:创建数据并将其直接发送到模板。这是在单个文件中使用plotly.js来获取在前端呈现的数据的粗略示例。您可以不断刷新页面以获得不同的图形。但请注意,每个情节都是 interactive ;您可以使用右上角的菜单进行缩放(例如导出)之类的操作,显示/隐藏绘图(如果有多个迹线,则更有意义)。通过渲染绘图图像,您将一无所获。

from flask import Flask, render_template_string

import random

app = Flask(__name__)


# Normally you'd have this in the templates directory but for simplicity of
# putting everything into one file for an example, I'm using a template string

template = """
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<div id="plot_div" style="width: 100%; height: 100%"></div>

<script type="text/javascript">

var trace1 = {
    x: {{ plot_data.x_axis }},
    y: {{ plot_data.y_axis }},
    type: 'scatter',
    name: 'Example'
};

var layout = {
    title: "Test",
    titlefont: {
            family: 'Poppins',
            size: 18,
            color: '#7f7f7f'
        },
    showlegend: true,
    xaxis: {
        title: 'Axis Unit',
    },
    yaxis: {
        title: 'Other Axis Unit',
    },
    margin: {
        l: 70,
        r: 40,
        b: 50,
        t: 50,
        pad: 4
    }
};
var data = [trace1];

Plotly.newPlot("plot_div", data, layout);

</script>
"""

def get_plot_data():
    x = list(range(10))
    y = [random.randint(0, 100) for i in range(10)]
    return {'x_axis': x, 'y_axis': y}

@app.route('/')
def home():
    plot_data = get_plot_data()
    return render_template_string(template,
                                  plot_data=plot_data)

if __name__ == '__main__':
    app.run()

此处常见的问题是传递日期时间字符串,因为它们将被转义。在这种情况下,您将需要使用x: {{ plot_data.x_axis | safe }}。参见Passing HTML to template using Flask/Jinja2How to make html markup show up?