matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

  • A+
所属分类:python数据分析
摘要这一篇介绍使用 Python 绘制华夫饼图(PyWaffle)。华夫饼图是饼图的一种变形,可以轻易看出每一部分的占比。这里我们会介绍使用 PyWaffle 来绘制不同形状的图像。

简介

华夫饼图(Waffle Chart),有的人也会叫它“Square Pie Chart”,是饼图的一种变形,擅长展示部分在整体中的占比关系。一般来说,华夫饼图是由100个格子组成,一个格子代表“1%”。用不同颜色的格子区分不同的分类数据,以展示各部分在整体中的占比。下面是一个典型的华夫饼图:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

参考资料

绘制华夫饼图介绍

使用之前,我们需要首先将将 pywaffle 导入。

  1. import matplotlib.pyplot as plt
  2. from pywaffle import Waffle

绘制基础的华夫饼图

首先看一下基础的华夫饼图的绘制。我们需要设置 FigureClassWaffle 即可。

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=5,
  4.     columns=10,  # Either rows or columns could be omitted
  5.     values=[30, 60, 10]
  6. )
  7. fig.show()

我们 values 中的和就是下面 block 的个数。同时 columns 就是下面华夫饼的列数,上面代码的结果如下图所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

 

绘制华夫饼中数值缩放

在默认情况下,华夫饼图会根据 values 的值绘制对应数量的 blocks。但是如果数量很多,全部画出来显然是不合适的。所以,如果当我们同时设定了 rows 或是 columns 之后,block 的数量就会确定下来。这样就相当于是显示一个百分比了。

例如下面的例子,虽然 values 的和是 200,但是我们设置了 row 和 column,那么最终显示的结果就只会有 100 个方块。

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=10,
  4.     columns=10,
  5.     values=[60, 120, 20]
  6. )
  7. fig.show()

最终的显示结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

 

设置华夫饼的标题和图例

我们可以设置标题,图例等,来让华夫饼图显示更多的信息。我们使用参数 title 来指定标题,他会接受一个 dict。同样的,使用 legend 来设置图例,他也是接受一个 dict。

例如下面一个简单的例子是可以绘制男生和女生的比例:

  1. data = {'男生':120, '女生':80}
  2. fig = plt.figure(
  3.     FigureClass=Waffle,
  4.     rows=10,
  5.     columns=10,
  6.     values=data,
  7.     title={
  8.         'label': '男生女生的人数比例',
  9.         'loc': 'center',
  10.         'fontdict': {
  11.             'fontsize': 20
  12.         }
  13.     },
  14.     legend={
  15.         'labels': [f"{k} ({100*v/sum(list(data.values()))}%)" for k, v in data.items()],
  16.         'loc': 'lower left',
  17.         'bbox_to_anchor': (0, -0.2),
  18.         'ncol': 2,
  19.         'framealpha': 0,
  20.         'fontsize': 12
  21.     }
  22. )
  23. fig.show()

最终可视化的结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

修改 Block 的颜色

我们可以自定义我们 Block 的颜色,可以直接指定颜色,如下所示:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=5,
  4.     columns=10,
  5.     values=[30, 16, 4],
  6.     colors=["#232066", "#983D3D", "#DCB732"]
  7. )

结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

当然,我们也可以直接设置 colormap 来设置颜色。需要注意的是,只有 Qualitative colormaps 是支持的。关于详细的 colormap 的内容,可以查看链接,Matplotlib Colormap reference

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=5,
  4.     columns=10,
  5.     values=[30, 16, 4],
  6.     cmap_name="tab10"
  7. )

最终的结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

 

Block 的一些属性

自定义 Block 的形状

这里华夫饼的 block 是可以支持所有 Font Awesome 中的字符。例如我们可以将方块改为「星星」的形状,如下所示:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     columns=10,
  4.     values=[30, 16, 4],
  5.     icons='star'
  6. )
  7. fig.show()

最终的结果如下图所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

修改 Block 之间的间距

