pyecharts Flask

2023-02-17 11:12 更新
本指南介紹了如何在 Flask 中使用 pyecharts。

Flask 模板渲染

Step 0: 新建一個 Flask 項目

$ mkdir pyecharts-flask-demo
$ cd pyecharts-flask-demo
$ mkdir templates

Step 1: 拷貝 pyecharts 模板

將 pyecharts 模板,位于 ?pyecharts.render.templates? 拷貝至剛新建的 templates 文件夾

chenjiandongx@DESKTOP-E83NUHA:/mnt/d/Python/pyecharts-flask-demo/templates$ tree
.
├── jupyter_lab.html
├── jupyter_notebook.html
├── macro
├── nteract.html
├── simple_chart.html
├── simple_page.html
└── table.html

Step 2: 渲染圖表

請將下面的代碼保存為 server.py 文件并移至項目的根目錄下。

目錄結構如下

chenjiandongx@DESKTOP-E83NUHA:/mnt/d/Python/pyecharts-flask-demo$ tree -L 1
.
├── server.py
└── templates

示例代碼

from flask import Flask
from jinja2 import Markup, Environment, FileSystemLoader
from pyecharts.globals import CurrentConfig

# 關于 CurrentConfig,可參考 [基本使用-全局變量]
CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))

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()

Step 3: 運行項目

$ python server.py

使用瀏覽器打開 http://127.0.0.1:5000 即可訪問服務

Flask 前后端分離

前后端分離可以使用動態(tài)更新數(shù)據(jù),增量更新數(shù)據(jù)等功能。

Step 0,Step 1 參見上面模板渲染章節(jié)內(nèi)容

Step 3: 新建一個 HTML 文件

新建 HTML 文件保存位于項目根目錄的 templates 文件夾,這里以如下 index.html 為例. 主要用到了 ?jquery ?和 ?pyecharts ?管理的 ?echarts.min.js? 依賴

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" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script>
        $(
            function () {
                var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
                $.ajax({
                    type: "GET",
                    url: "http://127.0.0.1:5000/barChart",
                    dataType: 'json',
                    success: function (result) {
                        chart.setOption(result);
                    }
                });
            }
        )
    </script>
</body>
</html>

Step 4: 編寫 flask 和 pyecharts 代碼渲染圖表

請將下面的代碼保存為 app.py 文件并移至項目的根目錄下。

目錄結構如下

sunhailindeMacBook-Pro:pyecharts_flask sunhailin$ tree -L 1
.
├── app.py
└── templates

注: 目前由于 json 數(shù)據(jù)類型的問題,無法將 pyecharts 中的 JSCode 類型的數(shù)據(jù)轉換成 json 數(shù)據(jù)格式返回到前端頁面中使用。因此在使用前后端分離的情況下盡量避免使用 JSCode 進行畫圖。

app.py

from random import randrange

from flask import Flask, render_template

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", [randrange(0, 100) for _ in range(6)])
        .add_yaxis("商家B", [randrange(0, 100) for _ in range(6)])
        .set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", 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()


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

Step 5: 運行項目

$ python app.py

使用瀏覽器打開 http://127.0.0.1:5000 即可訪問服務

定時全量更新圖表

前端主動向后端進行數(shù)據(jù)刷新

定時刷新的核心在于 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" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></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>

定時增量更新圖表

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" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" ></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 random import randrange

from flask.json import jsonify
from flask import Flask, render_template

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


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


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="動態(tài)數(shù)據(jù)"),
            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)})


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


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號