利用 Flask 動態展現 Pyecharts 圖表數據的幾種方法

本文將介紹如何在 web 框架 Flask 中使用可視化工具 pyecharts, 看完本教程你將掌握幾種動態展現可視化數據的方法,不會的話你來找我呀...javascript

Flask 模板渲染

1. 新建一個項目 flask-echarts

在編輯器中選擇 New Project,而後選擇 Flask,建立完以後,Pycharm 會幫咱們把啓動腳本和模板文件夾都建好css

2. 拷貝 pyecharts 模板

將連接中的如下模板 ├── jupyter_lab.html ├── jupyter_notebook.html ├── macro ├── nteract.html ├── simple_chart.html ├── simple_page.html └── table.html 所有拷貝到 tempaltes 文件夾中 github.com/pyecharts/p…html

3.渲染圖表

主要目標是將 pyecharts 生成的圖表數據在視圖函數中返回,因此咱們直接在 app.py 中修改代碼,以下:前端

from flask import Flask
from jinja2 import Markup


from pyecharts import options as opts
from pyecharts.charts import Bar

app = Flask(__name__, static_folder="templates")


def bar_base() -> Bar:
    c = (
        Bar()
            .add_xaxis(["襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子"])
            .add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
            .add_yaxis("商家B", [15, 25, 16, 55, 48, 8])
            .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副標題"))
    )
    return c


@app.route("/")
def index():
    c = bar_base()
    return Markup(c.render_embed())


if __name__ == "__main__":
    app.run()
複製代碼

直接運行,在瀏覽器中輸入地址,直接將數據顯示出來了java

這是一個很簡單的靜態數據展現,別急好戲還在後頭~

Flask 先後端分離

前面講的是一個靜態數據的展現的方法,用 pyecharts 和 Flask 結合最主要是實現一種動態更新數據,增量更新數據等功能!以上面講解的內容爲基礎,在 templates 文件夾中新建一個 index.html 的文件,其中主要用到了 jquery 和 pyecharts 管理的 echarts.min.js 依賴。python

index.htmljquery

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>動態更新數據</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script> ( function () { var result_json = '{{ result_json|tojson }}'; // var result = JSON.parse(result_json); var chart = echarts.init(document.getElementById('bar'), 'gray', {renderer: 'canvas'}); $.ajax({ type: "GET", url: "http://127.0.0.1:5000/barChart", dataType: 'json', data: {result: result_json}, success: function (result) { chart.setOption(result); } }); } ) </script>
</body>
</html>
複製代碼

有 html 基礎的朋友應該知道該代碼主要是向地址 "127.0.0.1:5000/barChart" 發送請求,因此在 app.py 中咱們也須要作相應的修改,添加該地址的路由函數,從而實現動態數據更新。 部分代碼以下:git

@app.route("/")
def index():
    data = request.args.to_dict()
    return render_template("index.html", result_json=data)

@app.route("/barChart")
def get_bar_chart():
    args = request.args.to_dict()
    result = eval(args.get("result"))
    name = result.get("name")
    subtitle = result.get("subtitle")
    c = bar_base(name, subtitle)

    return c.dump_options_with_quotes()
複製代碼

在 index 視圖函數中接收瀏覽器傳過來的參數,而後傳遞給 index.html。此處只是簡單示例,因此未作參數校驗。而另外一個視圖函數主要是獲取參數,傳給圖表生成函數 bar_base(), 從而實現根據 url 地址傳過來的參數,動態展現圖表數據。結果以下:github

這裏只是簡單演示, 因此只將圖表標題做爲動態傳參。此場景適用於第一次請求獲取咱們想要的數據,而後將其展現出來。好比我以前寫的 NBA 球員數據可視化 mp.weixin.qq.com/s/WWCNf46Ch… web

Python獲取NBA歷史巨星和現役全部球員生涯數據曲線

就是此方法,不一樣球員展現對應球員數據!

定時全量更新圖表

該場景主要是前端主動向後端進行數據刷新,定時刷新的核心在於 HTML 的 setInterval 方法。那麼 index.html 代碼就是下面這樣的:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>

</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script> var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'}); $( function () { fetchData(chart); setInterval(fetchData, 2000); } ); function fetchData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/barChart", dataType: 'json', success: function (result) { chart.setOption(result); } }); } </script>
</body>
</html>
複製代碼

對應的將 app.py 中 bar_base() 做相應的修改,從而實現定時全量更新圖表

def bar_base() -> Bar:
    c = (
        Bar()
            .add_xaxis(["襯衫", "羊毛衫", "雪紡衫", "褲子", "高跟鞋", "襪子"])
            .add_yaxis("商家A", [random.randint(10, 100) for _ in range(6)])
            .add_yaxis("商家B", [random.randint(10, 100) for _ in range(6)])
            .set_global_opts(title_opts=opts.TitleOpts(title="", subtitle=""))
    )
    return c

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/barChart")
def get_bar_chart():
    c = bar_base()
    return c.dump_options_with_quotes()
複製代碼

運行以後,在瀏覽器中打開,效果以下:

定時更新圖表

看到這動圖,有沒有一種...,若是我是 DJ DJ,琦你太美...

定時增量更新圖表

一樣的要對 index.html 作修改

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>

</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script> var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'}); var old_data = []; $( function () { fetchData(chart); setInterval(getDynamicData, 2000); } ); function fetchData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/lineChart", dataType: "json", success: function (result) { chart.setOption(result); old_data = chart.getOption().series[0].data; } }); } function getDynamicData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/lineDynamicData", dataType: "json", success: function (result) { old_data.push([result.name, result.value]); chart.setOption({ series: [{data: old_data}] }); } }); } </script>
</body>
</html>
複製代碼

增量更新,後端代碼也須要相應的修改

from pyecharts.charts import Line

def line_base() -> Line:
    line = (
        Line()
        .add_xaxis(["{}".format(i) for i in range(10)])
        .add_yaxis(
            series_name="",
            y_axis=[randrange(50, 80) for _ in range(10)],
            is_smooth=True,
            label_opts=opts.LabelOpts(is_show=False),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="動態數據"),
            xaxis_opts=opts.AxisOpts(type_="value"),
            yaxis_opts=opts.AxisOpts(type_="value"),
        )
    )
    return line

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/lineChart")
def get_line_chart():
    c = line_base()
    return c.dump_options_with_quotes()

idx = 9

@app.route("/lineDynamicData")
def update_line_data():
    global idx
    idx = idx + 1
    return jsonify({"name": idx, "value": randrange(50, 80)})
複製代碼

走起,來看看效果吧

感謝閱讀和關注!

相關文章
相關標籤/搜索