首先我们可与修改 block 之间的间距,使用 interval_ratio 来设置。看一下下面的例子:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=5,
  4.     values=[30, 16, 4],
  5.     interval_ratio_x=1,
  6.     interval_ratio_y=0.1
  7. )
  8. fig.show()

最终的显示结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

修改绘制方向和开始位置

同样,我们还可以修改绘制的方向。上面可以看到,默认都是竖着绘制的,我们也是可以横着绘制的,设置 vertical=True 即可。同时,可以一起设置开始的位置,我们设置从左上角开始:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     rows=5,
  4.     values=[30, 16, 4],
  5.     vertical=True,
  6.     starting_location='SE'
  7. )
  8. fig.show()

这个时候的结果如下图所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

每一个列别都有一个新的line

我们还可以将每一个新的类别有一个新的 line,如下所示:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     columns=10,
  4.     values=[30, 16, 4],
  5.     vertical=True,
  6.     block_arranging_style='new-line'
  7. )
  8. fig.show()

注意这里不能设置 row,只能设置 columns,最终的结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

 

华夫饼子图绘制

我们首先生成如下的数据,用来绘制不同的子图:

  1. import pandas as pd
  2. data = pd.DataFrame(
  3.     {
  4.         'labels': ['Hillary Clinton', 'Donald Trump', 'Others'],
  5.         'Virginia': [1981473, 1769443, 233715],
  6.         'Maryland': [1677928, 943169, 160349],
  7.         'West Virginia': [188794, 489371, 36258],
  8.     },
  9. ).set_index('labels')

接着我们绘制三幅子图,根据上面的三行数据:

  1. fig = plt.figure(
  2.     FigureClass=Waffle,
  3.     plots={
  4.         '311': {
  5.             'values': data['Virginia'] / 30000,
  6.             'labels': [f"{k} ({v})" for k, v in data['Virginia'].items()],
  7.             'legend': {
  8.                 'loc': 'upper left',
  9.                 'bbox_to_anchor': (1.05, 1),
  10.                 'fontsize': 8
  11.             },
  12.             'title': {
  13.                 'label': '2016 Virginia Presidential Election Results',
  14.                 'loc': 'left'
  15.             }
  16.         },
  17.         '312': {
  18.             'values': data['Maryland'] / 30000,
  19.             'labels': [f"{k} ({v})" for k, v in data['Maryland'].items()],
  20.             'legend': {
  21.                 'loc': 'upper left',
  22.                 'bbox_to_anchor': (1.2, 1),
  23.                 'fontsize': 8
  24.             },
  25.             'title': {
  26.                 'label': '2016 Maryland Presidential Election Results',
  27.                 'loc': 'left'
  28.             }
  29.         },
  30.         '313': {
  31.             'values': data['West Virginia'] / 30000,
  32.             'labels': [f"{k} ({v})" for k, v in data['West Virginia'].items()],
  33.             'legend': {
  34.                 'loc': 'upper left',
  35.                 'bbox_to_anchor': (1.3, 1),
  36.                 'fontsize': 8
  37.             },
  38.             'title': {
  39.                 'label': '2016 West Virginia Presidential Election Results',
  40.                 'loc': 'left'
  41.             }
  42.         },
  43.     },
  44.     rows=5,
  45.     colors=("#2196f3", "#ff5252", "#999999"),  # shared parameter among subplots
  46.     figsize=(9, 5)  # figsize is a parameter of plt.figure
  47. )

绘制的结果如下所示:

matplotlib绘图优化-绘制华夫饼图 (PyWaffle)

 

绘制华夫饼的一些问题

中文的正常显示

为了让在华夫饼图中的中文可以正常的显示,我们就是和设置 matplotlib 中中文正常显示是一样的。在开头加上下面的代码即可:

  1. from pylab import * # 设置显示中文
  2. mpl.rcParams['font.sans-serif'] = ['SimHei']
  3. plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

具体可以参考链接,Python数据处理之Matplotlib学习

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: