前言

从今年年初爆发的新冠疫情,截止至2020.09.21,全球累计确诊人数已超三千万,死亡人数近百万,这对于世界各国人民而言无疑是一场巨大的灾难。当前国内疫情局势已基本稳定,而美国、印度、巴西等国家的感染人数仍以较快的速度持续增长,情况不容乐观。
本文利用Python的pyecharts与matplotlib库制作了一些疫情可视化图来展现全球疫情的发展趋势,供初学者参考。代码比较野生,难免有所纰漏,欢迎指正。

1.获取疫情历史数据

疫情的历史数据可以从丁香园、或者百度疫情获取,也可以从GitHub上诸位大神提供的接口获取。本文的数据来源于https://github.com/canghailan/Wuhan-2019-nCoV中的Wuhan-2019-nCoV.csv文件,十分感谢大神的整理,也希望大家能够star,整理不易,这里向所有提供免费疫情数据的朋友表示敬意。
本文使用的数据统计截止日期为2020.09.21。

2.制作南丁格尔玫瑰图

人民日报与央视新闻官微早前发布过两张很漂亮的疫情玫瑰图,本文的玫瑰图主要仿制于此,使用的是matplotlib库,当然也可以通过pyecharts实现,代码也不复杂,有兴趣的朋友可以自己尝试。
图片如下:
在这里插入图片描述

2.1 全球各国确诊人数玫瑰图

#coding:utf-8
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def rosetype_pie(country,confirmed,size,colors):
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文显示

    num= len(size) # 柱子的数量
    width = 2 * np.pi / num # 每个柱子的宽度
    rad = np.cumsum([width] * num)  # 每个柱子的角度
    
    plt.figure(figsize=(8, 8),dpi=500,)  # 创建画布
    ax = plt.subplot(projection='polar')
    ax.set_ylim(-1, np.ceil(max(size) + 1))  # 中间空白,-1为空白半径大小,可自行调整
    ax.set_theta_zero_location('N',-5.0)  # 设置极坐标的起点方向 W,N,E,S, -5.0为偏离数值,可自行调整
    ax.set_theta_direction(1) # 1为逆时针,-1为顺时针
    ax.grid(False)  # 不显示极轴
    ax.spines['polar'].set_visible(False)  # 不显示极坐标最外的圆形
    ax.set_yticks([])  # 不显示坐标间隔
    ax.set_thetagrids([])  # 不显示极轴坐标

    ax.bar(rad, size, width=width, color=colors, alpha=1) # 画图
    ax.bar(rad, 1, width=width, color='white', alpha=0.15)  # 中间添加白色色彩使图案变浅
    ax.bar(rad, 3, width=width, color='white', alpha=0.1)  # 中间添加白色色彩使图案变浅
    ax.bar(rad, 5, width=width, color='white', alpha=0.05)  # 中间添加白色色彩使图案变浅
    ax.bar(rad, 7, width=width, color='white', alpha=0.03)  # 中间添加白色色彩使图案变浅

    # 设置text
    for i in np.arange(num):
        if i < 8:
            ax.text(rad[i],  # 角度
                    size[i]-0.2,  # 长度
                    country[i]+'\n'+str(confirmed[i])+'例',  # 文本
                    rotation=rad[i] * 180 / np.pi -5,  # 文字角度
                    rotation_mode='anchor',
                    # alpha=0.8,#透明度
                    fontstyle='normal',# 设置字体类型,可选参数[ ‘normal’ | ‘italic’ | ‘oblique’ ],italic斜体,oblique倾斜
                    fontweight='black', # 设置字体粗细,可选参数 [‘light’, ‘normal’, ‘medium’, ‘semibold’, ‘bold’, ‘heavy’, ‘black’]
                    color='white', # 设置字体颜色
                    size=size[i]/2.2, # 设置字体大小
                    ha="center", # 'left','right','center'
                    va="top", # 'top', 'bottom', 'center', 'baseline', 'center_baseline'
                    )
        elif i < 15:
            ax.text(rad[i]+0.02,
                    size[i]-0.7,
                    country[i] + '\n' + str(confirmed[i]) + '例',
                    fontstyle='normal',
                    fontweight='black',
                    color='white',
                    size=size[i] / 1.6,
                    ha="center",
                    )
        else:
            ax.text(rad[i],
                    size[i]+0.1,
                    str(confirmed[i]) + '例 ' + country[i],
                    rotation=rad[i] * 180 / np.pi + 85,
                    rotation_mode='anchor',
                    fontstyle='normal',
                    fontweight='black',
                    color='black',
                    size=4,
                    ha="left",
                    va="bottom",
                    )

    plt.show()


if __name__ == '__main__':
    df = pd.read_csv('Wuhan-2019-nCoV.csv') # 利用pandas读取数据
    colors = [(0.68359375, 0.02734375, 0.3203125),
                    (0.78125, 0.05078125, 0.2578125),
                    (0.875, 0.0390625, 0.1796875),
                    (0.81640625, 0.06640625, 0.0625),
                    (0.8515625, 0.1484375, 0.08203125),
                    (0.90625, 0.203125, 0.13671875),
                    (0.89453125, 0.2890625, 0.0703125),
                    (0.84375, 0.2421875, 0.03125),
                    (0.9140625, 0.26953125, 0.05078125),
                    (0.85546875, 0.31640625, 0.125),
                    (0.85546875, 0.3671875, 0.1171875),
                    (0.94921875, 0.48046875, 0.28125),
                    (0.9375, 0.51171875, 0.1484375),
                    (0.93359375, 0.59765625, 0.0625),
                    (0.93359375, 0.62890625, 0.14453125),
                    (0.86328125, 0.5859375, 0.15234375),
                    (0.86328125, 0.71875, 0.16015625),
                    (0.86328125, 0.8203125, 0.16015625),
                    (0.76171875, 0.8671875, 0.16015625),
                    (0.53125, 0.85546875, 0.15625),
                    (0.4765625, 0.94140625, 0.0703125),
                    (0.21484375, 0.91015625, 0.0625),
                    (0.15234375, 0.88671875, 0.08203125),
                    (0.11328125, 0.87890625, 0.19921875),
                    (0.11328125, 0.8125, 0.1796875),
                    (0.1875, 0.76953125, 0.2109375),
                    (0.2109375, 0.78125, 0.38671875),
                    (0.1484375, 0.76953125, 0.30859375),
                    (0.22265625, 0.73046875, 0.35546875),
                    (0.2890625, 0.6875, 0.4765625)] # 转化为小数的rgb色列表,
    df_top_confirmed = df.loc[(df['date'] == '2020-09-21') & (df['province'].isnull())].sort_values('confirmed',ascending=False).head(30) # 选择9.21日确诊数前三十的国家
    country = df_top_confirmed['country'].tolist()
    confirmed = df_top_confirmed['confirmed'].tolist()
    size = [22 , 19, 17, 12, 11, 10, 9, 8, 7.2, 7.0, 6.8, 6.6, 6.4, 6.2, 6.0, 5.8, 5.6, 5.4, 5.2, 5.0, 4.8, 4.6, 4.4, 4.2, 4.0, 3.8, 3.6, 3.4, 3.2, 3.0] # 自定义一个柱长度列
    rosetype_pie(country, confirmed, size, colors)

以上代码可得到的图如下:
在这里插入图片描述

2.2 全国各省市零新增天数玫瑰图

