广告区
- pyecharts 项目地址:右转仓库看看 --> pyecharts 1.0.0
- pyecharts-gallery 项目地址:右转仓库看看 --> pyecharts-gallery
谈谈 pyecharts ?
pyecharts
现阶段分为 0.5.X
和 1.0.0+
,经过长时间的重构以后,在写法上和以前大有不同。
- 新版文档将继续沿用 1.0.0 之后的文档
- 旧版文档已迁移至 0.5.X 之前的文档
- 目前
1.0.0
版本已经发布了,欢迎用过 0.5.X
之前版本和还没用过 pyecharts
的童鞋们来感受一下新版带来的体验?
- [关键点]
pyecharts 1.0.0+
只支持 Python 3.6+
,如果 Python
版本还在 3.6
一下的可以选择升级 Python
版本或者使用 0.5.X
以下的 pyecharts
- [敲黑板] 现阶段的
pyecharts
还没有完全的把 Echarts
所有配置,所以在有些样式或者小功能点上还没有实现,也请各位童鞋多多包涵。?
- [再多说一句] 有好的想法先看一下
Echarts
能否实现哈?
对比新旧版本之间的代码差异
from pyecharts import Bar
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
bar = Bar("柱状图数据堆叠示例")
bar.add("商家A", attr, v1, is_stack=True)
bar.add("商家B", attr, v2, is_stack=True)
bar.render()
复制代码
import pyecharts.options as opts
from pyecharts.charts import Bar
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
(
Bar()
.add_xaxis(attr)
.add_yaxis("商家A", v1, stack="stack1")
.add_yaxis("商家B", v2, stack="stack1")
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(title_opts=opts.TitleOpts(title="柱状图数据堆叠示例"))
.render("bar_stack.html")
)
复制代码
- 说明:
- 首先,两者在渲染的效果上都是一样的,只是在代码编写风格层面有很大的改观。
- 其次,顶层代码编写采用了链式写法,底层代码实际上在类层面的每一个可调用的方法返回的是一个
self
, 而链式写法的好处在于编写代码时条理更清晰。
- 最后,强力推荐 Type Hints,这次重构以后的代码内部强制使用 Type Hints,对开发者和使用者都是一件好事,毕竟参数存在复合类型的情况。
谈谈 pyecharts-gallery
- 项目的意义:
Echarts
有 Echarts Community Gallery
。因此 pyecharts
在使用者多了以后也应该有一个专属于 pythoner
自己的 pyecharts-gallery
。
- 项目的进度:
- 目前基本上使用
pyecharts
实现了大部分 Echarts
的官方实例,剩下的现阶段能够实现的还在补充中~
- 目前暂时实现不了的小功能和图,基本上是
pyecharts
缺少了对应的配置项 (例如旭日图和富文本以及 Graphic 图例)
举几个特别的实例看看
from __future__ import unicode_literals
import asyncio
from aiohttp import TCPConnector, ClientSession
import pyecharts.options as opts
from pyecharts.charts import Graph
async def get_json_data(url: str) -> dict:
async with ClientSession(connector=TCPConnector(ssl=False)) as session:
async with session.get(url=url) as response:
return await response.json()
data = asyncio.run(
get_json_data(
url="https://echarts.baidu.com/examples/data/asset/data/npmdepgraph.min10.json"
)
)
nodes = [
{
"x": node["x"],
"y": node["y"],
"id": node["id"],
"name": node["label"],
"symbolSize": node["size"],
"itemStyle": {"normal": {"color": node["color"]}},
}
for node in data["nodes"]
]
edges = [
{"source": edge["sourceID"], "target": edge["targetID"]} for edge in data["edges"]
]
(
Graph(init_opts=opts.InitOpts(width="1600px", height="800px"))
.add(
series_name="",
nodes=nodes,
links=edges,
layout="none",
is_roam=True,
is_focusnode=True,
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7),
)
.set_global_opts(title_opts=opts.TitleOpts(title="NPM Dependencies"))
.render("npm_dependencies.html")
)
复制代码
from __future__ import unicode_literals
import pyecharts.options as opts
from pyecharts.charts import Pie
"""
Gallery 使用 pyecharts 1.0.0
参考地址: https://echarts.baidu.com/examples/editor.html?c=pie-nest
目前无法实现的功能:
1、富文本的 label 暂时没有配置项
"""
inner_x_data = ["直达", "营销广告", "搜索引擎"]
inner_y_data = [335, 679, 1548]
inner_data_pair = [list(z) for z in zip(inner_x_data, inner_y_data)]
outer_x_data = ["直达", "营销广告", "搜索引擎", "邮件营销", "联盟广告", "视频广告", "百度", "谷歌", "必应", "其他"]
outer_y_data = [335, 310, 234, 135, 1048, 251, 147, 102]
outer_data_pair = [list(z) for z in zip(outer_x_data, outer_y_data)]
(
Pie(init_opts=opts.InitOpts(width="1600px", height="800px"))
.add(
series_name="访问来源",
data_pair=inner_data_pair,
radius=[0, "30%"],
label_opts=opts.LabelOpts(position="inner"),
)
.add(
series_name="访问来源",
radius=["40%", "55%"],
data_pair=outer_data_pair,
label_opts=opts.LabelOpts(formatter="{a} - {b} - {c} - {d}"),
)
.set_global_opts(legend_opts=opts.LegendOpts(pos_left="left", orient="vertical"))
.set_series_opts(
tooltip_opts=opts.TooltipOpts(
trigger="item", formatter="{a}
{b}: {c} ({d}%)"
)
)
.render("nested_pies.html")
)
复制代码
from __future__ import unicode_literals
import asyncio
from aiohttp import TCPConnector, ClientSession
import pyecharts.options as opts
from pyecharts.charts import Tree
async def get_json_data(url: str) -> dict:
async with ClientSession(connector=TCPConnector(ssl=False)) as session:
async with session.get(url=url) as response:
return await response.json()
data = asyncio.run(
get_json_data(url="https://echarts.baidu.com/examples/data/asset/data/flare.json")
)
(
Tree(init_opts=opts.InitOpts(width="1400px", height="800px"))
.add(
series_name="",
data=[data],
pos_top="18%",
pos_bottom="14%",
layout="radial",
symbol="emptyCircle",
symbol_size=7,
)
.set_global_opts(
tooltip_opts=opts.TooltipOpts(trigger="item", trigger_on="mousemove")
)
.render("radial_tree.html")
)
复制代码
- 4、issue 里面比较多提到的双 Y 轴或者多 Y 轴的图
- 补充一下
offset
这个参数目前发布的 1.0.0
还没有,目前更新的源码活在 dev
的分支上
from __future__ import unicode_literals
import pyecharts.options as opts
from pyecharts.charts import Bar, Line
"""
Gallery 使用 pyecharts 1.0.0
参考地址: https://www.echartsjs.com/examples/editor.html?c=multiple-y-axis
目前无法实现的功能:
1、yaxis_opts 需要增加 offset 参数
"""
colors = ['#5793f3', '#d14a61', '#675bba']
x_data = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
legend_list = ['蒸发量', '降水量', '平均温度']
evaporation_capacity = [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
rainfall_capacity = [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
average_temperature = [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
bar = (
Bar(init_opts=opts.InitOpts(width="1680px", height="800px"))
.add_xaxis(
xaxis_data=x_data
)
.add_yaxis(
series_name="蒸发量",
yaxis_data=evaporation_capacity,
yaxis_index=0,
color=colors[1]
)
.add_yaxis(
series_name="降水量",
yaxis_data=rainfall_capacity,
yaxis_index=1,
color=colors[0]
)
.extend_axis(
yaxis=opts.AxisOpts(
name="蒸发量",
type_="value",
min_=0,
max_=250,
position="right",
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(color=colors[1])
),
axislabel_opts=opts.LabelOpts(
formatter="{value} ml"
)
)
)
.extend_axis(
yaxis=opts.AxisOpts(
type_="value",
name="温度",
min_=0,
max_=25,
position="left",
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(color=colors[2])
),
axislabel_opts=opts.LabelOpts(
formatter="{value} °C"
),
splitline_opts=opts.SplitLineOpts(
is_show=True,
linestyle_opts=opts.LineStyleOpts(
opacity=1
)
)
)
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
type_="value",
name="降水量",
min_=0,
max_=250,
position="right",
offset=80,
axisline_opts=opts.AxisLineOpts(
linestyle_opts=opts.LineStyleOpts(color=colors[0])
),
axislabel_opts=opts.LabelOpts(
formatter="{value} ml"
),
),
tooltip_opts=opts.TooltipOpts(
trigger="axis",
axis_pointer_type="cross"
),
)
)
line = (
Line()
.add_xaxis(
xaxis_data=x_data
)
.add_yaxis(
series_name="平均温度",
y_axis=average_temperature,
yaxis_index=2,
color=colors[2],
)
)
bar.overlap(line).render("multiple_y_axes.html")
复制代码
- 5、双 X 轴
- 需要改动一下源码
line.py
(第 61 行, 改为 data = y_axis
)。
- 如果不想改动源码的话,示例代码第 55 行,去掉
xaxis_index
这个参数。这样子之后 axisPointer
的数据显示会有点问题。(问题原因就是数据格式的问题,因为 Line
的源码里头把 x
和 y
的数据合并了)
from __future__ import unicode_literals
import pyecharts.options as opts
from pyecharts.charts import Line
from pyecharts.commons.utils import produce_js_func
"""
Gallery 使用 pyecharts 1.0.0
参考地址: https://echarts.baidu.com/examples/editor.html?c=multiple-x-axis
目前无法实现的功能:
1、暂无
"""
js_formatter = """function (params) {
console.log(params);
return '降水量 ' + params.value + (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}"""
(
Line(init_opts=opts.InitOpts(width="1600px", height="800px"))
.add_xaxis(
xaxis_data=[
"2016-1", "2016-2", "2016-3", "2016-4", "2016-5", "2016-6",
"2016-7", "2016-8", "2016-9", "2016-10", "2016-11", "2016-12",
]
)
.extend_axis(
xaxis_data=[
"2015-1", "2015-2", "2015-3", "2015-4", "2015-5", "2015-6",
"2015-7", "2015-8", "2015-9", "2015-10", "2015-11", "2015-12",
],
xaxis=opts.AxisOpts(
type_="category",
axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
axisline_opts=opts.AxisLineOpts(
is_on_zero=False, linestyle_opts=opts.LineStyleOpts(color="#6e9ef1")
),
axispointer_opts=opts.AxisPointerOpts(
is_show=True,
label=opts.LabelOpts(
formatter=produce_js_func(js_formatter)
),
),
),
)
.add_yaxis(
series_name="2015 降水量",
is_smooth=True,
symbol="emptyCircle",
is_symbol_show=False,
xaxis_index=1,
color="#d14a61",
y_axis=[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2),
)
.add_yaxis(
series_name="2016 降水量",
is_smooth=True,
symbol="emptyCircle",
is_symbol_show=False,
color="#6e9ef1",
y_axis=[3.9, 5.9, 11.1, 18.7, 48.3, 69.2, 231.6, 46.6, 55.4, 18.4, 10.3, 0.7],
label_opts=opts.LabelOpts(is_show=False),
linestyle_opts=opts.LineStyleOpts(width=2),
)
.set_global_opts(
legend_opts=opts.LegendOpts(
),
tooltip_opts=opts.TooltipOpts(trigger="none", axis_pointer_type="cross"),
xaxis_opts=opts.AxisOpts(
type_="category",
axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
axisline_opts=opts.AxisLineOpts(
is_on_zero=False, linestyle_opts=opts.LineStyleOpts(color="#d14a61")
),
axispointer_opts=opts.AxisPointerOpts(
is_show=True,
label=opts.LabelOpts(
formatter=produce_js_func(js_formatter)
),
),
),
yaxis_opts=opts.AxisOpts(
type_="value",
splitline_opts=opts.SplitLineOpts(
is_show=True,
linestyle_opts=opts.LineStyleOpts(opacity=1)
)
),
)
.render("multiple_x_axes.html")
)
复制代码
最后说两句
- 目前
pyecharts-gallery
一直持续在更新,也欢迎大家分享一些自己的示例和使用感受。?
- 与此同时,我也在不停的参与
pyecharts
的优化和更新,希望能够推动这个库成为 Python
最好用的数据可视化的库之一。?
- 最后的最后,也欢迎各位开发者能够加入到
pyecharts
的开发中来,欢迎大家多多提供 PR 和 Issue。?