数据可视化|用动态面积图分析疫情

公众号后台回复“图书“,了解更多号主新书内容

作者:林骥

来源:林骥

01

你好,我是林骥。

面积图是在折线图的基础上,用颜色填充折线下方的区域,从而更好地突出数据的趋势。

为了促进信息的有效表达,我们还可以根据数值的大小,用不同的颜色来填充面积。

比如说,我们用下面的面积图来展现美国新增确认人数的变化趋势,从中可以比较直观地看出,美国 7 月份新增确诊人数明显增加。

为了让展现的效果更加震撼,我们还可以把它做成动态面积图。

更多视频作品,请关注林骥的视频号。

如果你喜欢我的作品,请记得关注、点赞和分享。

02

下面是动态面积图的制作过程,你可以前往 https://github.com/linjiwx/mp 下载画图用的数据和完整代码。

首先,导入所需的库,并设置中文字体和定义颜色等。

# 导入所需的库
import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker 
import matplotlib.animation as animation
import datetime
from IPython.display import HTML

# 正常显示中文标签
mpl.rcParams['font.sans-serif'] = ['SimHei']

# 正常显示负号
mpl.rcParams['axes.unicode_minus'] = False

# 让网格线显示在下方
mpl.rc('axes', axisbelow=True)

# 禁用科学计数法
pd.set_option('display.float_format', lambda x: '%.2f' % x) 

# 定义颜色,主色:蓝色,辅助色:灰色,互补色:橙色
c = {'蓝色':'#00589F', '深蓝色':'#003867', '浅蓝色':'#5D9BCF',
     '灰色':'#999999', '深灰色':'#666666', '浅灰色':'#CCCCCC',
     '橙色':'#F68F00', '深橙色':'#A05D00', '浅橙色':'#FBC171'}

# 防止动态图显示不完整
plt.rcParams['animation.embed_limit'] = 1e100

其次,读取和定义数据。

# # 当需要更新数据时,去掉注释后运行一次
# import akshare as ak

# # 从 akshare 获取历史数据,速度比较慢
# df_all_history = ak.covid_19_history()

# # 保存到 Excel 文件中,以便下次快速读取数据
# df_all_history.to_excel('./data/covid_history.xlsx')

# 定义想要展示的国家
countries = ['美国']

# 从 Excel 文件中读取数据
df_all = pd.read_excel('./data/covid_history.xlsx', index_col=0).fillna('')

# 将字符串格式的日期转换为日期格式
df_all['date'] = pd.to_datetime(df_all['date'])

# 排除省份的数据,只保留国家的数据,设置日期为索引
dfc = df_all.query("province=='' and country==@countries[0]").set_index('date')

# 添加新增确诊列
dfc['new'] = dfc.confirmed - dfc.confirmed.shift(1).fillna(0)

# 筛选数据
df1 = pd.DataFrame(dfc.new)
df1.columns = [countries[0]]
df1 = df1.fillna(0)
df1= df1[df1.index >= '2020-03-01']

# 总天数
length = df1.shape[0] + 1

# 定义填充面积的颜色
colors = plt.cm.Spectral_r(df1[countries[0]]/max(df1[countries[0]]))

接下来,开始用「面向对象」的方法进行画图,并输出动画文件。

# 使用「面向对象」的方法画图,定义图片的大小
fig, ax = plt.subplots(figsize=(16, 9))

# 设置背景颜色
fig.set_facecolor('w')
ax.set_facecolor('w')

# 隐藏边框
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# 设置坐标标签字体大小和颜色
ax.tick_params(labelsize=16, colors=c['深灰色'])

# 定义动画函数
def animate(num): 
    # 先清空画面
    ax.clear()
    
    # 动态显示新的数据
    df_temp = df1.iloc[0:num, :]
    idx = df_temp.index

    # 绘制折线图
    ax.plot(idx, df_temp[countries[0]], color=c['蓝色'], linewidth=3, zorder=2)
    # 用条形图填充为面积图,用不同的颜色表示数值的大小
    ax.bar(idx, df_temp[countries[0]], width=1.5, align='center', color=colors)
    
    string = '○'+str(int(df_temp[countries[0]][-1]))
    ax.text(idx[-1], df_temp[countries[0]][-1], string, size=20, ha='left', va='center', color=c['蓝色'])

    # 设置标题
    ax.set_title('\n\n'+countries[0]+'新增确诊人数的变化趋势\n', loc='left', fontsize=26)
    
    # 设置 X 轴坐标范围
    ax.set_xlim(df1.index[0]+datetime.timedelta(days=-5), df1.index[-1]+datetime.timedelta(days=5))
    
    # 设置 Y 轴坐标范围
    ax.set_ylim(0, max(df1[countries[0]]))
    
    # 图片背景显示日期的动态变化
    ymax = ax.get_ylim()[1]
    string = (df1.index[0]+datetime.timedelta(days=int(num-1))).strftime('%Y年%m月%d日')
    ax.text(df1.index[0], ymax, string, ha='left', va='top', fontsize=60, color=c['灰色'], zorder=-1, alpha=0.2)
    
    # 设置网络线
    ax.grid(axis='y', color=c['浅灰色'])
    
    
# 绘制动画
animator = animation.FuncAnimation(fig, animate, frames=np.arange(1, length, 1), interval=100)

# 在 Jupyter Notebook 中显示动画
# HTML(animator.to_jshtml())

# 保存为 mp4 的文件格式
animator.save('动态面积图.mp4')

03

最后,把代码生成的 mp4 文件,导入视频剪辑软件,再配上音效,这个视频就做好了。

◆ ◆ ◆  ◆ ◆
麟哥新书已经在当当上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前当当正在举行活动,大家可以用原价4.45折的预购价格购买,还是非常划算的:

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

管理员二维码:


猜你喜欢

● 麟哥拼了!!!亲自出镜推荐自己新书《数据分析师求职面试指南》● 厉害了!麟哥新书登顶京东销量排行榜!● 笑死人不偿命的知乎沙雕问题排行榜
● 用Python扒出B站那些“惊为天人”的阿婆主!● 你相信逛B站也能学编程吗点击阅读原文,即可参与当当4.45折购书活动
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值