#coding:utf-8
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def get_data():
    colors = [
        '#FAE927', '#E9E416', '#C9DA36', '#9ECB3C', '#6DBC49',
        '#37B44E', '#3DBA78', '#14ADCF', '#209AC9', '#1E91CA',
        '#2C6BA0', '#2B55A1', '#2D3D8E', '#44388E', '#6A368B',
        '#7D3990', '#A63F98', '#C31C88', '#D52178', '#D5225B',
        '#D02C2A', '#D44C2D', '#F57A34', '#FA8F2F', '#D99D21',
    ]

    df = pd.read_csv('Wuhan-2019-nCoV.csv')  # 利用pandas读取数据
    df_province = df.loc[(~df['province'].isnull()) & (df['city'].isnull())] # 找到新中国各省、自治区的数据
    trans_list = ['湖北','广东','北京','吉林','上海','浙江','安徽','江西','山东','广西','海南','四川','贵州','云南','宁夏','天津','山西','黑龙江','河南','湖南','重庆','河北','辽宁','江苏','福建','陕西','台湾','香港','澳门','内蒙','甘肃','新疆','青海','西藏'] # 对于中国省、自治区重命名,方便后续操作
    def transfer(x):
        for i in trans_list:
            if i[:2] == x[:2]:
                return i
    df_province['pro'] = df_province['province'].apply(transfer) # 新增一列重命名后的省自治区名字
    df_province.drop('province', axis=1, inplace=True) # 删除原来的province列
    df_province.rename(columns={'pro': 'province'}, inplace=True) # 将新增列重命名为province
    df_province.to_csv('china_province_data.csv',index=0) # 保存至本地,方便后续操作
    province_list = df_province['province'].unique().tolist() # 各省/区的名字列表
    increase_day_list = []
    for i in province_list:
        df_province_i = df_province.loc[df_province['province'] == i] # 定位到省
        df_province_i_confirm_list = df_province_i['confirmed'].tolist()[::-1] # 获取确诊总人数列表,并倒序,将最近的日期放在列表最前面
        increase_day = 0
        for j in range(len(df_province_i_confirm_list) - 1):
            if df_province_i_confirm_list[j] == df_province_i_confirm_list[j + 1]: # 判断该元素与下一个是否相等,如果相等计数+1,如果不等跳出循环,最后的计数值就是零增长天数
                increase_day += 1
            else:
                break
        increase_day_list.append(increase_day)
    df1 = pd.DataFrame(data=increase_day_list,index=province_list,columns=['num']) # 创建df,排序,并除去0天的省份与数值
    df1 = df1.sort_values('num', ascending=False)
    df1 = df1.loc[df1['num'] != 0]
    province = df1.index.tolist()
    num = df1['num'].tolist()
    size = [22, 19, 17, 12, 11, 10, 9, 6.8, 6.6, 6.4, 6.2, 6.0, 5.8, 5.6, 5.4, 4.4, 4.2, 4.0, 3.8, 3.6, 2.4, 2.0, 1.8, 1.6, 1.4] # 自定义柱长列表
    rosetype_pie(province,num,size, colors)

def rosetype_pie(province,num,size,colors):
    plt.rcParams['font.sans-serif'] = ['SimHei']

    n= len(num)
    width = 2 * np.pi / n
    rad = np.cumsum([width] * n)

    plt.figure(figsize=(10, 10),dpi=500,)
    ax = plt.subplot(projection='polar')
    ax.set_ylim(-8, np.ceil(max(size) + 1))
    ax.set_theta_zero_location('N',5.0)
    ax.set_theta_direction(-1)
    ax.grid(False) 
    ax.spines['polar'].set_visible(False)
    ax.set_yticks([])
    ax.set_thetagrids([])
    ax.bar(rad, size, width=width, color=colors, alpha=1)
    ax.set_title("零新增", x=0.50,y=0.42,fontdict={'family':'Microsoft YaHei', 'size':50,'color':'#003366','fontweight':'heavy',}) # 设置标题
    ax.text(0.15*np.pi,-7.5," 多个省区市 \n确诊病例连续多日",fontdict={'family':'Microsoft YaHei', 'size':20,'color':'#003366','fontweight':'heavy'},ha="center",va="baseline",) # 设置文字
    # 设置天数标签
    for i in np.arange(n):
        if i < 3:
            ax.text(rad[i],
                    size[i]-4,
                    str(num[i])+'天',
                    fontstyle='normal',
                    fontweight='black',
                    fontdict={'family':'Microsoft YaHei', 'size':size[i],'color':'#003366',},
                    ha="center",
                    va="center",
                    )
        elif i <7:
            ax.text(rad[i]+0.06,
                    size[i]-2,
                    str(num[i]) + '天',
                    fontstyle='normal',
                    fontweight='black',
                    fontdict={'family': 'Microsoft YaHei', 'size': 12,'color':'white',},
                    ha="center",
                    va="center",
                    )
        elif i <15:
            ax.text(rad[i]+0.02,
                    size[i]-1.1,
                    str(num[i]) + '天',
                    fontstyle='normal',
                    fontweight='black',
                    fontdict={'family': 'Microsoft YaHei', 'size':11,'color':'white',},
                    ha="center",
                    va="center",
                    )
        elif i< 20:
            ax.text(rad[i]-0.06,
                    size[i]-0.8,
                    str(num[i]) + '天',
                    fontstyle='normal',
                    fontweight='black',
                    fontdict={'family': 'Microsoft YaHei', 'size': 9,'color':'white',},
                    ha="center",
                    va="center",
                    )
        else:
            ax.text(rad[i],
                    size[i]-0.7,
                    str(num[i]) + '天',
                    fontstyle='normal',
                    fontweight='black',
                    fontdict={'family': 'Microsoft YaHei', 'size': 9,'color':'white',},
                    ha="center",
                    va="center",
                    )

        # 设置省份标签
        for i in np.arange(n):
            if i < 3:
                ax.text(rad[i] - 0.01,
                        size[i] - 2,
                        province[i],
                        # alpha=0.8,#透明度
                        fontstyle='normal',
                        fontweight='black',
                        color='#003366',
                        size=size[i],
                        ha="center",
                        va="center",
                        )
            elif i < 7:
                ax.text(rad[i] - 0.03,
                        size[i] - 1.7,
                        province[i],
                        fontstyle='normal',
                        fontweight='black',
                        color='white',
                        size=12,
                        ha="center",
                        va="center",
                        )
            elif i < 15:
                ax.text(rad[i]-0.03,
                        size[i] - 2.3,
                        province[i],
                        fontstyle='normal',
                        fontweight='black',
                        color='white',
                        size=10,
                        ha="center",
                        va="center",
                        )
            elif i < 20:
                ax.text(rad[i]+0.04,
                        size[i] - 1.2,
                        province[i],
                        fontstyle='normal',
                        fontweight='black',
                        color='white',
                        size=9,
                        ha="center",
                        va="center",
                        )
            else:
                ax.text(rad[i],
                        size[i] +1,
                        province[i],
                        fontstyle='normal',
                        fontweight='black',
                        color=colors[i],
                        size=8,
                        ha="center",
                        va="center",
                        )

    plt.show()


if __name__ == '__main__':
    get_data()

运行以上代码可得如下图。按照例图的样式来设置文字标签还是比较繁琐的。
在这里插入图片描述

3.制作疫情地图

制作疫情地图主要使用pyecharts库,官方文档里有实例可参考,链接:https://gallery.pyecharts.org/#/Map/README。

3.1全国各省市目前确诊总人数疫情地图

# coding:utf-8
from pyecharts import options as opts
from pyecharts.charts import Map
import pandas as pd

def china_map(data_pair):
    Map(init_opts=opts.InitOpts(theme='dark', width='1600px', height='900px')
        ).add(
        series_name="",
        data_pair=data_pair,
        maptype="china",
        label_opts=opts.LabelOpts(
            is_show=True,
            position='inside',
        ),
        is_map_symbol_show=False,
    ).set_global_opts(
        title_opts=opts.TitleOpts(
            title="全国新冠疫情地图",
            pos_left="center",
            pos_top="20",
            title_textstyle_opts=opts.TextStyleOpts(
                font_size=24,
                font_family="Microsoft YaHei"),
            subtitle='统计时间截止至2020.09.21 21时',
            subtitle_textstyle_opts=opts.TextStyleOpts(
                font_size=12, font_family="Microsoft YaHei"),
        ),
        tooltip_opts=opts.TooltipOpts(
            is_show=True,
            formatter="{b} : 确诊{c}人",
        ),
        visualmap_opts=opts.VisualMapOpts(
            is_piecewise=True,
            dimension=0,
            pos_left="10",
            pos_bottom="20",
            pieces=[
                {'max': 9, 'min': 0, 'label': '0-9', 'color': '#FFFFCC'},
                {'max': 99, 'min': 10, 'label': '10-99', 'color': '#FFC4B3'},
                {'max': 499, 'min': 100, 'label': '100-499', 'color': '#FF9985'},
                {'max': 999, 'min': 500, 'label': '500-999', 'color': '#F57567'},
                {'max': 4999, 'min': 1000, 'label': '1000-4999', 'color': '#E64546'},
                {'max': 9999, 'min': 5000, 'label': '5000-9999', 'color': '#B80909'},
                {'max': 49999, 'min': 10000, 'label': '10000-49999', 'color': '#8A0808'},
                {'max': 99999, 'min': 50000, 'label': '>=50000', 'color': '#660000'}
            ]
        )
    ).render('中国疫情地图.html')


