Matplotlib 和 Seaborn 用来做数据固定的静态图表很不错, 但如果需要动态显示数据的变化过程用这俩库就有点难度了. 如果能用短视频来动态展示图表中数据的变化是不是就有点厉害了? 而且不用学新的库, 就用 Matplotlib 和 Seaborn, 是不是更厉害了! 今天就教大家一个很酷的教程, 马上动起来.
这里我们用到的数据是由美国疾控中心和药物滥用研究所收集的. 我最近用他们的数据给一个关于美国鸦片药物滥用危机的纪录片做了几个动态图所以这里就接着用了. 下面是数据的下载链接:
下载地址:
https://www.drugabuse.gov/sites/default/files/overdose_data_1999-2015.xls
除了用 Matplotlib 和 Seaborn 来作图我们还用到了 Numpy 和 Pandas 来处理数据. 先把需要的库都 import 进来:
接下来把数据从下载的 Excel 文件读进来, 我们用 Pandas 来读所以读进来就是一个 DataFrame. 这里我们还写了一个传入行数只读取一行数据的函数. 这是为了以后给不同药物分别做图的时候读数据方便一些.
这些准备工作做好我们就可以开始作图了. 如果你用 Jupyter Notebook 的 话记得加图表页内显示的命令 %matplotlib notebook.
我们先用刚才写的 get_data 函数把因为海洛因死亡的人数读出来. 这个 DataFrame 有两列, 分别是年份和死亡人数.
接下来我们初始化一个 FFMPEG 输出流. 这里我设置帧率 20 码率 1800 , 当然你自己可以改帧率和码率.
下面我们需要创建图表和横纵坐标. 这里要把数据范围定死不然数据更新的时候 Matplotlib 会自动更新数据范围我们的动图数据范围就会来回变.
绘图中最重要的就是下面这个 animate 函数, 它的参数 i 指的是帧数. 我们通过参数 i 来选择这一帧应该显示的数据然后用 Seaborn 来画一个折线图. 最后两行改改字体和折线的宽度让图好看一点.
要让图表动起来我们得把刚才定义的 animate 函数传给 matplotlib.animation.FuncAnimation . 除了 animate ,FuncAnimation 还有一个参数 frames , 这个参数的意思是说我们这段动画想一共要多少帧. 这里 frames 的值是 17 帧, 所以 animate 函数会被调用 17 次.
最后我们把这段动画存成 mp4 格式就行了. 如果想先看看效果, 可以用 plt.show() .
最后出来的效果是这样的:
意思是有了但给人感觉数据的跳跃有点太快了, 所以我们可能得给数据点中间插点值. 插值可以用下面的 augment 函数:
用 augment 函数处理完数据我们还要调整一下 FuncAnimation 函数中的帧数. 这里我给 augment 传入的 numsteps 是 10, 也就是说 augment 后从 99 年到 15 年的 16 个数据点变成了 160 个, 所以帧数也要设成 160. 调整完的图看着顺溜多了, 不过在数据增减变化的地方还是能看到很硬的拐弯.
为了让这些拐角也平滑一点我们参考了下面这个链接里的高斯平滑算法. 这个链接里也介绍了其他的平滑算法.
https://www.swharden.com/wp/2008-11-17-linear-data-smoothing-in-python/
此外我们还可以给图片加点背景色.
大功告成! 其实不是大功, 只是用 Matplotlib 制作动态图表的一个很基本的例子. 不过原理都是一样的, 在 animate 函数里绘图然后调整调整合适的参数什么图都能动起来. 最后 希望大家顺利操作起来!
来源: http://www.tuicool.com/articles/EfqEv2u