文章目录(Table of Contents)
简介
华夫饼图(Waffle Chart),有的人也会叫它“Square Pie Chart”,是饼图的一种变形,擅长展示部分在整体中的占比关系。一般来说,华夫饼图是由100个格子组成,一个格子代表“1%”。用不同颜色的格子区分不同的分类数据,以展示各部分在整体中的占比。下面是一个典型的华夫饼图:
参考资料
- 知乎上关于华夫饼图的介绍,这么好吃的华夫饼图,我还是第一次见!。可以参考上面的一些画图的样式,在其他地方做报告的地方可以用上这样的画法。
- 使用 Python 绘制华夫饼图使用 Pywaffle,相关的包的介绍如下链接所示,Waffle Document
- 这个是相关的 package 的 github 的链接,Github-PyWaffle
绘制华夫饼图介绍
使用之前,我们需要首先将将 pywaffle 导入。
- import matplotlib.pyplot as plt
- from pywaffle import Waffle
绘制基础的华夫饼图
首先看一下基础的华夫饼图的绘制。我们需要设置 FigureClass
是 Waffle
即可。
- fig = plt.figure(
- FigureClass=Waffle,
- rows=5,
- columns=10, # Either rows or columns could be omitted
- values=[30, 60, 10]
- )
- fig.show()
我们 values 中的和就是下面 block 的个数。同时 columns 就是下面华夫饼的列数,上面代码的结果如下图所示:
绘制华夫饼中数值缩放
在默认情况下,华夫饼图会根据 values 的值绘制对应数量的 blocks。但是如果数量很多,全部画出来显然是不合适的。所以,如果当我们同时设定了 rows 或是 columns 之后,block 的数量就会确定下来。这样就相当于是显示一个百分比了。
例如下面的例子,虽然 values 的和是 200,但是我们设置了 row 和 column,那么最终显示的结果就只会有 100 个方块。
- fig = plt.figure(
- FigureClass=Waffle,
- rows=10,
- columns=10,
- values=[60, 120, 20]
- )
- fig.show()
最终的显示结果如下所示:
设置华夫饼的标题和图例
我们可以设置标题,图例等,来让华夫饼图显示更多的信息。我们使用参数 title 来指定标题,他会接受一个 dict。同样的,使用 legend 来设置图例,他也是接受一个 dict。
例如下面一个简单的例子是可以绘制男生和女生的比例:
- data = {'男生':120, '女生':80}
- fig = plt.figure(
- FigureClass=Waffle,
- rows=10,
- columns=10,
- values=data,
- title={
- 'label': '男生女生的人数比例',
- 'loc': 'center',
- 'fontdict': {
- 'fontsize': 20
- }
- },
- legend={
- 'labels': [f"{k} ({100*v/sum(list(data.values()))}%)" for k, v in data.items()],
- 'loc': 'lower left',
- 'bbox_to_anchor': (0, -0.2),
- 'ncol': 2,
- 'framealpha': 0,
- 'fontsize': 12
- }
- )
- fig.show()
最终可视化的结果如下所示:
修改 Block 的颜色
我们可以自定义我们 Block 的颜色,可以直接指定颜色,如下所示:
- fig = plt.figure(
- FigureClass=Waffle,
- rows=5,
- columns=10,
- values=[30, 16, 4],
- colors=["#232066", "#983D3D", "#DCB732"]
- )
结果如下所示:
当然,我们也可以直接设置 colormap 来设置颜色。需要注意的是,只有 Qualitative colormaps 是支持的。关于详细的 colormap 的内容,可以查看链接,Matplotlib Colormap reference。
- fig = plt.figure(
- FigureClass=Waffle,
- rows=5,
- columns=10,
- values=[30, 16, 4],
- cmap_name="tab10"
- )
最终的结果如下所示:
Block 的一些属性
自定义 Block 的形状
这里华夫饼的 block 是可以支持所有 Font Awesome 中的字符。例如我们可以将方块改为「星星」的形状,如下所示:
- fig = plt.figure(
- FigureClass=Waffle,
- columns=10,
- values=[30, 16, 4],
- icons='star'
- )
- fig.show()
最终的结果如下图所示:
修改 Block 之间的间距
首先我们可与修改 block 之间的间距,使用 interval_ratio 来设置。看一下下面的例子:
- fig = plt.figure(
- FigureClass=Waffle,
- rows=5,
- values=[30, 16, 4],
- interval_ratio_x=1,
- interval_ratio_y=0.1
- )
- fig.show()
最终的显示结果如下所示:
修改绘制方向和开始位置
同样,我们还可以修改绘制的方向。上面可以看到,默认都是竖着绘制的,我们也是可以横着绘制的,设置 vertical=True
即可。同时,可以一起设置开始的位置,我们设置从左上角开始:
- fig = plt.figure(
- FigureClass=Waffle,
- rows=5,
- values=[30, 16, 4],
- vertical=True,
- starting_location='SE'
- )
- fig.show()
这个时候的结果如下图所示:
每一个列别都有一个新的line
我们还可以将每一个新的类别有一个新的 line,如下所示:
- fig = plt.figure(
- FigureClass=Waffle,
- columns=10,
- values=[30, 16, 4],
- vertical=True,
- block_arranging_style='new-line'
- )
- fig.show()
注意这里不能设置 row,只能设置 columns,最终的结果如下所示:
华夫饼子图绘制
我们首先生成如下的数据,用来绘制不同的子图:
- 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')
接着我们绘制三幅子图,根据上面的三行数据:
- fig = plt.figure(
- FigureClass=Waffle,
- plots={
- '311': {
- 'values': data['Virginia'] / 30000,
- 'labels': [f"{k} ({v})" 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': [f"{k} ({v})" 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': [f"{k} ({v})" 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'
- }
- },
- },
- rows=5,
- colors=("#2196f3", "#ff5252", "#999999"), # shared parameter among subplots
- figsize=(9, 5) # figsize is a parameter of plt.figure
- )
绘制的结果如下所示:
绘制华夫饼的一些问题
中文的正常显示
为了让在华夫饼图中的中文可以正常的显示,我们就是和设置 matplotlib 中中文正常显示是一样的。在开头加上下面的代码即可:
- from pylab import * # 设置显示中文
- mpl.rcParams['font.sans-serif'] = ['SimHei']
- plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
具体可以参考链接,Python数据处理之Matplotlib学习
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论