if __name__ == '__main__':
    df = pd.read_csv('china_province_data.csv')  # 利用pandas读取数据
    province_list = df[df['date']=='2020-09-21']['province'].tolist()  # 各省/区的名字列表
    data_list = df[df['date']=='2020-09-21']['confirmed'].tolist() # 数据
    data_pair = [x for x in zip(province_list, data_list)]
    china_map(data_pair)

得到的可视化图如下:
在这里插入图片描述

3.2全球各国家与地区目前确诊总人数疫情地图

#coding:utf-8
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.commons.utils import JsCode


# 国家名称中英文映射表,已根据疫情数据中的中文名称进行对应矫正,操作较为麻烦,目前尚有一些缺失国家及地区。此文暂不涉及。
name_map = {'Liechtenstein': '列支敦士登', 'Morocco': '摩洛哥', 'W. Sahara': '西撒哈拉', 'Serbia': '塞尔维亚', 'Afghanistan': '阿富汗',
                'Angola': '安哥拉', 'Albania': '阿尔巴尼亚', 'Aland': '奥兰群岛', 'Andorra': '安道尔',
                'United Arab Emirates': '阿联酋', 'Argentina': '阿根廷', 'Armenia': '亚美尼亚', 'American Samoa': '美属萨摩亚',
                'Fr. S. Antarctic Lands': '法属南半球和南极领地', 'Antigua and Barb.': '安提瓜和巴布达', 'Australia': '澳大利亚',
                'Austria': '奥地利', 'Azerbaijan': '阿塞拜疆', 'Burundi': '布隆迪', 'Belgium': '比利时', 'Benin': '贝宁',
                'Burkina Faso': '布基纳法索', 'Bangladesh': '孟加拉国', 'Bulgaria': '保加利亚', 'Bahrain': '巴林', 'Bahamas': '巴哈马',
                'Bosnia and Herz.': '波黑', 'Belarus': '白俄罗斯', 'Belize': '伯利兹', 'Bermuda': '百慕大', 'Bolivia': '玻利维亚',
                'Brazil': '巴西', 'Barbados': '巴巴多斯', 'Brunei': '文莱', 'Bhutan': '不丹', 'Botswana': '博茨瓦纳',
                'Central African Rep.': '中非', 'Canada': '加拿大', 'Switzerland': '瑞士', 'Chile': '智利', 'China': '中国',
                "Côte d'Ivoire": '科特迪瓦', 'Cameroon': '喀麦隆', 'Dem. Rep. Congo': '刚果(布)', 'Congo': '刚果(金)',
                'Colombia': '哥伦比亚', 'Comoros': '科摩罗', 'Cape Verde': '佛得角', 'Costa Rica': '哥斯达黎加', 'Cuba': '古巴',
                'Curaçao': '库拉索', 'Cayman Is.': '开曼群岛', 'N. Cyprus': '北塞浦路斯', 'Cyprus': '塞浦路斯', 'Czech Rep.': '捷克',
                'Germany': '德国', 'Djibouti': '吉布提', 'Denmark': '丹麦', 'Dominican Rep.': '多米尼加',
                'Algeria': '阿尔及利亚', 'Ecuador': '厄瓜多尔', 'Egypt': '埃及', 'Eritrea': '厄立特里亚', 'Spain': '西班牙',
                'Estonia': '爱沙尼亚', 'Ethiopia': '埃塞俄比亚', 'Finland': '芬兰', 'Fiji': '斐济', 'Falkland Is.': '福克兰群岛(马尔维纳斯)',
                'France': '法国', 'Faeroe Is.': '法罗群岛', 'Micronesia': '密克罗尼西亚', 'Gabon': '加蓬', 'United Kingdom': '英国',
                'Georgia': '格鲁吉亚', 'Ghana': '加纳', 'Guinea': '几内亚', 'Gambia': '冈比亚', 'Guinea-Bissau': '几内亚比绍',
                'Eq. Guinea': '赤道几内亚', 'Greece': '希腊', 'Grenada': '格林纳达', 'Greenland': '格陵兰', 'Guatemala': '危地马拉',
                'Guam': '关岛', 'Heard I. and McDonald Is.': '赫德岛和麦克唐纳群岛', 'Honduras': '洪都拉斯',
                'Croatia': '克罗地亚', 'Haiti': '海地', 'Hungary': '匈牙利', 'Indonesia': '印度尼西亚', 'Isle of Man': '英国属地曼岛',
                'India': '印度', 'Br. Indian Ocean Ter.': '英属印度洋领土', 'Ireland': '爱尔兰', 'Iran': '伊朗', 'Iraq': '伊拉克',
                'Iceland': '冰岛', 'Israel': '以色列', 'Italy': '意大利', 'Jamaica': '牙买加', 'Jersey': '泽西岛', 'Jordan': '约旦',
                'Japan': '日本', 'Siachen Glacier': '锡亚琴冰川', 'Kazakhstan': '哈萨克斯坦', 'Kenya': '肯尼亚',
                'Kyrgyzstan': '吉尔吉斯斯坦', 'Cambodia': '柬埔寨', 'Kiribati': '基里巴斯', 'Korea': '韩国', 'Kuwait': '科威特',
                'Lao PDR': '老挝', 'Lebanon': '黎巴嫩', 'Liberia': '利比里亚', 'Libya': '利比亚', 'Saint Lucia': '圣卢西亚',
                'Sri Lanka': '斯里兰卡', 'Lesotho': '莱索托', 'Lithuania': '立陶宛', 'Luxembourg': '卢森堡', 'Latvia': '拉脱维亚',
                'Moldova': '摩尔多瓦', 'Madagascar': '马达加斯加', 'Mexico': '墨西哥', 'Macedonia': '北马其顿', 'Mali': '马里',
                'Malta': '马耳他', 'Myanmar': '缅甸', 'Montenegro': '黑山', 'Mongolia': '蒙古', 'N. Mariana Is.': '北马里亚纳',
                'Mozambique': '莫桑比克', 'Mauritania': '毛利塔尼亚', 'Montserrat': '蒙特塞拉特', 'Mauritius': '毛里求斯',
                'Malawi': '马拉维', 'Malaysia': '马来西亚', 'Namibia': '纳米比亚', 'New Caledonia': '新喀里多尼亚', 'Niger': '尼日尔',
                'Nigeria': '尼日利亚', 'Nicaragua': '尼加拉瓜', 'Niue': '纽埃', 'Netherlands': '荷兰', 'Norway': '挪威',
                'Nepal': '尼泊尔', 'New Zealand': '新西兰', 'Oman': '阿曼', 'Pakistan': '巴基斯坦', 'Panama': '巴拿马', 'Peru': '秘鲁',
                'Philippines': '菲律宾', 'Palau': '帕劳', 'Papua New Guinea': '巴布亚新几内亚', 'Poland': '波兰',
                'Puerto Rico': '波多黎各', 'Dem. Rep. Korea': '朝鲜', 'Portugal': '葡萄牙', 'Paraguay': '巴拉圭',
                'Palestine': '巴勒斯坦', 'Fr. Polynesia': '法属波利尼西亚', 'Qatar': '卡塔尔', 'Romania': '罗马尼亚', 'Russia': '俄罗斯',
                'Rwanda': '卢旺达', 'Saudi Arabia': '沙特阿拉伯', 'Sudan': '苏丹', 'S. Sudan': '南苏丹', 'Senegal': '塞内加尔',
                'Singapore': '新加坡', 'S. Geo. and S. Sandw. Is.': '南乔治亚岛和南桑威奇群岛', 'Saint Helena': '圣赫勒拿',
                'Solomon Is.': '所罗门群岛', 'Sierra Leone': '塞拉利昂', 'El Salvador': '萨尔瓦多',
                'St. Pierre and Miquelon': '圣皮埃尔和密克隆', 'São Tomé and Principe': '圣多美和普林西比', 'Suriname': '苏里南',
                'Slovakia': '斯洛伐克', 'Slovenia': '斯洛文尼亚', 'Sweden': '瑞典', 'Swaziland': '斯威士兰', 'Seychelles': '塞舌尔',
                'Syria': '叙利亚', 'Turks and Caicos Is.': '特克斯和凯科斯群岛', 'Chad': '乍得', 'Togo': '多哥', 'Thailand': '泰国',
                'Tajikistan': '塔吉克斯坦', 'Turkmenistan': '土库曼斯坦', 'Timor-Leste': '东帝汶', 'Tonga': '汤加',
                'Trinidad and Tobago': '特立尼达和多巴哥', 'Tunisia': '突尼斯', 'Turkey': '土耳其', 'Tanzania': '坦桑尼亚',
                'Uganda': '乌干达', 'Ukraine': '乌克兰', 'Uruguay': '乌拉圭', 'United States': '美国', 'Uzbekistan': '乌兹别克斯坦',
                'St. Vin. and Gren.': '圣文森特和格林纳丁斯', 'Venezuela': '委内瑞拉', 'U.S. Virgin Is.': '美属维尔京群岛', 'Vietnam': '越南',
                'Vanuatu': '瓦努阿图', 'Samoa': '萨摩亚', 'Yemen': '也门', 'South Africa': '南非', 'Zambia': '赞比亚',
                'Zimbabwe': '津巴布韦', 'Somalia': '索马里', "Anguilla": "安圭拉", 'Dominica': '多米尼克','Gibraltar': '直布罗陀',
                'Guyana': '圭亚那','Saint Kitts and Nevis': '圣基茨和尼维斯','Monaco': '摩纳哥','Maldives': '马尔代夫','San Marino': '圣马力诺',
                'Vatican City': '梵蒂冈','British Virgin Islands': '英属维尔京群岛'}
