前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pyecharts原来可以这样快速入门

pyecharts原来可以这样快速入门

作者头像
double
发布2020-02-21 16:30:37
1.3K0
发布2020-02-21 16:30:37
举报
文章被收录于专栏:算法channel算法channel

最近两天,翻看下pyecharts的源码,感叹这个框架写的真棒,思路清晰,设计简洁,通俗易懂,推荐读者们有空也阅读下。

bee君是被pyecharts官档介绍-五个特性所吸引:

1)简洁的 API 设计,使用如丝滑般流畅,支持链式调用;

2)囊括了 30+ 种常见图表,应有尽有;

3)支持主流 Notebook 环境,Jupyter Notebook 和 JupyterLab;

4)可轻松集成至 Flask,Django 等主流 Web 框架;

5)高度灵活的配置项,可轻松搭配出精美的图表

pyecharts确实也如上面五个特性介绍那样,使用起来非常方便。那么,有些读者不禁好奇会问,pyecharts是如何做到的?

我们不妨从pyecharts官档5分钟入门pyecharts章节开始,由表(最高层函数)及里(底层函数也就是所谓的源码),一探究竟。

第一个例子

不妨从官档给出的第一个例子说起,

from pyecharts.charts import Bar

bar = Bar()
bar.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
# render 会生成本地 HTML 文件,默认会在当前目录生成 render.html 文件
# 也可以传入路径参数,如 bar.render("mycharts.html")
bar.render()

第一行代码:from pyecharts.charts import Bar,先上一张源码中包的结构图

图1

bar.py模块中定义了类Bar(RectChart),如下所示:

class Bar(RectChart):
    """
    <<< Bar Chart >>>

    Bar chart presents categorical data with rectangular bars
    with heights or lengths proportional to the values that they represent.
    """

这里有读者可能会有以下两个问题:

1)为什么根据图1中的包结构,为什么不这么写:from pyecharts.charts.basic_charts import Bar

图2

答:请看图2中__init__.py模块,文件内容如下,看到导入charts包,而非charts.basic_charts

from pyecharts import charts, commons, components, datasets, options, render, scaffold
from pyecharts._version import __author__, __version__

2)Bar(RectChart)是什么意思

答:RectChart是Bar的子类

下面4行代码,很好理解,没有特殊性。

第一个例子的改写

pyecharts主要两个大版本,0.5基版本和1.0基版本,从1.0基版本开始全面支持链式调用,bee君也很喜爱这种链式调用模式,代码看起来更加紧凑:

from pyecharts.charts import Bar

bar = (
    Bar()
    .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
    .add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
)
bar.render()

实现链式调用也没有多难,保证返回类本身self即可,如果非要有其他返回对象,那么要提到类内以便被全局共享,

add_xaxis函数返回self

    def add_xaxis(self, xaxis_data: Sequence):
        self.options["xAxis"][0].update(data=xaxis_data)
        self._xaxis_data = xaxis_data
        return self

add_yaxis函数同样返回self.

一切皆options

pyecharts用起来很爽的另一个重要原因,参数配置项封装的非常nice,通过定义一些列基础的配置组件,比如global_options.py模块中定义的配置对象有以下27

    AngleAxisItem,
    AngleAxisOpts,
    AnimationOpts,
    Axis3DOpts,
    AxisLineOpts,
    AxisOpts,
    AxisPointerOpts,
    AxisTickOpts,
    BrushOpts,
    CalendarOpts,
    DataZoomOpts,
    Grid3DOpts,
    GridOpts,
    InitOpts,
    LegendOpts,
    ParallelAxisOpts,
    ParallelOpts,
    PolarOpts,
    RadarIndicatorItem,
    RadiusAxisItem,
    RadiusAxisOpts,
    SingleAxisOpts,
    TitleOpts,
    ToolBoxFeatureOpts,
    ToolboxOpts,
    TooltipOpts,
    VisualMapOpts,

第二个例子

了解上面的配置对象后,再看官档给出的第二个例子,与第一个例子相比,增加了一行代码:set_global_opts函数

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

# V1 版本开始支持链式调用
# 你所看到的格式其实是 `black` 格式化以后的效果
# 可以执行 `pip install black` 下载使用
bar = (
    Bar()
    .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
    .add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
    .set_global_opts(title_opts=opts.TitleOpts(title="主标题", subtitle="副标题"))
    
bar.render()

set_global_opts函数在pyecharts中被高频使用,它定义在底层基础模块Chart.py中,它是前面说到的RectChart的子类,Bar类的孙子类。

浏览下这个函数的参数

def set_global_opts(
        self,
        title_opts: types.Title = opts.TitleOpts(),
        legend_opts: types.Legend = opts.LegendOpts(),
        tooltip_opts: types.Tooltip = None,
        toolbox_opts: types.Toolbox = None,
        brush_opts: types.Brush = None,
        xaxis_opts: types.Axis = None,
        yaxis_opts: types.Axis = None,
        visualmap_opts: types.VisualMap = None,
        datazoom_opts: types.DataZoom = None,
        graphic_opts: types.Graphic = None,
        axispointer_opts: types.AxisPointer = None,
    ):

以第二个参数title_opts为例,说明pyecharts中参数赋值的风格。

首先,title_opts默认参数,默认值为opts.TitleOpts(),这个对象在上一节中,我们提到过,是global_options.py模块中定义的27个配置对象种的一个。

其次,pyecharts中为了增强代码可读性,参数的类型都显示的给出。此处它的类型为:types.Title. 这是什么类型?它的类型不是TitleOpts吗?不急,看看Title这个类型的定义:

Title = Union[opts.TitleOpts, dict]

原来Title可能是opts.TitleOpts, 也可能是python原生的dict. 通过Union实现的就是这种类型效果。所以这就解释了官档中为什么说也可以使用字典配置参数的问题,如下官档:

    # 或者直接使用字典参数
    # .set_global_opts(title_opts={"text": "主标题", "subtext": "副标题"})
)

最后,真正的关于图表的标题相关的属性都被封装到TitleOpts类中,比如title,subtitle属性,查看源码,TitleOpts对象还有更多属性:

class TitleOpts(BasicOpts):
    def __init__(
        self,
        title: Optional[str] = None,
        title_link: Optional[str] = None,
        title_target: Optional[str] = None,
        subtitle: Optional[str] = None,
        subtitle_link: Optional[str] = None,
        subtitle_target: Optional[str] = None,
        pos_left: Optional[str] = None,
        pos_right: Optional[str] = None,
        pos_top: Optional[str] = None,
        pos_bottom: Optional[str] = None,
        padding: Union[Sequence, Numeric] = 5,
        item_gap: Numeric = 10,
        title_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
        subtitle_textstyle_opts: Union[TextStyleOpts, dict, None] = None,
    ):

小结

OK. 到此跟随5分钟入门的官档,结合两个例子实现的背后源码,探讨了:

1)与包结构组织相关的__init__.py;2)类的继承关系:Bar->RectChart->Chart;3)链式调用;4)重要的参数配置包options,以TitleOpts类为例,set_global_opts将它装载到Bar类中实现属性自定义。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员郭震zhenguo 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一个例子
  • 第一个例子的改写
  • 一切皆options
  • 第二个例子
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档