基于Pyhton的方格百分比图绘制
一、实验目的
1.掌握seaborn库
2.掌握百分比方格图的基本知识和使用,并基于python实现百分比方格图的绘制
二、实验设备与器件
PC机、TempoAI平台
三、实验内容
百分比方格图及Python库介绍
方格百分比图,又名华夫饼图(Waffle Chart),有的人也会叫它“Square Pie Chart”,是饼图的一种变形,擅长展示部分在整体中的占比关系。一般来说,方格百分比图是由100个格子组成,一个格子代表“1%”。用不同颜色的格子区分不同的分类数据,以展示各部分在整体中的占比。下面我们看一个百分比图的例子:
可以看出,在方格百分比图中,我们可以清楚地观察到数据的分布信息。 PyWaffle是一个麻省理工学院许可的开源Python 包, 可用于绘制华夫饼图表。我们使用PyWaffle构造图表后,可传递到matplotlib.pyplot.figure
中,进行结果显示。我们可以使用pip install pywaffle
方便地安装PyWaffle库。
!pip install pywaffle
下面我们就开始使用该库掌握百分比方格图的绘制吧。
百分比方格图的基本绘制
下面的代码用于构建一个百分比方格图类,并将其展示出来。我们绘制一个五行二十列的百分比方格,并显示3个类别的占比情况,假设这三个类别为最近一百天内的天气情况,·晴天:雨天:多云 = 48:46:6
# 导入库
import matplotlib.pyplot as plt
from pywaffle import Waffle
# 在制作百分比方格图时,我们只需要把Waffle类传到plt,即可进行完成初始化
plt.figure(
FigureClass=Waffle,
# 设定行列数
rows=10,
columns=10,
values=[48, 46, 6]
)
plt.show()
上图中,虽然数据的对比是直观的,但我们并没有用标签来指示各个数据代表的含义,因此我们可以为上图添加标签:
plt.figure(
FigureClass=Waffle,
rows=10,
columns=10,
# 为数据添加标签
values={'Sun': 48, 'Rain': 46, 'Cloud': 6},
# 设置图例的位置
legend={'loc': 'upper left', 'bbox_to_anchor': (1, 1)},
)
plt.show()
我们还可以更改图标的形状用来更生动地展示效果:
plt.figure(
FigureClass=Waffle,
rows=5,
values=[48, 46, 6],
# 十六进制的颜色
colors=["#FFA500", "#4384FF", "#C0C0C0"],
# 指定晴天,阵雨,多云的图标
icons=['sun', 'cloud-showers-heavy', 'cloud'],
font_size=12,
# 图标为实心
icon_style='solid',
icon_legend=True,
legend={
'labels': ['Sun', 'Shower', 'Cloud'],
'loc': 'upper left',
'bbox_to_anchor': (1, 1)},
dpi=120
)
plt.show()
使用百分比方格图展示投票情况
现在假设我们有一组投票数据,里面包含了三个地区对总统候选人的投票情况,我们想要使用百分比方格图去形象地展示出这组数据的分布,我们应该进行哪些操作呢,下面就让我们进行该任务的实现。
首先,我们先定义一下数据:
import pandas as pd
# 使用Pandas的DataFrame创建数据
data = pd.DataFrame(
{
'labels': ['Hillary Clinton', 'Donald Trump', 'Others'], # 候选人
'Virginia': [1981473, 1769443, 233715], # 第一个地区的投票人数
'Maryland': [1677928, 943169, 160349], # 第二个地区的投票人数
'West Virginia': [188794, 489371, 36258], # 第三个地区的投票人数
},
).set_index('labels')
从上述数据来看,我们需要三个子图去描述该数据,与此同时我们还要为每个子图添加标题,每个地区投票人数及比例等信息。我们先对第一个地区的情况进行百分比方格图的绘制:
In [6]:
# 用来各各地区投票的总数
def count(data):
count = 0
all_num = [v for k,v in data]
for i in all_num:
count = count + i
return count
fig = plt.figure(
FigureClass=Waffle,
rows=5,
colors=("#2196f3", "#ff5252", "#999999"),
figsize=(9, 5),
# 使用plots可以在一张图像中绘制多个子图
plots={
'311': {
# 设定方格百分比的值
'values': data['Virginia'] / 30000,
# 设定标签的值:人名,投票数,百分比,操作为先取出每个地区对候选人的投票,然后除以该地区投票总数,得到每个候选人的投票百分比。
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['Virginia'].items())*100) for k, v in data['Virginia'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.05, 1),
'fontsize': 8
},
# 设定标题
'title': {
'label': '2016 Virginia Presidential Election Results',
'loc': 'left'
}
}
},
)
上图中,对各位投票人得票信息一目了然。下面我们使用子图的方式来展示三个区域的投票情况:
In [7]:
fig = plt.figure(
FigureClass=Waffle,
rows=5,
colors=("#2196f3", "#ff5252", "#999999"),
figsize=(9, 5),
plots={
'311': {
# 设定方格百分比的值
'values': data['Virginia'] / 30000,
# 设定标签的值:人名,投票数,本地区对候选人投票百分比
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['Virginia'].items())*100) for k, v in data['Virginia'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.05, 1),
'fontsize': 8
},
# 设定标题
'title': {
'label': '2016 Virginia Presidential Election Results',
'loc': 'left'
}
},
# 对第二个地区的投票进行统计
'312': {
'values': data['Maryland'] / 30000,
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['Maryland'].items())*100) for k, v in data['Maryland'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.2, 1),
'fontsize': 8
},
'title': {
'label': '2016 Maryland Presidential Election Results',
'loc': 'left'
}
},
'313': {
'values': data['West Virginia'] / 30000,
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['West Virginia'].items())*100) for k, v in data['West Virginia'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.3, 1),
'fontsize': 8
},
'title': {
'label': '2016 West Virginia Presidential Election Results',
'loc': 'left'
}
},
}
)
编程要求
依据上述相关知识点及示例,编程完成上述投票数据的方格百分比图绘制。
In [8]:
#根据编程要求,补充下面Begin-End区间的代码
import matplotlib.pyplot as plt
from pywaffle import Waffle
import pandas as pd
data = pd.DataFrame(
{
'labels': ['Hillary Clinton', 'Donald Trump', 'Others'], # 候选人
'Virginia': [1981473, 1769443, 233715], # 第一个地区的投票人数
'Maryland': [1677928, 943169, 160349], # 第二个地区的投票人数
'West Virginia': [188794, 489371, 36258], # 第三个地区的投票人数
},
).set_index('labels')
######Begin ######
###### End ######
参考答案如下:
In [9]:
#根据编程要求,补充下面Begin-End区间的代码
import matplotlib.pyplot as plt
from pywaffle import Waffle
import pandas as pd
data = pd.DataFrame(
{
'labels': ['Hillary Clinton', 'Donald Trump', 'Others'], # 候选人
'Virginia': [1981473, 1769443, 233715], # 第一个地区的投票人数
'Maryland': [1677928, 943169, 160349], # 第二个地区的投票人数
'West Virginia': [188794, 489371, 36258], # 第三个地区的投票人数
},
).set_index('labels')
######Begin ######
# 统计总数
def count(data):
count = 0
all_num = [v for k,v in data]
for i in all_num:
count = count + i
return count
fig = plt.figure(
FigureClass=Waffle,
rows=5,
colors=("#2196f3", "#ff5252", "#999999"),
figsize=(9, 5),
plots={
'311': {
# 设定方格百分比的值
'values': data['Virginia'] / 30000,
# 设定标签的值:人名,投票数,本地区对候选人投票百分比
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['Virginia'].items())*100) for k, v in data['Virginia'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.05, 1),
'fontsize': 8
},
# 设定标题
'title': {
'label': '2016 Virginia Presidential Election Results',
'loc': 'left'
}
},
'312': {
'values': data['Maryland'] / 30000,
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['Maryland'].items())*100) for k, v in data['Maryland'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.2, 1),
'fontsize': 8
},
'title': {
'label': '2016 Maryland Presidential Election Results',
'loc': 'left'
}
},
'313': {
'values': data['West Virginia'] / 30000,
'labels': ['{} ({}) ({:.1f}%)'.format(k, v, v/count(data['West Virginia'].items())*100) for k, v in data['West Virginia'].items()],
'legend': {
'loc': 'upper left',
'bbox_to_anchor': (1.3, 1),
'fontsize': 8
},
'title': {
'label': '2016 West Virginia Presidential Election Results',
'loc': 'left'
}
},
}
)
###### End ######
至此,Python 的方格百分比图的绘制结束。