def get_data():
    df = pd.read_csv('Wuhan-2019-nCoV.csv')  # 利用pandas读取数据
    df = df.loc[(df['date'] == '2020-09-21') & (df['province'].isnull())] # 定位到最近日期然后筛选国家
    country = df['country'].tolist() # 国家
    confirmed = df['confirmed'].tolist() # 确诊人数
    cure = df['cured'].tolist() # 治愈人数
    death = df['dead'].tolist() # 死亡人数
    data_pair = {(i, (j, x, y)) for i, j, x, y  in zip(country, confirmed, cure, death)}
    draw_global_pics(data_pair)
    # print(data_pair)


def draw_global_pics(data_pair):
    # jscode,用来显示数据
    mapformatter = """
                 function (params, ticket, callback) {
                 var result = '';
                     var xName = params.name;
                     var con = params.data.value[0];
                     var cure = params.data.value[1];
                     var death = params.data.value[2];
                     var value = params.value;

                     result += xName  + '<br/>';
                     result += '确诊人数: ' + value+ '<br/>';
                     result += '治愈人数: ' + cure + '<br/>';
                     result += '死亡人数: ' + death + '<br/>';
                     result += '<br/>';
                     console.log(params);
                 return result
                 }
              """
    world_map = (
            Map(init_opts=opts.InitOpts(theme='dark',width='2000px',height='1000px'))
            .add(
                '', 
                data_pair, 
                'world',
                name_map=name_map,
                is_map_symbol_show=False,)
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            .set_global_opts(
                title_opts=opts.TitleOpts(
                    title='全球新冠疫情累计确诊人数地图',pos_right='center',pos_top='2%',title_textstyle_opts=opts.TextStyleOpts(
                        font_size=24, font_family="Microsoft YaHei",
                    ),
                    subtitle='统计时间截止至2020.09.21',subtitle_textstyle_opts=opts.TextStyleOpts(
                        font_size=12, color="#CCCCCC",font_family="Microsoft YaHei"
                    ),
                ),
                legend_opts=opts.LegendOpts(is_show=False),
                visualmap_opts=opts.VisualMapOpts(
                    is_piecewise=True,
                    dimension=0,
                    pos_left="10",
                    pos_bottom='20',
                    pieces=[
                        {'max': 9, 'min': 0, 'label': '0-9', 'color': '#FFFFCC'},
                        {'max': 99, 'min': 10, 'label': '10-99', 'color': '#FFC4B3'},
                        {'max': 999, 'min': 100, 'label': '100-999', 'color': '#FF9985'},
                        {'max': 9999, 'min': 1000, 'label': '1000-9999', 'color': '#F57567'},
                        {'max': 99999, 'min': 10000, 'label': '10000-99999', 'color': '#E64546'},
                        {'max': 999999, 'min': 100000, 'label': '100000-999999', 'color': '#B80909'},
                        {'max': 4999999, 'min': 1000000, 'label': '1000000-4999999', 'color': '#8A0808'},
                        {'max': 9999999, 'min': 5000000, 'label': '>=5000000', 'color': '#660000'}
                    ]
                ),
                tooltip_opts=opts.TooltipOpts(is_show=True, formatter=JsCode(mapformatter))
            )
        )
    world_map.render('全球疫情地图多组数据.html')


if __name__ == '__main__':
    get_data()

得到的可视化地图如下,鼠标移动至国家上面可显示确诊人数、死亡人数等信息,若想添加其他信息可通过修改文中的jscode实现。
在这里插入图片描述

3.3全国各省市确诊人数发展趋势动态疫情地图

#coding:utf-8
import pandas as pd
import pyecharts.options as opts
from pyecharts.globals import ThemeType
from pyecharts.commons.utils import JsCode
from pyecharts.charts import Timeline,Map


def get_data():
    df = pd.read_csv('Wuhan-2019-nCoV.csv')  # 利用pandas读取数据
    df_province = df.loc[(df['date']>='2020-01-17')&(~df['province'].isnull())&(df['city'].isnull())] # 读取各省、自治区、直辖市历史数据
    def transfer(x):
        if x.endswith('自治区') or x.endswith('省') or x.endswith('特别行政区') or x.endswith('市'):
            return x.replace('壮族', '').replace('维吾尔', '').replace('回族', '').replace('自治区', '').replace('省', '').replace(
                '特别行政区', '').replace('市', '')
        else:
            return x
    df_province['province'] = df_province['province'].apply(transfer) # 修改各省、自治区、直辖市的名称,以便map接收

    date = df_province['date'].unique().tolist()[:30] # 可自行修改展示的天数
    data_list = []
    time_list = []

    # 将data_list设置成内置dict形式,格式为:[
    # {'time': '01.01', 'data': [{'name': '北京', 'value': [0, '北京']},{'name': '天津', 'value': [0, '天津']},]},
    # {'time': '01.02', 'data': [{'name': '北京', 'value': [1, '北京']},{'name': '天津', 'value': [1, '天津']},]},
    # ]
    for i in date:
        time = i[5:].replace('-', '.') # 将时间改为 12.01 形式,个人喜好。
        time_list.append(time)
        data = []
        name = df_province.loc[df_province['date'] == i]['province'].tolist()
        num = df_province.loc[df_province['date'] == i]['confirmed'].tolist()
        for x,y in zip(name,num):
            data.append({"name":x,"value":[y,x]})
        data_list.append({"time":time,"data":data})

    time_line(data_list,time_list)


def get_day_chart(data,day):
    map_data = [
        [[x["name"], x["value"]] for x in d["data"]] for d in data if d["time"] == day
    ][0]
    map_chart = (
        Map()
            .add(
            series_name="",
            data_pair=map_data,
            maptype="china",
            label_opts=opts.LabelOpts(is_show=False),
            is_map_symbol_show=False,
            itemstyle_opts={
                "normal": {"areaColor": "#323c48", "borderColor": "#404a59"},
                "emphasis": {
                    "label": {"show": Timeline},
                    "areaColor": "rgba(255,255,255, 0.5)",
                },
            },
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title="新冠疫情全国各省市发展趋势图",
                # subtitle="统计截止日期2020.03.01",
                pos_left="center",
                pos_top="top",
                title_textstyle_opts=opts.TextStyleOpts(
                    font_size=25, color="rgba(255,255,255, 0.9)"
                ),
            ),
            tooltip_opts=opts.TooltipOpts(
                is_show=True,
                formatter=JsCode(
                    """function(params) {
                    if ('value' in params.data) {
                        return params.data.value[1] + ': ' + params.data.value[0];
                    }
                }"""
                ),
            ),
            visualmap_opts=opts.VisualMapOpts(
                is_calculable=True,
                dimension=0,
                pos_left="10",
                pos_top="center",
                is_piecewise=True,
                pieces=[
                    {'max': 9, 'min': 0, 'label': '0-9', 'color': '#FFFFCC'},
                    {'max': 99, 'min': 10, 'label': '10-99', 'color': '#FFC4B3'},
                    {'max': 999, 'min': 100, 'label': '100-999', 'color': '#FF9985'},
                    {'max': 9999, 'min': 1000, 'label': '1000-9999', 'color': '#F57567'},
                    {'max': 19999, 'min': 10000, 'label': '10000-19999', 'color': '#E64546'},
                    {'max': 29999, 'min': 20000, 'label': '20000-29999', 'color': '#B80909'},
                    {'max': 39999, 'min': 30000, 'label': '30000-39999', 'color': '#8A0808'},
                    {'max': 49999, 'min': 40000, 'label': '40000-49999', 'color': '#660000'},
                    {'max': 99999, 'min': 50000, 'label': '>=50000', 'color': '#660000'}
                ]
            ),
        )
    )

    return map_chart


