1. 程式人生 > 程式設計 >利用 Flask 動態展示 Pyecharts 圖表資料的幾種方法

利用 Flask 動態展示 Pyecharts 圖表資料的幾種方法

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

Flask 模板渲染

1. 新建一個專案 flask-echarts

在編輯器中選擇 New Project,然後選擇 Flask,建立完之後,Pycharm 會幫我們把啟動指令碼和模板資料夾都建好

2. 拷貝 pyecharts 模板

將連結中的以下模板 ├── jupyter_lab.html ├── jupyter_notebook.html ├── macro ├── nteract.html ├── simple_chart.html ├── simple_page.html └── table.html 全部拷貝到 tempaltes 資料夾中 github.com/pyecharts/p…

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

直接執行,在瀏覽器中輸入地址,直接將資料顯示出來了

這是一個很簡單的靜態資料展示,別急好戲還在後頭~

Flask 前後端分離

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

index.html

<!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 中我們也需要做相應的修改,新增該地址的路由函式,從而實現動態資料更新。 部分程式碼如下:

@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 地址傳過來的引數,動態展示圖表資料。結果如下:

這裡只是簡單演示,所以只將圖表標題作為動態傳參。此場景適用於第一次請求獲取我們想要的資料,然後將其展示出來。比如我之前寫的 NBA 球員資料視覺化 mp.weixin.qq.com/s/WWCNf46Ch…

就是此方法,不同球員展示對應球員資料!

定時全量更新圖表

該場景主要是前端主動向後端進行資料重新整理,定時重新整理的核心在於 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",
success: function (result) {
chart.setOption(result);
}
});
}
</script>
</body>
</html>

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

def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["襯衫",[random.randint(10,100) for _ in range(6)])
.add_yaxis("商家B",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'),{renderer: 'canvas'});
var old_data = [];
$(
function () {
fetchData(chart);
setInterval(getDynamicData,
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",
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)})

走起,來看看效果吧