利用动态气泡图进行数据分析

     作者:林骥

     来源:林骥

01

你好,我是林骥。

一个动态气泡图,可以展现多个维度的信息。

比如说,要对比分析中国和美国从 1800 年以来每年的人口数量、人均收入和预期寿命,我们可以这样设置每个维度代表的含义:

(1)X 轴:人均收入;

(2)Y 轴:预期寿命;

(3)气泡大小:人口;

(4)气泡颜色:国家;

(5)时间变化:年份。

利用 matplotlib 制作动画的功能,我做了一个动态气泡图的视频:

在作图的细节方面,我做了一下刻意的调整:

(1)图表标题文字用深灰色,并且左对齐;

(2)X 轴和 Y 轴的标题与数字对齐,竖向的文字分行逐字显示;

(3)气泡的颜色与对应的文字使用接近的颜色;

(4)去掉网格线、图例、边框、刻度线等元素;

(5)只选取两个国家的数据。

以上这些刻意的调整,主要是为了更加突出地展现数据本身,或许让人看起来比较「素颜」,但是不要忘了我们作图的目标,是让观众更加快速地理解想要表达的信息,而不是靠「浓妆艳抹」去吸人眼球。

数据可视化,有时需要有批判性思维,突出数据中的重要内容。我们可以从设计师身上学习,多想一想数据可视化的目标是什么,尽可能让数据更利于观众理解,而不能拿着数字,就开始盲目地画图。

02

接下来,我们看看用 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 下载画图用的数据和完整代码。

03

下面对这个动态气泡图做一个简单的数据分析。

两个气泡的位置在不断变化,整体趋势都是从左下角向右上角移动,左下角代表贫穷和疾病,右上角代表富有和健康,说明两个国家的人们变得越来越富有、越来越长寿;气泡的大小也在不断变化,整体趋势是越变越大,代表人口越来越多。

在这个动态气泡图中,有短暂向下的波动,如果我们追溯当年发生的事件,那么就会发现,战争等重大灾难对人们的预期寿命影响非常大。

从上面的分析可以看出,真正有意思的,并不是数据本身,而是数据背后隐藏的信息。

人们都希望知道数据有什么意义,如果你能帮助他们,让他们更容易理解数据的意义,那么你就为他们创造了价值。

要想更容易理解数据,可视化是一种非常有效的方法,把数据放在视觉空间中,我们的大脑就会更容易发现数据背后潜藏的信息。

对数据进行可视化,我们也要有「双赢思维」,让观众的兴趣与自己想要传递的信息保持一致,实现双赢。

如果只顾观众的兴趣,弄了一堆花哨的东西,但是没有传递有价值的信息,那么只是浪费观众和自己的时间和精力。

如果不顾观众的兴趣,则做出的图表可能没人看,就容易碌碌无为,最终也体现不出自己的价值

◆ ◆ ◆  ◆ 

长按二维码关注我们


数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。

管理员二维码:

猜你喜欢

 笑死人不偿命的知乎沙雕问题排行榜

 用Python扒出B站那些“惊为天人”的阿婆主!

 全球股市跳水大战,谁最坑爹!

● 华农兄弟、徐大Sao&李子柒?谁才是B站美食区的最强王者?

● 你相信逛B站也能学编程

你可能感兴趣的:(利用动态气泡图进行数据分析)