def time_line(data,time_list):
    timeline = Timeline(
        init_opts=opts.InitOpts(width="1570px", height="720px", theme=ThemeType.DARK)
    )
    for d in time_list:
        g = get_day_chart(data,d)
        timeline.add(g, time_point=d)

    timeline.add_schema(
        orient="vertical",
        is_auto_play=True,
        is_inverse=True,
        play_interval=1000,# 播放速度,单位ms
        pos_left="null",
        pos_right="5%",
        pos_top="20",
        pos_bottom="20",
        width="50",
        label_opts=opts.LabelOpts(is_show=True, color="#fff",interval=7),# interval 标签间隔
    )

    timeline.render('中国疫情发展趋势.html')


if __name__ == '__main__':
    get_data()

运行以上代码可以得到的图预览
在这里插入图片描述

3.4全球各大洲、国家与地区确诊人数发展趋势动态组合图

#coding:utf-8
import pandas as pd
import pyecharts.options as opts
from pyecharts.globals import ThemeType
from pyecharts.commons.utils import JsCode
from pyecharts.charts import Timeline, Grid, Bar, Map, Pie, Line

name_map = {'Liechtenstein': '列支敦士登', 'Morocco': '摩洛哥', 'W. Sahara': '西撒哈拉', 'Serbia': '塞尔维亚', 'Afghanistan': '阿富汗',
                'Angola': '安哥拉', 'Albania': '阿尔巴尼亚', 'Aland': '奥兰群岛', 'Andorra': '安道尔',
                'United Arab Emirates': '阿联酋', 'Argentina': '阿根廷', 'Armenia': '亚美尼亚', 'American Samoa': '美属萨摩亚',
                'Fr. S. Antarctic Lands': '法属南半球和南极领地', 'Antigua and Barb.': '安提瓜和巴布达', 'Australia': '澳大利亚',
                'Austria': '奥地利', 'Azerbaijan': '阿塞拜疆', 'Burundi': '布隆迪', 'Belgium': '比利时', 'Benin': '贝宁',
                'Burkina Faso': '布基纳法索', 'Bangladesh': '孟加拉国', 'Bulgaria': '保加利亚', 'Bahrain': '巴林', 'Bahamas': '巴哈马',
                'Bosnia and Herz.': '波黑', 'Belarus': '白俄罗斯', 'Belize': '伯利兹', 'Bermuda': '百慕大', 'Bolivia': '玻利维亚',
                'Brazil': '巴西', 'Barbados': '巴巴多斯', 'Brunei': '文莱', 'Bhutan': '不丹', 'Botswana': '博茨瓦纳',
                'Central African Rep.': '中非', 'Canada': '加拿大', 'Switzerland': '瑞士', 'Chile': '智利', 'China': '中国',
                "Côte d'Ivoire": '科特迪瓦', 'Cameroon': '喀麦隆', 'Dem. Rep. Congo': '刚果(布)', 'Congo': '刚果(金)',
                'Colombia': '哥伦比亚', 'Comoros': '科摩罗', 'Cape Verde': '佛得角', 'Costa Rica': '哥斯达黎加', 'Cuba': '古巴',
                'Curaçao': '库拉索', 'Cayman Is.': '开曼群岛', 'N. Cyprus': '北塞浦路斯', 'Cyprus': '塞浦路斯', 'Czech Rep.': '捷克',
                'Germany': '德国', 'Djibouti': '吉布提', 'Denmark': '丹麦', 'Dominican Rep.': '多米尼加',
                'Algeria': '阿尔及利亚', 'Ecuador': '厄瓜多尔', 'Egypt': '埃及', 'Eritrea': '厄立特里亚', 'Spain': '西班牙',
                'Estonia': '爱沙尼亚', 'Ethiopia': '埃塞俄比亚', 'Finland': '芬兰', 'Fiji': '斐济', 'Falkland Is.': '福克兰群岛(马尔维纳斯)',
                'France': '法国', 'Faeroe Is.': '法罗群岛', 'Micronesia': '密克罗尼西亚', 'Gabon': '加蓬', 'United Kingdom': '英国',
                'Georgia': '格鲁吉亚', 'Ghana': '加纳', 'Guinea': '几内亚', 'Gambia': '冈比亚', 'Guinea-Bissau': '几内亚比绍',
                'Eq. Guinea': '赤道几内亚', 'Greece': '希腊', 'Grenada': '格林纳达', 'Greenland': '格陵兰', 'Guatemala': '危地马拉',
                'Guam': '关岛', 'Heard I. and McDonald Is.': '赫德岛和麦克唐纳群岛', 'Honduras': '洪都拉斯',
                'Croatia': '克罗地亚', 'Haiti': '海地', 'Hungary': '匈牙利', 'Indonesia': '印度尼西亚', 'Isle of Man': '英国属地曼岛',
                'India': '印度', 'Br. Indian Ocean Ter.': '英属印度洋领土', 'Ireland': '爱尔兰', 'Iran': '伊朗', 'Iraq': '伊拉克',
                'Iceland': '冰岛', 'Israel': '以色列', 'Italy': '意大利', 'Jamaica': '牙买加', 'Jersey': '泽西岛', 'Jordan': '约旦',
                'Japan': '日本', 'Siachen Glacier': '锡亚琴冰川', 'Kazakhstan': '哈萨克斯坦', 'Kenya': '肯尼亚',
                'Kyrgyzstan': '吉尔吉斯斯坦', 'Cambodia': '柬埔寨', 'Kiribati': '基里巴斯', 'Korea': '韩国', 'Kuwait': '科威特',
                'Lao PDR': '老挝', 'Lebanon': '黎巴嫩', 'Liberia': '利比里亚', 'Libya': '利比亚', 'Saint Lucia': '圣卢西亚',
                'Sri Lanka': '斯里兰卡', 'Lesotho': '莱索托', 'Lithuania': '立陶宛', 'Luxembourg': '卢森堡', 'Latvia': '拉脱维亚',
                'Moldova': '摩尔多瓦', 'Madagascar': '马达加斯加', 'Mexico': '墨西哥', 'Macedonia': '北马其顿', 'Mali': '马里',
                'Malta': '马耳他', 'Myanmar': '缅甸', 'Montenegro': '黑山', 'Mongolia': '蒙古', 'N. Mariana Is.': '北马里亚纳',
                'Mozambique': '莫桑比克', 'Mauritania': '毛利塔尼亚', 'Montserrat': '蒙特塞拉特', 'Mauritius': '毛里求斯',
                'Malawi': '马拉维', 'Malaysia': '马来西亚', 'Namibia': '纳米比亚', 'New Caledonia': '新喀里多尼亚', 'Niger': '尼日尔',
                'Nigeria': '尼日利亚', 'Nicaragua': '尼加拉瓜', 'Niue': '纽埃', 'Netherlands': '荷兰', 'Norway': '挪威',
                'Nepal': '尼泊尔', 'New Zealand': '新西兰', 'Oman': '阿曼', 'Pakistan': '巴基斯坦', 'Panama': '巴拿马', 'Peru': '秘鲁',
                'Philippines': '菲律宾', 'Palau': '帕劳', 'Papua New Guinea': '巴布亚新几内亚', 'Poland': '波兰',
                'Puerto Rico': '波多黎各', 'Dem. Rep. Korea': '朝鲜', 'Portugal': '葡萄牙', 'Paraguay': '巴拉圭',
                'Palestine': '巴勒斯坦', 'Fr. Polynesia': '法属波利尼西亚', 'Qatar': '卡塔尔', 'Romania': '罗马尼亚', 'Russia': '俄罗斯',
                'Rwanda': '卢旺达', 'Saudi Arabia': '沙特阿拉伯', 'Sudan': '苏丹', 'S. Sudan': '南苏丹', 'Senegal': '塞内加尔',
                'Singapore': '新加坡', 'S. Geo. and S. Sandw. Is.': '南乔治亚岛和南桑威奇群岛', 'Saint Helena': '圣赫勒拿',
                'Solomon Is.': '所罗门群岛', 'Sierra Leone': '塞拉利昂', 'El Salvador': '萨尔瓦多',
                'St. Pierre and Miquelon': '圣皮埃尔和密克隆', 'São Tomé and Principe': '圣多美和普林西比', 'Suriname': '苏里南',
                'Slovakia': '斯洛伐克', 'Slovenia': '斯洛文尼亚', 'Sweden': '瑞典', 'Swaziland': '斯威士兰', 'Seychelles': '塞舌尔',
                'Syria': '叙利亚', 'Turks and Caicos Is.': '特克斯和凯科斯群岛', 'Chad': '乍得', 'Togo': '多哥', 'Thailand': '泰国',
                'Tajikistan': '塔吉克斯坦', 'Turkmenistan': '土库曼斯坦', 'Timor-Leste': '东帝汶', 'Tonga': '汤加',
                'Trinidad and Tobago': '特立尼达和多巴哥', 'Tunisia': '突尼斯', 'Turkey': '土耳其', 'Tanzania': '坦桑尼亚',
                'Uganda': '乌干达', 'Ukraine': '乌克兰', 'Uruguay': '乌拉圭', 'United States': '美国', 'Uzbekistan': '乌兹别克斯坦',
                'St. Vin. and Gren.': '圣文森特和格林纳丁斯', 'Venezuela': '委内瑞拉', 'U.S. Virgin Is.': '美属维尔京群岛', 'Vietnam': '越南',
                'Vanuatu': '瓦努阿图', 'Samoa': '萨摩亚', 'Yemen': '也门', 'South Africa': '南非', 'Zambia': '赞比亚',
                'Zimbabwe': '津巴布韦', 'Somalia': '索马里', "Anguilla": "安圭拉", 'Dominica': '多米尼克','Gibraltar': '直布罗陀',
                'Guyana': '圭亚那','Saint Kitts and Nevis': '圣基茨和尼维斯','Monaco': '摩纳哥','Maldives': '马尔代夫','San Marino': '圣马力诺',
                'Vatican City': '梵蒂冈','British Virgin Islands': '英属维尔京群岛'}

