Flask数据可视化

在Web开发过程中遇到要做些数据可视化工作,对于我来说,基本上后端使用Pyecharts配合着前端echarts.js实现数据可视化工作。

Pyechats介绍

✨ 特性

  • 简洁的 API 设计,使用如丝滑般流畅,支持链式调用
  • 囊括了 30+ 种常见图表,应有尽有
  • 支持主流 Notebook 环境,Jupyter Notebook 和 JupyterLab
  • 可轻松集成至 Flask,Django 等主流 Web 框架
  • 高度灵活的配置项,可轻松搭配出精美的图表
  • 详细的文档和示例,帮助开发者更快的上手项目
  • 多达 400+ 地图文件以及原生的百度地图,为地理数据可视化提供强有力的支持

版本
Pyechats有两个大版本,分为v0.5.X和v1。这两个版本像python2python3一样相互不兼容,而且v1版本使用了python3.6+更新新的语法特性,所以v1版本只支持python3.6+。

Pyecharts使用

在Web开发过程中,两个版本的Pyechats都使用过,使用的场景也不同。

场景一:Top10柱状图展示

在一次爬虫数据展示中,爬取诗词名句网中诗人作品,并将作品数量前十的诗人展示出来。那时,还是第一次使用pyechats,使用的是0.5.1版本,可以说,第一次接触可视化工具,对于前端知识不怎么了解的我,使用起来还是非常方便的。对于这个场景,通过导入相应的图表如使用如:

1
Bar     柱状图
2
Pie     饼状图
3
Line    折线图

主要使用这些图,还有其他图表如:Funnel(漏斗图)Gauge(仪表盘)等等,如果有需要,详情请见Pyechats基本图表

  • 后端
  1. 导入柱状图表Bar类,以及页面Page
    1
    from pyecharts import Bar, Page
  2. 定义一个函数,从数据库中查询数据,返回返回Bar的实例
    1
    def get_bar():
    2
        poets = Poet.query.order_by(Poet.num.desc()).limit(10)  #获取诗人作品量前十的诗人
    3
        attr_poet = []    #定义x轴数据,诗人姓名
    4
        num_poet = []   #定义y轴数据,诗人作品数
    5
        for poet in poets:   
    6
            attr_poet.append(poet.name)   #填充x轴数据
    7
            num_poet.append(poet.num)      #填充y轴数据
    8
        bar = Bar("作诗数前十名诗人")    #实例
    9
        bar.add("", attr_poet, num_poet, is_label_show=True, center=[50,50])  #将数据添加
    10
        return bar   #返回实例
  3. 在视图中渲染给前端
    1
    @app.route('/search/')
    2
    def search():
    3
        page = Page()  #创建一个页面实例
    4
        bar = get_bar()   #执行函数,得到Bar实例
    5
        page.add(bar)   #将图表添加带页面类中,如果页面中有多个图:page.add([bar1, bar2, ....])
    6
        return render_template('search.html', chart=page.render_embed())  #渲染页面,返回chart
  • 前端
  1. 导入echarts.js
    1
    <script src="{{ url_for('static', filename='js/echarts.min.js') }}"></script>
  2. 在相应位置使用Jinja2语法引用chart
    1
    <div>
    2
        {{ chart|safe }}
    3
    </div>
    这样就实现数据展示,展示如下:
    作诗数前十诗人
    如果有兴趣研究项目地址如下:shicimingju

场景二:数据实时展示

在近期的项目中,遇到了要实时更新的数据,类似实时展示24小时用户在线数量,这样的话每一个小时都要向后端请求一次数据,然后重新渲染图表,实现效果如下;
今日在线人数
配合着Layui的轮播图展示,为了实现这个功能,我使用了v1的版本,这个相比于0.5版本,这个版本的实现效果更佳深入用户体验。实现这个功能使用Pyecharts也非常方便。

  • 后端
    因为v1版本对代码进行了重构,所有导包方式也发生了变化
  1. 新版本的Pyecharts将图表封装到pyecharts.charts这个文件中,将配置封装到options文件中,将两者分开,所以导包时:
    1
    from pyecharts import options as opts
    2
    from pyecharts.charts import Line
  2. 0.5版本类似,首先写个函数创建图表,由于还没正式上线,所以为假数据。
    1
    def bar_base() -> Line:
    2
        c = (
    3
            Line()
    4
                .add_xaxis(xaxis_data=list(map(lambda x: '{}:00'.format(x), [i for i in range(25)])))
    5
                .add_yaxis("在线人数", [random.randint(25, 150) for _ in range(25)], is_smooth=True, color='#66CDAA',
    6
                           label_opts=opts.LabelOpts(is_show=False))
    7
                .set_series_opts(
    8
                areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
    9
            )
    10
                .set_global_opts(
    11
                title_opts=opts.TitleOpts(title="今日在线人数", pos_left='43%', pos_top='8%'),
    12
                xaxis_opts=opts.AxisOpts(
    13
                    axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
    14
                    is_scale=False,
    15
                    boundary_gap=False,
    16
                ),
    17
                legend_opts=opts.LegendOpts(is_show=False),
    18
            )
    19
        )
    20
        return c
  3. 定义一个视图函数进行,进行与前端交互
    1
    @bp.route("/barChart")
    2
    @login_required
    3
    def get_bar_chart():
    4
        c = bar_base()
    5
        return c.dump_options()
  • 前端
  1. 引用echarts.js

    1
    <script src="{{ url_for('static', filename='common/echarts.min.js') }}"></script>
  2. 结合Layui的轮播图,将生成的图表放入轮播图中

    1
    <div class="layui-carousel" id="test1" lay-filter="test1">
    2
           <div carousel-item="">
    3
                  <div id="bar" style="background-image: url('{{ static('admin/img/timg.gif') }}');"></div>
    4
                         <div>条目2</div>
    5
                         <div>条目3</div>
    6
                          <div>条目4</div>
    7
                          <div>条目5</div>
    8
                   </div>
    9
          </div>
  3. 通过JS实现AJAX轮询操作

    1
    2
        var chart = echarts.init(document.getElementById('bar'), 'essos', {renderer: 'canvas'});
    3
        window.onresize = function(){
    4
          chart.resize();
    5
        };
    6
        chart.setOption({
    7
    8
            toolbox: {
    9
                show: true,
    10
                feature: {
    11
                    mark: {show: true},
    12
                    dataView: {show: true, readOnly: false},
    13
                    magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
    14
                    restore: {show: true},
    15
                    saveAsImage: {show: true}
    16
                }
    17
            },
    18
        });
    19
        $(
    20
            function () {
    21
                fetchData(chart);
    22
                setInterval(fetchData, 1000 * 60);
    23
            }
    24
        );
    25
    26
        function fetchData() {
    27
            $.ajax({
    28
                type: "GET",
    29
                url: "/barChart",
    30
                dataType: 'json',
    31
                success: function (result) {
    32
                    chart.setOption(result);
    33
                }
    34
            });
    35
        }
    36
    });

    这样就可以实现相应的功能了。

总结

在开发过程中,使用过多次Pyecharts,通过记录这两次场景应用,方便以后的学习,数据可视化还需要更深入的研究,以后还会继续学习相关知识。