【python疫情可视化】用pyecharts开发全国疫情动态地图,效果酷炫!

一、效果演示

我用python开发了一个动态疫情地图,首先看下效果:

如图所示,地图根据实时数据通过时间线轮播的方式,动态展示数据的变化。随着时间的推移,疫情确诊数量的增多,地图各个省份颜色逐渐加深,可以很明显地看到动态可视化效果。

这个动态疫情地图,是通过python的第三方库pyecharts制作完成的。数据来源是github上的一位大神:
https://github.com/BlankerL/DXY-COVID-19-Data
在此,感谢github作者整理的数据来源,方便我们数据分析人员使用。

针对此数据源,我还开发了一个定时自动下载疫情数据的python脚本,有兴趣的小伙伴可以滴滴我。

二、代码讲解(文末含完整源码)

下面,通过python代码(部分核心代码)逐一分解,这个动态疫情地图是怎样实现的:

首先,导入需要的库:

import pandas as pd  # 用于读取excel文件
from pyecharts import options as opts  # 可视化选项
from pyecharts.charts import Timeline, Map  # 时间线、地图
from pyecharts.globals import ThemeType  # 图表主题

然后,定义好数据源文件,并做一些初始的数据清洗、数据预处理工作:

# 数据源文件
src_file = 'DXYArea_0214.xls'
# 中间文件
mid_file = 'to_csv4.csv'
# 疫情地图所用颜色
list_color = ['#F4AD8B', '#EF826F', '#EE806E', '#BD3932', '#801D17']
# 读取数据
df = pd.read_excel(io=src_file, usecols=['provinceName',
                                         'province_confirmedCount',
                                         'updateTime'],
                   )  # 读取数据源
df['updateTime'] = df['updateTime'].astype(str).str[0:10]
df2 = df.groupby(['provinceName', 'updateTime']).apply(
    lambda t: t[t.province_confirmedCount == t.province_confirmedCount.max()])  # 按省份日期分组统计确诊数量
df2 = df2[['provinceName', 'province_confirmedCount', 'updateTime']]
df2 = df2.drop_duplicates()  # 删除重复值
df2 = df2.reset_index(drop=True)  # 重置索引
df2.to_csv(mid_file, index=False)  # 保存csv
df3 = pd.read_csv(mid_file)

筛选出指定日期的数据,并做一定的数据处理,供后续可视化代码读取调用:

# 筛选出指定日期的数据
df_20200201 = df3[df3['updateTime'].str.contains("2020-02-01")]
df_20200202 = df3[df3['updateTime'].str.contains("2020-02-02")]
df_20200203 = df3[df3['updateTime'].str.contains("2020-02-03")]
df_20200204 = df3[df3['updateTime'].str.contains("2020-02-04")]
df_20200205 = df3[df3['updateTime'].str.contains("2020-02-05")]
df_20200206 = df3[df3['updateTime'].str.contains("2020-02-06")]
df_20200207 = df3[df3['updateTime'].str.contains("2020-02-07")]
df_20200208 = df3[df3['updateTime'].str.contains("2020-02-08")]
df_20200209 = df3[df3['updateTime'].str.contains("2020-02-09")]
df_20200210 = df3[df3['updateTime'].str.contains("2020-02-10")]
df_20200211 = df3[df3['updateTime'].str.contains("2020-02-11")]
df_20200212 = df3[df3['updateTime'].str.contains("2020-02-12")]
df_20200213 = df3[df3['updateTime'].str.contains("2020-02-13")]

最后,也是最关键的代码,可视化地图部分:

def timeline_map() -> Timeline:
    tl = Timeline(init_opts=opts.InitOpts(page_title="疫情地图4",
                                          theme=ThemeType.CHALK,
                                          width="1000px", height="620px"),
                  )
    for idx in range(0, 13):
        provinces = []
        confirm_value = []
        for item_pv in df_list[idx]['provinceName']:
            provinces.append(item_pv)
        for item_pc in df_list[idx]['province_confirmedCount']:
            confirm_value.append(item_pc)
        zipped = zip(provinces, confirm_value)
        f_map = (
            Map(init_opts=opts.InitOpts(width="900px",
                                        height="500px",
                                        page_title="疫情地图4",
                                        bg_color=None))
            .add(series_name="确诊数量",
                             data_pair=[list(z) for z in zipped],
                             maptype="china",
                             is_map_symbol_show=False)
            .set_global_opts(
                title_opts=opts.TitleOpts(title="2月全国疫情地图",
                                          subtitle="2月{}日-当天数据\n"
                                          "数据源:https://github.com/BlankerL/DXY-COVID-19-Data\n"
                                          "注:仅限个人研究使用,请勿用作商业用途!".format(
                                              idx + 1),
                                          pos_left="center", ),
                legend_opts=opts.LegendOpts(is_show=True, pos_top="40px", pos_right="30px"),
                visualmap_opts=opts.VisualMapOpts(
                    is_piecewise=True, range_text=['高', '低'], pieces=[
                        {"min": 10000, "color": "#751d0d"},
                        {"min": 1000, "max": 9999, "color": "#ae2a23"},
                        {"min": 500, "max": 999, "color": "#d6564c"},
                        {"min": 100, "max": 499, "color": "#f19178"},
                        {"min": 10, "max": 99, "color": "#f7d3a6"},
                        {"min": 1, "max": 9, "color": "#fdf2d3"},
                        {"min": 0, "max": 0, "color": "#FFFFFF"}
                    ]),
            )
            .set_series_opts(label_opts=opts.LabelOpts(is_show=True),
                             markpoint_opts=opts.MarkPointOpts(
                                 symbol_size=[90, 90], symbol='circle'),
                             effect_opts=opts.EffectOpts(is_show='True', )
                             )
        )
        tl.add(f_map, "{}日".format(idx + 1))
        tl.add_schema(is_timeline_show=True,  # 是否显示
                      play_interval=800,  # 播放间隔
                      symbol=None,  # 图标
                      is_loop_play=True  # 循环播放
                      )
    return tl

核心代码就是这些,执行成功之后,就是这样的效果啦:

三、讲解视频

快速讲解

3分钟快速讲解:
https://www.zhihu.com/zvideo/1447561855132241920

详细讲解

半小时详细讲解:
https://www.zhihu.com/zvideo/1562394229283995648

四、附完整源码

附完整源码:点击这里完整源码


更多可视化案例源码 -> 马哥python说

posted @ 2022-05-03 14:56  马哥python说  阅读(935)  评论(0编辑  收藏  举报