def get_data():
    df = pd.read_csv('Wuhan-2019-nCoV.csv') # 读取数据
    df = df.loc[df['province'].isnull()] # 定位到全球国家数据,即province列是nan值

    # 每个国家对应的洲dict
    continent = {
        '亚洲': ['中国', '蒙古', '朝鲜', '韩国', '日本', '菲律宾', '越南', '老挝', '柬埔寨', '缅甸', '泰国', '马来西亚', '文莱', '新加坡', '印度尼西亚', '东帝汶',
               '尼泊尔','不丹', '孟加拉国', '印度', '巴基斯坦', '斯里兰卡', '马尔代夫', '哈萨克斯坦', '吉尔吉斯斯坦', '塔吉克斯坦', '乌兹别克斯坦', '土库曼斯坦', '阿富汗',
               '伊拉克','伊朗', '北马里亚纳','叙利亚', '约旦', '黎巴嫩', '以色列', '巴勒斯坦', '沙特阿拉伯', '巴林', '卡塔尔', '科威特', '阿联酋', '阿曼', '也门', '格鲁吉亚', 
               '亚美尼亚','阿塞拜疆','土耳其'],
        '欧洲': ['英国', '法国', '荷兰', '爱尔兰', '比利时', '卢森堡', '摩纳哥', '丹麦', '挪威', '瑞典', '芬兰', '冰岛', '罗马尼亚', '保加利亚', '塞尔维亚', '黑山',
               '北马其顿', '阿尔巴尼亚', '希腊', '斯洛文尼亚', '克罗地亚', '波黑', '意大利', '梵蒂冈', '圣马力诺', '马耳他', '西班牙', '葡萄牙', '安道尔',
               '塞浦路斯', '波兰', '捷克', '斯洛伐克', '奥地利', '匈牙利', '德国', '瑞士', '列支敦士登', '爱沙尼亚', '拉脱维亚', '立陶宛', '白俄罗斯', '俄罗斯',
               '乌克兰', '泽西岛','摩尔多瓦', '海峡群岛', '福克兰群岛(马尔维纳斯)', '英国属地曼岛', '圣马丁', '法罗群岛', '直布罗陀'],
        '非洲': ['埃及', '利比亚', '突尼斯', '阿尔及利亚', '摩洛哥', '埃塞俄比亚', '厄立特里亚', '索马里', '吉布提', '肯尼亚', '坦桑尼亚', '乌干达', '卢旺达', '布隆迪',
               '塞舌尔','苏丹', '南苏丹', '乍得', '中非', '喀麦隆', '赤道几内亚', '加蓬', '刚果(布)', '刚果(金)', '圣多美和普林西比', '毛利塔尼亚', '塞内加尔', '冈比亚',
               '马里','布基纳法索', '几内亚', '几内亚比绍', '佛得角', '塞拉利昂', '利比里亚', '科特迪瓦', '加纳', '多哥', '贝宁', '尼日尔', '尼日利亚', '赞比亚', '安哥拉',
               '津巴布韦','马拉维', '莫桑比克', '博茨瓦纳', '纳米比亚', '南非', '斯威士兰', '莱索托', '马达加斯加', '科摩罗', '毛里求斯', '马约特', '留尼汪'],
        '北美洲': ['加拿大', '美国', '墨西哥', '危地马拉', '伯利兹', '萨尔瓦多', '洪都拉斯', '尼加拉瓜', '哥斯达黎加', '巴拿马', '巴哈马', '古巴', '牙买加', '海地',
                '圣皮埃尔和密克隆','多米尼加', '安提瓜和巴布达', '圣基茨和尼维斯', '多米尼克', '圣卢西亚', '圣文森特和格林纳丁斯', '格林纳达', '巴巴多斯', '特立尼达和多巴哥', 
                '圣皮埃尔', '百慕大','英属维尔京群岛', '安圭拉', '特克斯和凯科斯群岛', '蒙特塞拉特', '格陵兰', '瓜德罗普', '开曼群岛', '阿鲁巴', '库拉索', '圣巴泰勒米岛',
                '马提尼克', '波多黎各','美属维尔京群岛'],
        '南美洲': ['哥伦比亚', '委内瑞拉', '圭亚那', '苏里南', '厄瓜多尔', '秘鲁', '玻利维亚', '巴西', '智利', '阿根廷', '乌拉圭', '巴拉圭', '法属圭亚那'],
        '大洋洲': ['澳大利亚', '新西兰', '帕劳', '密克罗尼西亚联邦', '马绍尔群岛', '基里巴斯', '瑙鲁', '巴布亚新几内亚', '所罗门群岛', '瓦努阿图', '斐济', '图瓦卢', '萨摩亚',
                '汤加', '关岛','库克群岛', '纽埃', '新喀里多尼亚', '法属波利尼西亚']
    }
    def assortment(x): # 定义一个分类函数
        for k,v in continent.items():
            if x in v:
                return k
    df['contient'] = df['country'].apply(assortment) # df中添加一列各国对应的大洲名
    time_list = df.loc[df['country'] == '中国']['date'].unique().tolist() # 时间列表
    data_list = [] # 所有数据列表
    for i in time_list:
        map_data = []
        country_name = df.loc[df['date'] == i]['country'].tolist() # 国家列表
        country_confirm_num = df.loc[df['date'] == i]['confirmed'].tolist() # 与国家列表相对应的确诊人数列表
        for x,y in zip(country_name,country_confirm_num):
            map_data.append({"name":x,"value":[y,x]})

        global_confirm_num = df.loc[df['date'] == i].sum()['confirmed'] # 全球确诊人数列表
        contient_confirm_num = df.loc[df['date'] == i].groupby('contient').sum()['confirmed'].tolist() # 各大洲确诊人数列表
        contient_name = df.loc[df['date'] == i].groupby('contient').sum()['confirmed'].index.tolist() # 大洲名
        pie_data = [i for i in zip(contient_name, contient_confirm_num)] # 饼图数据
        bar_data = [] # 柱状图数据
        df_top25_confirm_country = pd.DataFrame(data=country_confirm_num,index=country_name,columns=['num'])
        df_top25_confirm_country = df_top25_confirm_country.sort_values('num',ascending=False).head(25) # 全球确诊数前25位国家与确诊数df
        top25_confirm_country= df_top25_confirm_country.index.tolist() # 全球确诊数前25位国家名字列表
        top25_confirm_country_num =  df_top25_confirm_country['num'].tolist() # 全球确诊数前25位国家确诊数列表
        for a,b in zip(top25_confirm_country,top25_confirm_country_num):
            bar_data.append({"name":a,"value":b})

        data_list.append({"time":i,"data": {"map_data":map_data,"bar_data": {"name":top25_confirm_country,"value":bar_data},"pie_data":pie_data,"line_data":global_confirm_num}})
    time_line(data_list,time_list)


