来源:Python数据之道
作者:Peter
整理:Lemon
饼图在实际的可视化要求中是非常常见的,它能够很好显示个体的占比或者数据情况。本文中讲解的是如何利用 pyecharts
来绘制各种满足不同需求的饼图,包含:
开始之前,先来看看部分效果:
注:文末提供本文的源码获取方式,供大家练习
本文中使用的还是 pandas+pyecharts
组合,在jupyter notebook
中进行绘图。首先导入所需要的各种库:
我们自行模拟了一份消费数据,包含5个消费项目:住宿+餐饮+交通+服装+红包,具体数据如下:
# 生成数据
df = pd.DataFrame({
"消费":["住宿","餐饮","交通","服装","红包"],
"数据":[2580,1300,500,900,1300]
})
df
将消费和数据中的具体数据转成列表形式:
代码的具体解释见注释:
c = (
Pie()
.add("", [list(z) for z in zip(x_data, y_data)]) # zip函数两个部分组合在一起list(zip(x,y))-----> [(x,y)]
.set_global_opts(title_opts=opts.TitleOpts(title="Pie-月度开支")) # 标题
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}")) # 数据标签设置
)
c.render_notebook()
上面生成的饼图是使用 pyecharts 自带的颜色和位置,有时候我们需要做下改变:
现在我们生成的饼图如下显示:
上面的图例是水平方向排列的,而且个数比较少。如果我们的图例比较多,需要改成竖直方向,同时实现翻页滚动功能。
在这里我们使用的是 pyecharts 中自带的数据:
1、Faker.choose()
:是用来生成数据标签,有3种不同的取值情况
2、Faker.values()
是用来生成具体的数据,随机生成
还是通过上面的绘图方法,加入数据同时添加各种配置项:
视频效果如下:环状饼图主要是通过 add
方法中的 radius
参数来实现的。实现过程如下:
x_data = ["小明", "小红", "张三", "李四", "王五"]
y_data = [335, 310, 234, 135, 548]
c = (
Pie(init_opts=opts.InitOpts(width="1600px", height="1000px")) # 图形的大小设置
.add(
series_name="访问来源",
data_pair=[list(z) for z in zip(x_data, y_data)],
radius=["15%", "50%"], # 饼图内圈和外圈的大小比例
center=["30%", "40%"], # 饼图的位置:左边距和上边距
label_opts=opts.LabelOpts(is_show=True), # 显示数据和百分比
)
.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}%)"
),
)
c.render_notebook()
可以看到图形的中间是空的
内嵌饼图是指将两个甚至多个环状饼图放在一起,实现代码过程如下:
import pyecharts.options as opts
from pyecharts.charts import Pie
from pyecharts.globals import ThemeType
# 内部饼图
inner_x_data = ["直达", "营销广告", "搜索引擎","产品"]
inner_y_data = [335, 679, 548, 283]
inner_data_pair = [list(z) for z in zip(inner_x_data, inner_y_data)]
# [['直达', 335], ['营销广告', 679], ['搜索引擎', 1548], [‘产品’, 283]]
# 外部环形(嵌套)
outer_x_data = ["搜索引擎", "邮件营销", "直达", "营销广告", "联盟广告", "视频广告", "产品", "百度", "谷歌","邮件营销", "联盟广告"]
outer_y_data = [335, 135, 147, 102, 220, 310, 234, 135, 648, 251]
outer_data_pair = [list(z) for z in zip(outer_x_data, outer_y_data)]
c = (
# 初始化
Pie(init_opts=opts.InitOpts(
width="900px", # 设置图形大小
height="800px",
theme=ThemeType.SHINE)) # 选择主题
# 内部饼图
.add(
series_name="版本3.2.1", # 图形名称
center=["50%", "35%"], # 饼图位置
data_pair=inner_data_pair, # 系列数据项,格式为 [(key1, value1), (key2, value2)]
radius=["25%", "40%"], # 饼图半径 数组的第一项是内半径,第二项是外半径
label_opts=opts.LabelOpts(position='inner'), # 标签设置在内部
)
# 外部嵌套环形图
.add(
series_name="版本3.2.9", # 系列名称
center=["50%", "35%"], # 饼图位置
radius=["40%", "60%"], # 饼图半径 数组的第一项是内半径,第二项是外半径
data_pair=outer_data_pair, # 系列数据项,格式为 [(key1, value1), (key2, value2)]
# 标签配置项
label_opts=opts.LabelOpts(
position="outside",
formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c} {per|{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {
"color": "#999",
"lineHeight": 22,
"align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {
"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
# 全局配置项
.set_global_opts(
xaxis_opts = opts.AxisOpts(is_show = False), #隐藏X轴刻度
yaxis_opts = opts.AxisOpts(is_show = False), #隐藏Y轴刻度
legend_opts = opts.LegendOpts(is_show = True), #隐藏图例
title_opts = opts.TitleOpts(title = None), #隐藏标题
)
# 系统配置项
.set_series_opts(
tooltip_opts=opts.TooltipOpts(
trigger="item",
formatter="{a}
{b}: {c} ({d}%)"
),
label_opts=opts.LabelOpts(is_show=True) # 隐藏每个触角标签
)
)
c.render_notebook()
视频效果如下:
有时候我们需要将多个图形放在一个大画布中,需要用到子图的制作。
在下面的代码中每个 add()
都是一个图形的绘制,我们绘制了4个饼图;同时center指定每个图形的位置,radius指定每个饼图内外圈的大小
c = (
Pie()
.add(
"",
[list(z) for z in zip(["剧情", "其他"], [30, 70])],
center=["20%", "30%"], # 位置
radius=[60, 80], # 每个饼图内外圈的大小
)
.add(
"",
[list(z) for z in zip(["奇幻", "其他"], [40, 60])],
center=["55%", "30%"],
radius=[60, 80],
)
.add(
"",
[list(z) for z in zip(["爱情", "其他"], [24, 76])],
center=["20%", "70%"],
radius=[60, 80],
)
.add(
"",
[list(z) for z in zip(["惊悚", "其他"], [11, 89])],
center=["55%", "70%"],
radius=[60, 80],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Pie-多饼图基本示例"),
legend_opts=opts.LegendOpts(
type_="scroll", pos_top="20%", pos_left="80%", orient="vertical"
),
)
)
c.render_notebook()
视频效果如下:
玫瑰图中每个部分的大小和粗细都是不同的
v = Faker.choose()
c = (
Pie()
.add(
"",
[list(z) for z in zip(v, Faker.values())], # 两个值
radius=["30%", "60%"], # 大小
center=["25%", "50%"], # 位置
rosetype="radius",
label_opts=opts.LabelOpts(is_show=False), # 不在图形上显示数据
)
.add(
"",
[list(z) for z in zip(v, Faker.values())],
radius=["30%", "60%"],
center=["75%", "50%"],
rosetype="area",
)
.set_global_opts(title_opts=opts.TitleOpts(title="Pie-玫瑰图示例"))
)
c.render_notebook()
视频效果如下:
作者简介
Peter,硕士毕业僧一枚,从电子专业自学Python入门数据行业,擅长数据分析及可视化。喜欢数据,坚持跑步,热爱阅读,乐观生活。个人格言:不浮于世,不负于己
个人站点:www.renpeter.cn,欢迎常来小屋逛逛
我是东哥,最后给大家免费分享入门Python的最强三件套:《ThinkPython》、《简明Python教程》、《Python进阶》的PDF电子版。如果你是刚入门的小白,不用想了,这是最好的学习教材。
现在免费分享出来,有需要的读者可以下载学习,在下面的公众号GitHuboy里回复关键字:Python,就行。
推荐阅读
逻辑回归 + GBDT模型融合实战!
微软开源最强Python自动化神器!不用写一行代码!
3 行Python代码获取海量数据
爱了!Python 动态图表太太太秀了!
年终述职报告就这么写(实操版)
Kaggle竞赛:Python银行信用卡客户流失预测
超赞!20个炫酷的数据可视化大屏(含源码)
?分享、点赞、在看,给个三连击呗!?