使用Pyecharts和Flask进行数据可视化

项目git地址:

https://bitbucket.org/hfut/xian

由于是比赛项目,目前还是private项目,过一段时间再改成public~


Echarts是百度开源的一款很出名的图标库,可以用它来进行数据可视化。要把它同flask整合起来,提供web数据可视化服务,我一开始的思路是利用flask的jinja2模板引擎,直接生成js代码,交由用户浏览器渲染展示。但是这样template文件就太过于复杂,超级容易出错。

后来找到了PyEcharts库,它是对Echarts的python封装,可以用python的语法来生成echarts源码,并且提供了一系列的类库,可以方便的与flask结合。

Flask 默认采用 jinja2 作为其模板引擎。根据 Flask 文档,可以在 Flask.jinja_environment ,指定自己实现的模板引擎类,以实现特定功能。

在 Flask 中可按下列步骤实现自己的模板引擎类:

  • 创建一个继承自 flask.templating.Environment 的模板引擎类FlaskEchartsEnvironment 。
  • 在构造函数 init 中,为该类添加 pyecharts_config 属性, 添加模板函数到全局字典中。
  • 在自己的 Flask 应用类中指定 FlaskEchartsEnvironment 为默认模板引擎。
<code class="python">from flask import Flask, render_template
from flask.templating import Environment

from pyecharts import HeatMap
from pyecharts.engine import ECHAERTS_TEMPLATE_FUNCTIONS
from pyecharts.conf import PyEchartsConfig

class FlaskEchartsEnvironment(Environment):
    def __init__(self, *args, **kwargs):
        super(FlaskEchartsEnvironment, self).__init__(*args, **kwargs)
        self.pyecharts_config = PyEchartsConfig(jshost='https://cdn.bootcss.com/echarts/3.7.2')
        self.globals.update(ECHAERTS_TEMPLATE_FUNCTIONS)

class MyFlask(Flask):
    jinja_environment = FlaskEchartsEnvironment
@app.route('/')
def index():
    hm=create_heatmap()
    return render_template('index.html',hm=hm)


app = MyFlask(__name__)

这样,就可以再template文件中,方便的使用模板函数

<code class="html">
<html lang="zh-CN">

    <meta charset="UTF-8">
    <title>自定义模板</title>
    {{ echarts_js_dependencies(hm) }}


    <p>在 Flask 下使用 echarts_* 系列模板函数(Template Functions)渲染页面。</p>
    {{ echarts_container(hm) }}
    {{ echarts_js_content(hm) }}


页面展示

缺点

当然,使用Pyecharts库虽然很方便,但是也存在其不足。

**一是无法做到图表的高度定制化。**Pyecharts只提供了几种常用的图形,提供修改的选项也并不多,并不能像js代码那样随心所欲的更改样式,面对复杂的制图需求,可能就显得捉襟见肘。这其实也挺正常,本来Python只是一个后台语言,要干js这种前端语言的事情就显得力不从心了。

flask数据可视化最佳的解决方式是:前后端完全分离,不碰template模板,后台用flask写restful api,前端用vue/react等框架,调用api生成图表。

但是由于我目前不懂js,所以只好采用了这种折衷的办法,还好制图要求并不高,也够用,看来也要学习一下js/vue。

二是Pyecharts由个人维护,并不稳定 这次在使用pyecharts的过程中,碰到了一个bug,geo的value会出现多次,找了半天发现并不是我代码的问题,去pyecharts的github主页查看,发现作者提交的issue,显示这是一个bug,目前已经在develop分支fix。但是我用的pip源是stable版,还需要我clone这个仓库重新编译安装,最后才解决这个问题。