def get_day_chart(data,time_list,day):

    # global_confirm_num = [i['data']['line_data'] for i in data] # 这么传确诊数据画折线图时有点问题,目前的解决方法是打印出来再放在函数内
    global_confirm_num = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 6, 6, 7, 8, 9, 14, 18, 21, 29, 30, 33, 35, 37, 37, 37, 37, 40, 43, 44, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 47, 62, 198, 275, 295, 445, 577, 839, 1305, 1998, 2777, 4556, 6030, 7784, 9777, 11876, 14465, 17290, 20523, 24324, 28018, 31380, 34865, 37453, 40535, 43092, 45128, 59283, 64435, 67091, 69177, 71326, 73331, 75181, 76109, 77089, 77615, 78390, 79153, 80059, 80776, 81718, 82907, 84298, 86274, 87503, 89938, 92473, 94489, 96923, 100787, 104005, 107947, 111475, 116404, 121750, 129206, 139196, 148507, 161895, 174424, 187921, 205334, 229007, 254088, 287385, 318075, 359038, 396304, 439388, 491472, 555936, 620524, 685374, 743479, 809739, 885183, 963547, 1050006, 1154606, 1228703, 1296919, 1376639, 1457146, 1537834, 1627708, 1726067, 1801472, 1871663, 1950795, 2026797, 2117948, 2160870, 2276746, 2363064, 2437346, 2511944, 2594414, 2668783, 2761940, 2866823, 2948982, 3026987, 3092487, 3168018, 3251817, 3342236, 3430121, 3516219, 3595614, 3675262, 3763095, 3856621, 3954198, 4046293, 4135407, 4220903, 4296056, 4378064, 4471726, 4567793, 4665396, 4754391, 4841589, 4928151, 5019712, 5128065, 5232357, 5344240, 5440546, 5536452, 5625886, 5722044, 5828573, 5949338, 6070180, 6201973, 6302943, 6410130, 6528854, 6615088, 6744678, 6894885, 7023370, 7129890, 7240586, 7363639, 7504001, 7644944, 7774961, 7914745, 8036193, 8157051, 8311584, 8440982, 8625327, 8806970, 8965984, 9088717, 9236180, 9402366, 9576377, 9761393, 9959246, 10139301, 10301991, 10463382, 10637573, 10858187, 11042322, 11239529, 11434207, 11612189, 11789840, 12005058, 12220325, 12445327, 12677164, 12895696, 13093522, 13285775, 13517315, 13755265, 14009299, 14253687, 14481482, 14704273, 14921151, 15152108, 15455658, 15732548, 16020885, 16275298, 16501128, 16708041, 16948893, 17242062, 17573340, 17844591, 18089190, 18317797, 18511123, 18787085, 19050863, 19333035, 19612089, 19874305, 20098137, 20335304, 20611420, 20878388, 21138130, 21418432, 21705433, 21897348, 22141369, 22394936, 22674711, 22932805, 23216277, 23447688, 23651995, 23904456, 24138940, 24404401, 24714688, 24993449, 25241808, 25473263, 25733181, 26005959, 26278094, 26562178, 26893408, 27155320, 27378802, 27568865, 27834732, 28121685, 28453449, 28767461, 29026540, 29221414, 29522135, 29804754, 30143923, 30451420, 30798922, 31096846, 31319306]
    minNum = 0
    maxNum = 7500000 # 国家确诊人数的最大值

    map_data = [
        [[x["name"], x["value"]] for x in d["data"]["map_data"]] for d in data if d["time"] == day
    ][0]

    map_chart = (
        Map()
            .add(
            series_name="",
            data_pair=map_data,
            zoom=1,
            center=[80, 10],
            maptype='world',
            name_map=name_map,
            is_map_symbol_show=False,
            # itemstyle_opts={
            #     "normal": {"areaColor": "#323c48", "borderColor": "#404a59"},
            #     "emphasis": {
            #         "label": {"show": Timeline},
            #         "areaColor": "rgba(255,255,255, 0.5)",
            #     },
            # },
            itemstyle_opts={
                "normal": {"areaColor": "#323c48", "borderColor": "#404a59"},
                "emphasis": {
                    "areaColor": "rgba(255,255,255, 0.5)",
                },
            },
        )
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title="全球新冠疫情地图{}".format(time_list[-1]),
                subtitle="",
                pos_left="center",
                pos_top="2%",
                title_textstyle_opts=opts.TextStyleOpts(
                    font_size=25, color="rgba(255,255,255, 0.9)"
                ),
            ),
            tooltip_opts=opts.TooltipOpts(
                is_show=True,
                formatter=JsCode(
                    """function(params) {
                    if ('value' in params.data) {
                        return params.data.value[1] + ': ' + params.data.value[0];
                    }
                }"""
                ),
            ),
        )
    )

    data_mark = []
    i = 0
    for x in time_list:
        if x == day:
            data_mark.append(global_confirm_num[i])
        else:
            data_mark.append("")
        i = i + 1
    line_chart = (
        Line()
            .add_xaxis(time_list)
            .add_yaxis("", global_confirm_num)
            .add_yaxis(
            "",
            data_mark,
            markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")])
        )
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False), )
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title="全球新冠疫情确诊总人数发展趋势", pos_left="72%", pos_top="7%"
            ),
            yaxis_opts=opts.AxisOpts(
                is_show=False,
            ),
        )
    )

    bar_x_data = [d['data']["bar_data"]["name"] for d in data if d["time"] == day][0]
    bar_y_data = [d['data']["bar_data"]["value"] for d in data if d["time"] == day][0]
    bar = (
        Bar()
            .add_xaxis(xaxis_data=bar_x_data)
            .add_yaxis(
            series_name="",
            yaxis_data=bar_y_data,
            yaxis_index=1,
            label_opts=opts.LabelOpts(
                is_show=True, position="right", formatter="{b} : {c}"
            ),
        )
            .reversal_axis()
            .set_global_opts(
            xaxis_opts=opts.AxisOpts(max_=maxNum, axislabel_opts=opts.LabelOpts(is_show=False)),
            yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(is_show=False)),
            tooltip_opts=opts.TooltipOpts(is_show=False),
            visualmap_opts=opts.VisualMapOpts(
                is_piecewise=True,
                is_calculable=True,
                dimension=0,
                pos_left="10",
                pos_top="26%",
                pieces=[
                    {'max': 9, 'min': 0, 'label': '0-9', 'color': '#FFF5EE'},
                    {'max': 99, 'min': 10, 'label': '10-99', 'color': '#FFE4C4'},
                    {'max': 999, 'min': 100, 'label': '100-999', 'color': '#FFC4B3'},
                    {'max': 9999, 'min': 1000, 'label': '1000-9999', 'color': '#FF9985'},
                    {'max': 99999, 'min': 10000, 'label': '10000-99999', 'color': '#F57567'},
                    {'max': 499999, 'min': 100000, 'label': '100000-499999', 'color': '#E64546'},
                    {'max': 999999, 'min': 500000, 'label': '500000-999999', 'color': '#B80909'},
                    {'max': 4999999, 'min': 1000000, 'label': '1000000-4999999', 'color': '#8A0808'},
                    {'max': 99999999, 'min': 5000000, 'label': '>=5000000', 'color': '#660000'}
                ]
            ),
            graphic_opts=[
                opts.GraphicGroup(
                    graphic_item=opts.GraphicItem(
                        rotation=JsCode("Math.PI / 4"),
                        bounding="raw",
                        right=120,
                        bottom=120,
                        z=120,
                    ),
                    children=[
                        opts.GraphicRect(
                            graphic_item=opts.GraphicItem(left="center", top="center", z=100),
                            graphic_shape_opts=opts.GraphicShapeOpts(width=400, height=80),
                            graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
                                fill="rgba(0,0,0,0.3)"
                            ),
                        ),
                        opts.GraphicText(
                            graphic_item=opts.GraphicItem(left="center", top="center", z=100),
                            graphic_textstyle_opts=opts.GraphicTextStyleOpts(
                                text=f"{str(day)}",
                                font="bold 30px Microsoft YaHei",
                                graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(fill="#fff"),
                            ),
                        ),
                    ],
                )
            ],
        )
    )

    pie_data = [
        d["data"]["pie_data"] for d in data if d["time"] == day
    ][0]
    pie = (
        Pie()
            .add(
            series_name="",
            data_pair=pie_data,
            radius=["15%", "35%"],
            center=["80.5%", "74%"],
            label_opts=opts.LabelOpts(formatter="{b}:{d}%", position="outside", font_size=16), # formatter="{b}\n确诊人数:{c}\n占比:{d}%"
            itemstyle_opts=opts.ItemStyleOpts(
                border_width=1, border_color="rgba(0,0,0,0.3)"
            ),
        )
            .set_global_opts(
            tooltip_opts=opts.TooltipOpts(is_show=False),
            legend_opts=opts.LegendOpts(is_show=False),
        )
    )

    grid_chart = (
        Grid()
            .add(
            bar,
            grid_opts=opts.GridOpts(
                pos_left="15", pos_right="40%", pos_top="50%", pos_bottom="5"
            ),
        )
            .add(
            line_chart,
            grid_opts=opts.GridOpts(
                pos_left="65%", pos_right="5%", pos_top="5", pos_bottom="55%"
            ),
        )
            .add(pie, grid_opts=opts.GridOpts())
            .add(map_chart, grid_opts=opts.GridOpts()
        )
    )

    return grid_chart


