动态气泡图绘制,超简单~~

2022-02-17 15:00:56 浏览数 (1)

效果预览

http://mpvideo.qpic.cn/0b78imaaaaaahiaex25z7rpfaq6dabbqaaaa.f10002.mp4?dis_k=1114c40f6f8ad01d51b825cc30f30149&dis_t=1645081209&vid=wxv_1335626019700703233&format_id=10002&support_redirect=0&mmversion=false

看完后是不是感觉超有感觉,本推文将会教会你如何制作出这样的视频(核心教程还是Matplotlib 图表的绘制,当然后期还需要 FastStone Capture 进行视频制作和 快剪辑 进行视频剪辑和背景音乐的添加)

01. 引言

动态的图表拥有静态图表不能比拟的优势,能够有效反映出一个变量在一段时间的变化趋势,在PPT汇报演讲中是一大加分项,而在严谨的学术图表中则不建议使用。统计学家Hans Rosling在TED上关于《亚洲何时崛起》的演讲,其所采用的数据可视化展示方法可谓是近年来经典的可视化案例之一,动态的气泡图生动的展示了中国和印度是如何在过去几十年拼命追赶欧美经济的整个过程。可以说,Hans Rosling 让数据变得不再枯燥无味,使其生动的展示在大众面前,为了对这位伟大的统计学家的怀念(Hans Rosling 于2017年2月7日离开了这个世界), 本次教程将使用Python 经典的可视化库Matplotlib再现这经典的动态气泡图,或者说Hans Rosling Charts。

02. 数据处理

数据文件主要有country_metadata.csvLife Expectancy- Dataset.xlsxGDP per capita.xlsxData Population.xlsx四个数据文件,其中country_metadata.csv为对每个国家进行地区设定,其他数据文件则为对应的指标(Life Expectancy、GDP per capita、Data Population)数据,需要对数据进行合并处理:主要代码如下:

代码语言:javascript复制
df = pd.merge(country, lifeExp, how="left", on="Country Code")
df = pd.merge(df, GDP_per, how='left', on=['Country Code', 'time'])
df = pd.merge(df, pop, how='left', on=['Country Code', 'time'])
df.dropna(axis=0, inplace=True)

在数据处理过程中,还需要对不同地区(Region)进行颜色赋值(这里我主要分成四个地区,也可以按照country_metadata.csv文件中的设定进行地区分类,本文如此设置,纯属为了绘图方便,本意无其他任何含义),主要代码如下:

再对数据用apply()操作,使定义的region_set()和color_set02()应用到所选数据上:代码如下:

最终通过转换后的数据如下:

03. 数据可视化

Matplotlib 用于绘制动态图表主要涉及到 animation 模块,而制作动图,则需要分为以下三个步骤:

1、静态绘图函数的编写。

2、使用 animation 模块里的 FuncAnimation(),其调用形式主要如下:

代码语言:javascript复制
FuncAnimation( fig, func, frames, interval)

其中:

(1) fig 为画布对象。

(2)func 为第一步定义的静态绘图函数。

(3)frames 设置动画的帧数。

(4)interval 为动画每一帧间隔的时间,默认为200ms。

假设返回对象为animator.

3、用HTML(animator.to_jshtml())将动画效果在jupyter notebook中显示,或者直接导出gif或者MP4视频文件。

本推文绘制动态图的完整代码如下:

知识点讲解:

(1)第 12 行在 matplotlib 绘制动态图表过程中非常重要,一般设置较大值,如2**64 或者 2**128,其目的就是为了消除动态图过大,导致出图不完整问题。

(2)第 34 行设置了x轴的刻度比例,这里这样设置是为了更好的展示某些年份的数据。但想要完美解决,还需要要解决如下问题:matplotlib设置刻度间隔相等,但不同间隔表示不同的值,如下:

希望有知道解决方法的小伙伴可以留言告知啊,感谢!!!

(3)第 46-59 行为添加部分解释文本,设置 transform = ax.transAxes,是文本位置相对于 Axes 进行更改,不随数据更改而改变,建议在设置固定位置文本内容时,可采用此设置。

(4)第 61 行 ax.set_axisbelow(True)设置网格等属性位于图层属性之下,这是比较懒的设置方法,当涉及绘制多种图表时,可以在各自绘制时设置 zorder 属性,确定每个图层的顺序。

(5)第 63-78 行为对多类别散点图图例的制作(多数类似教程忽略了图例的添加,导致绘制的图表不够完善),但随着Matplotlib 3.1版本的发布,PathCollection新增加一个方法legend_elements(),实现以自动方式获取散点图的句柄和标签,极大简化了散点图图例的创建,下面给出样例,感兴趣的也可以前往Matplotlib官网查看,本例子没有采用最新方法。

红色框内为类别图例添加,绿色框内为散点大小图例添加,结果如下:

(6)第 90-93 行 对图例进行属性设置,详细设置可查看官网,但需要指出的是,90行设置图例标题字体大小,除此之外还有set_fontcolor、set_fontface等字体或其他属性的设置方法,这里提出就是为了告诉大家,别忘了python万物皆可对象。

(7)第 96-99 行,对动态图进行展示,当然可以直接保存成gif文件,如100行操作,也可以直接保存成MP4格式文件,代码如下:

代码语言:javascript复制
bubble_animator.to_html5_video()
bubble_animator.save('E:/animation01.mp4')

但此操作需要电脑配置好 FFmpeg,否则无法运行。

以上,基于matplotlib的动态气泡图就绘制完成了,难点:在于多类别图例的添加,可以参考本文方法也可参考官网方法。

下面给出本例子其中一年份数据绘图的结果图 :

04. 总结

Matplotlib 进行动态图表的绘制过程总体而言还是比较简单的,当然除了前期复杂的数据处理过程。就个人而言,绘制动态图可以先采用单一数据进行静态可视化绘制,在经过美化图表设置后,在通过 animation 模块进行 “魔力”即可。个人知识点有限,难免会有出错的地方,如发现请指出,我会第一时间回复并进行更正。

0 人点赞