作者:林骥
来源:林骥
你好,我是林骥。
一个动态气泡图,可以展现多个维度的信息。
比如说,要对比分析中国和美国从 1800 年以来每年的人口数量、人均收入和预期寿命,我们可以这样设置每个维度代表的含义:
(1)X 轴:人均收入;
(2)Y 轴:预期寿命;
(3)气泡大小:人口;
(4)气泡颜色:国家;
(5)时间变化:年份。
利用 matplotlib 制作动画的功能,我做了一个动态气泡图的视频:
在作图的细节方面,我做了一下刻意的调整:
(1)图表标题文字用深灰色,并且左对齐;
(2)X 轴和 Y 轴的标题与数字对齐,竖向的文字分行逐字显示;
(3)气泡的颜色与对应的文字使用接近的颜色;
(4)去掉网格线、图例、边框、刻度线等元素;
(5)只选取两个国家的数据。
以上这些刻意的调整,主要是为了更加突出地展现数据本身,或许让人看起来比较「素颜」,但是不要忘了我们作图的目标,是让观众更加快速地理解想要表达的信息,而不是靠「浓妆艳抹」去吸人眼球。
数据可视化,有时需要有批判性思维,突出数据中的重要内容。我们可以从设计师身上学习,多想一想数据可视化的目标是什么,尽可能让数据更利于观众理解,而不能拿着数字,就开始盲目地画图。
接下来,我们看看用 matplotlib 画图的具体步骤。
首先,导入所需的库,并设置中文字体和定义颜色等。
# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
# 正常显示中文标签
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 自动适应布局
mpl.rcParams.update({'figure.autolayout': True})
# 正常显示负号
mpl.rcParams['axes.unicode_minus'] = False
# 禁用科学计数法
pd.set_option('display.float_format', lambda x: '%.2f' % x)
# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色
colors = {'蓝色':'#00589F', '深蓝色':'#003867', '浅蓝色':'#5D9BCF',
'灰色':'#999999', '深灰色':'#666666', '浅灰色':'#CCCCCC',
'橙色':'#F68F00', '深橙色':'#A05D00', '浅橙色':'#FBC171'}
其次,从 Excel 文件中读取数据,并定义画图用的数据。
# 读取从 https://www.gapminder.org/data 下载的 Excel文件
dfx = pd.read_excel('./data/income_per_person.xlsx', index_col='country')
dfy = pd.read_excel('./data/life_expectancy_years.xlsx', index_col='country')
dfs = pd.read_excel('./data/population_total.xlsx', index_col='country')
接下来,开始用「面向对象」的方法进行画图。
# 使用「面向对象」的方法画图,定义图片的大小
fig, ax = plt.subplots(figsize=(9, 6))
# 设置边框颜色
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
# 隐藏刻度线
ax.tick_params(axis='x', which='major', length=0)
ax.tick_params(axis='y', which='major', length=0)
# 设置坐标标签字体大小和颜色
ax.tick_params(labelsize=16, colors=colors['深灰色'])
# 动画函数
def animate(year):
# 先清空画布,让画面动态显示新的数据
ax.cla()
# 设置标题
ax.text(-11000, 106, '\n中美人口数量、人均收入和预期寿命的动态变化\n', fontsize=26, color=colors['深灰色'])
# 主要通过数字 year 来控制图形的变化,year = 0 代表第 1 年,当 year 增加,相应的画图数据发生变化
# 中国数据
x = dfx.loc['China'].iloc[year, ]
y = dfy.loc['China'].iloc[year, ]
s = dfs.loc['China'].iloc[year, ]/100000000
# 画气泡图
ax.scatter(x, y, s*500, c = colors['浅蓝色'], alpha=0.9)
# 设置显示的文本标签
ax.text(x, y-18.5, '中国 ' + '%.2f' % s + ' 亿人\n$' + '%.0f' % x + ',' + '%.1f' % y + ' 岁',
fontsize=16, c = colors['深蓝色'], ha='center', va='center')
# 美国数据
x = dfx.loc['United States'].iloc[year, ]
y = dfy.loc['United States'].iloc[year, ]
s = dfs.loc['United States'].iloc[year, ]/100000000
# 画气泡图
ax.scatter(x, y, s*500, c = colors['浅橙色'], alpha=0.9)
# 设置显示的文本标签
ax.text(x, y+15.5, '美国 ' + '%.2f' % s + ' 亿人\n$' + '%.0f' % x + ',' + '%.1f' % y + ' 岁',
fontsize=16, c = colors['深橙色'], ha='center', va='top')
# 设置坐标轴范围
ax.set_xlim(-5000, 65000)
ax.set_ylim(0, 100)
# 设置 X、Y 轴的标题,适当留白
ax.text(-1000, -15, '人均收入$', ha='left', fontsize=16, color=colors['深灰色'])
ax.text(-11000, 103, '预\n期\n寿\n命', va='top', fontsize=16, color=colors['深灰色'])
# 更新文本的位置和内容
x_mean = (ax.get_xlim()[0] + ax.get_xlim()[1]) / 2
y_mean = (ax.get_ylim()[0] + ax.get_ylim()[1]) / 2
ax.text(x_mean, y_mean, str(1800 + year), ha='center', va='center', fontsize=260, color=colors['灰色'], zorder=-1, alpha=0.2)
# 用函数的方式绘制动画,frames 表示动画的张数, interval 表示间隔毫秒数
anim = FuncAnimation(fig, animate, frames=220, interval=100)
# 保存为 mp4 的文件格式
anim.save('动态气泡图.mp4')
你可以前往 https://github.com/linjiwx/mp 下载画图用的数据和完整代码。
下面对这个动态气泡图做一个简单的数据分析。
两个气泡的位置在不断变化,整体趋势都是从左下角向右上角移动,左下角代表贫穷和疾病,右上角代表富有和健康,说明两个国家的人们变得越来越富有、越来越长寿;气泡的大小也在不断变化,整体趋势是越变越大,代表人口越来越多。
在这个动态气泡图中,有短暂向下的波动,如果我们追溯当年发生的事件,那么就会发现,战争等重大灾难对人们的预期寿命影响非常大。
从上面的分析可以看出,真正有意思的,并不是数据本身,而是数据背后隐藏的信息。
人们都希望知道数据有什么意义,如果你能帮助他们,让他们更容易理解数据的意义,那么你就为他们创造了价值。
要想更容易理解数据,可视化是一种非常有效的方法,把数据放在视觉空间中,我们的大脑就会更容易发现数据背后潜藏的信息。
对数据进行可视化,我们也要有「双赢思维」,让观众的兴趣与自己想要传递的信息保持一致,实现双赢。
如果只顾观众的兴趣,弄了一堆花哨的东西,但是没有传递有价值的信息,那么只是浪费观众和自己的时间和精力。
如果不顾观众的兴趣,则做出的图表可能没人看,就容易碌碌无为,最终也体现不出自己的价值
◆ ◆ ◆ ◆ ◆
长按二维码关注我们
数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。
管理员二维码:
猜你喜欢
● 笑死人不偿命的知乎沙雕问题排行榜
● 用Python扒出B站那些“惊为天人”的阿婆主!
● 全球股市跳水大战,谁最坑爹!
● 华农兄弟、徐大Sao&李子柒?谁才是B站美食区的最强王者?
● 你相信逛B站也能学编程