def time_line(data,time_list):

    timeline = Timeline(
        init_opts=opts.InitOpts(width="2250px", height="1000px", theme=ThemeType.DARK)
    )
    for d in time_list:
        g = get_day_chart(data,time_list,d)
        timeline.add(g, time_point=str(d))

    timeline.add_schema(
        orient="vertical",
        is_auto_play=False,
        is_inverse=True,
        play_interval=500,
        pos_left="null",
        pos_right="20",
        pos_top="20",
        pos_bottom="20",
        width="60",
        label_opts=opts.LabelOpts(is_show=False),#(is_show=True, color="#fff",interval=15),
    )

    timeline.render("全球疫情发展趋势.html")


if __name__ == "__main__":
    get_data()
    

运行以上代码可得到的图预览:
在这里插入图片描述

4.制作词云

#coding:utf-8
import pandas as pd
import numpy as np
from wordcloud import WordCloud
from matplotlib import colors
from PIL import Image


def wordcloude_china():
    df = pd.read_csv('Wuhan-2019-nCoV.csv') # 读取数据
    city = df.loc[(~df['city'].isnull())&(df['date']=='2020-09-21')]['city'].tolist() # 定位到市区最新数据
    confirm_num = df.loc[(~df['city'].isnull())&(df['date']=='2020-09-21')]['confirmed'].tolist()
    data = {i:j for i,j in zip(city, confirm_num)}

    word_cloud = WordCloud(
        font_path='C:/Windows/Fonts/msyhbd.ttc',# 显示中文需要加载本地中文字体
        background_color='white', # 设置背景色
        width=1000,
        height=600)
    word_cloud.generate_from_frequencies(data)
    word_cloud.to_file('中国疫情词云图.png')


def wordcloude_world():
    df = pd.read_csv('Wuhan-2019-nCoV.csv') # 读取数据
    country = df.loc[(df['province'].isnull())&(df['date']=='2020-09-21')]['country'].tolist() # 定位到全球国家最新数据
    confirm_num = df.loc[(df['province'].isnull())&(df['date']=='2020-09-21')]['confirmed'].tolist()
    data = {i:j for i,j in zip(country, confirm_num)}

    color_list = ['#CD0000', '#CD3700', '#CD4F39', '#CD5B45', '#CD6600', '#CD8500', '#CD8162', '#CD7054', '#CD3333', '#CD2626', '#CD661D', '#CD853F', '#CDBA96', '#CDAA7D', '#CD6839', '#CD5555', '#CD9B9B', '#CD950C', '#CD9B1D', '#CDAD00', '#CDCD00', '#CDCDB4', '#CDBE70', '#CDC673', '#A2CD5A', '#9ACD32', '#66CD00', '#00CD00', '#00CD66', '#7CCD7C', '#43CD80', '#9BCD9B', '#66CDAA', '#79CDCD', '#00CDCD', '#00C5CD', '#7AC5CD', '#96CDCD', '#EE0000', '#EE4000', '#EE5C42', '#EE6A50', '#EE7600', '#EE9A00', '#EE9572', '#EE8262', '#EE3B3B', '#EE2C2C', '#EE7621', '#EE9A49', '#EED8AE', '#EEC591', '#EE7942', '#EE6363', '#EEB4B4', '#EEAD0E', '#EEB422', '#EEC900', '#EEEE00', '#EEEED1', '#EEDC82', '#EEE685', '#BCEE68', '#B3EE3A', '#76EE00', '#00EE00', '#00EE76', '#90EE90', '#4EEE94', '#B4EEB4', '#76EEC6', '#8DEEEE', '#00EEEE', '#00E5EE', '#8EE5EE', '#AEEEEE', '#FF0000', '#FF4500', '#FF6347', '#FF7256', '#FF7F00', '#FFA500', '#FFA07A', '#FF8C69', '#FF4040', '#FF3030', '#FF7F24', '#FFA54F', '#FFE7BA', '#FFD39B', '#FF8247', '#FF6A6A', '#FFC1C1', '#FFB90F', '#FFC125', '#FFD700', '#FFFF00', '#FFFFE0', '#FFEC8B', '#FFF68F', '#CAFF70', '#C0FF3E', '#7FFF00', '#00FF00', '#00FF7F', '#9AFF9A', '#54FF9F', '#C1FFC1', '#7FFFD4', '#97FFFF', '#00FFFF', '#00F5FF', '#98F5FF', '#BBFFFF', '#8B0000', '#8B2500', '#8B3626', '#8B3E2F', '#8B4500', '#8B5A00', '#8B5742', '#8B4C39', '#8B2323', '#8B1A1A', '#8B4513', '#8B5A2B', '#8B7E66', '#8B7355', '#8B4726', '#8B3A3A', '#8B6969', '#8B658B', '#8B6914', '#8B7500', '#8B8B00', '#8B8B7A', '#8B814C', '#8B864E', '#6E8B3D', '#698B22', '#008B00', '#458B00', '#008B45', '#548B54', '#2E8B57', '#698B69', '#458B74', '#528B8B', '#008B8B', '#00868B', '#53868B', '#668B8B']
    colormap = colors.ListedColormap(color_list) # 将自定义的色号转化为wc可用的colormap
    mask = np.array(Image.open('mask.jpg')) # 打开本地口罩白底图---可以去淘宝、京东搜索口罩然后找白底图

    wc = WordCloud(
        font_path='C:/Windows/Fonts/msyhbd.ttc',
        background_color='white',
        colormap=colormap,
        prefer_horizontal=0.8,# 水平显示的文字相对于竖直显示文字的比例
        mask=mask,# 添加蒙版
        # contour_width=0.1,
        # contour_color='green',
        relative_scaling=0.3,# 设置字体大小与词频的关联程度为0.3
        max_font_size=80,# 设置显示的最大字体
        scale = 3,# 提升图片的精细程度,3为放大3倍
        max_words = 250, # 显示的最大词语数量
        width=1600,
        height=1200)
    wc.generate_from_frequencies(data)
    wc.to_file('全球疫情词云图.png')


if __name__ == '__main__':
    wordcloude_china()
    wordcloude_world()

可得的词云图如下:
在这里插入图片描述
在这里插入图片描述
码字不易,若对您有所帮助,望能关注收藏点赞,谢谢

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