来源:Python数据之道
作者:Peter
整理:Lemon
利用Pyecharts玩转饼图
饼图在实际的可视化要求中是非常常见的,它能够很好显示个体的占比或者数据情况。本文中讲解的是如何利用 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} <br/>{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} <br/>{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,欢迎常来小屋逛逛
本文来自公众号读者投稿,欢迎各位童鞋向公号投稿,点击下面图片了解详情!
源码文件获取
为方便大家练习,已将整理好的源代码(jupyter notebook文件)分享给各位同学,大家可以在下面的公众号 「柠檬数据」 回复 pie2020 来获取。
转载:https://blog.csdn.net/lemonbit/article/details/111148340