各位读者朋友们,今天是农历新年的第一天,在这里给大家道声:新年好!我们虽未谋面,但见字如面,期待新的一年各位读者朋友继续关注bee君
。
最近两天,翻看下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
.
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类中实现属性自定义。
阅读更多:
《我的Python之路V1.3.pdf》可以下载了,这版pdf更精美!
喜欢就点「在看」吧 !