python 分组柱状图matplotlib_Python做动态数据图

题外话:正是因为业余接触Python,常专注数小时弄清某件事用python怎样实现,这才催生了一个想法:创设公众号来记录、积累和分享。笔者学习python为目标导向,有需求才会去研究相应模块,知识体系未必扎实完备,优化方面的不足请见谅。

多维动态图表可以直观地展现某几项指标多年来的变化,效果见下图:

64e6ef829c5fc5e2ecb89e1667dc06f4.gif

e8104a404209e9207b97e6a635ecf100.gif

想做出这样图表,就要用到我们今天的主角:matplotlib中的animation模块。

简单来说,这个模块帮助你把已有的元素进行分组,每组所有元素构成动态图的一帧。而这个模块本身也非常简单,只有两种函数:FuncAnimation和ArtistAnimation。前者以函数驱动,后者则像堆积木一样一帧一帧堆起来。

本文主要介绍ArtistAnimation。它的各项参数如下:

a5fe2d820c88f3addbc41a0ec778c257.png

fig就是目标图表了;artists为一个列表,它的官方解释为“artists : list, each list entry a collection of artists that represent what needs to be enabled on each frame. These will be disabled for other frames.”;最后面是两个系列参数的总称。

19a5ee2bab2a339077f77661c7500741.png

简单来说,它的结构就是这样的了,每一个子列表包含众多“Artist”,构成一帧图。那么什么是“Artist”呢?其实matplotlib的制图功能还是非常强大的,柱、饼图说冰山一角好像都有点多了。属于“Artist”类的见下图:

9166f26743fa3ac14ba870978b8867dc.png

(图片来源:https://matplotlib.org)

不要慌,我们是目标导向,只看自己需要的。

接下来详解code:

1c67ba88d5c8a379dc0f4f2074f7187b.png

为了python支持中文,第一行必不可少。为了matplotlib支持中文,这里换成系统自带字体微软雅黑。

706504edb54c956d9eacb75e477c1ba8.png

创建一个figure叫“fig”,一个坐标系叫“ax”。ind和width为所画柱状图的参数,依次与位置和宽度有关。

cf0667046f4a606b155359d1e81ac751.png

笔者所用数据是从excel摘取,所以使用了xlrd模块。(这模块一搜全会)N就是我们这个图的总帧数,接下来创建3个关键的列表,Pictures用来装柱状图,Years用来装年份,Artists整合前两个列表,形成ArtistAnimation函数所接受的格式。

4eb6449cd7924477bcdcf0541abdf4de.png

接下来是主循环。基本操作读数据、处理缺省值、转换成元组tuple。(在bar()函数里,对应参数需要array-like格式)注意从第二个开始运算符变为“+=”,即在第一个基础上再把后面的加上去。使用type()函数我们会发现,单纯plt.bar()做出来的类是matplotlib.container.BarContainer,而多个这种类加起来后则变为tuple,同时之前的单个类转化为matplotlib.patches.Rectangle。如果用类似的方式加上年份,则会报错:

529bc4bb3e6dfef953f01209c2c20d49.png

d75658d1cffe9c7bb4bfa9bbac6b95c7.png

笔者在此提供了一种解决方案:根据官方提供的artist类图表,Text和Rectangle都是一个artist,而tuple是支持索引的,那就把patches这个tuple给拆了,再加上年份,把这所有的一团装在一个新的list里面。这样最大的好处是避免了不同类无法相加的尴尬情境,每一帧的list里面包含这一帧所有的最小单元artist。这样就很简单了,开始堆积木就好了。

fdda781a9949f6bd8128dbef2bb8fe2f.png

加个标题,中文切记引号前要加u,表示utf-8编码。然后横轴标签,以及图例。ArtistAnimation函数让我们做的所有artists分组一帧一帧地呈现。

将做的图呈现出来直接plt.show()就好了,而将做的图完美保存可就有讲究了。推荐使用imagemagick,保存为gif格式,一来文件很小,二来矢量保存伸缩不影响图质。

这东西需要提前安装好。Windows相对容易,在MacOS或者Linux系统下则需要先安装Homebrew,这和pip类似是包管理器。

4e18d3c9920544612223302ae22bd06b.png

粘贴这一行到终端敲回车就可以了,挺酷的。

0b42c84b2aa08eda6703d151513469f1.png

有了homebrew就可以这样直接安装imagemagick了。

成功安装好imagemagick就可以像刚刚那样直接保存为gif格式的动态图表啦!

以上是柱状图的code,饼图更简单一些,就不过多赘述了。