前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Python绘制全国各省新型冠状病毒疫情状况

用Python绘制全国各省新型冠状病毒疫情状况

作者头像
博文视点Broadview
发布2020-06-10 16:58:27
1.2K0
发布2020-06-10 16:58:27
举报

本文使用数据说明:数据截至2月2日24时,累计报告确诊病例17205例,现有重症病例2296例,累计死亡病例361例,累计治愈出院475例。疑似病例21558例。

图表来自百度疫情实时大数据报告

最近在家关注疫情之余,用Python绘制了全国各省新型冠状病毒疫情状况动态图表,其地图数据来源于腾讯的疫情实时追踪展示地图:https://github.com/dongli/china-shapefiles

全国各省的疫情实时数据来源于丁香园:https://github.com/BlankerL/DXY-2019-nCoV-Data/blame/master/DXYArea.csv#

http://mpvideo.qpic.cn/0bf244aaeaaabyaa5pryibpfbz6daltqaaqa.f10003.mp4?dis_k=e7ba482b6377684a30d1e8cf7b15227c&dis_t=1591779391

具体实现代码

我们使用下载的china.shp和china_nine_dotted_line.shp两个文件,可以绘制如下所示的带南海地区单独展示的中国地图

代码语言:javascript
复制
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
from mpl_toolkits.basemap import Basemap
import matplotlib.dates as mdates
import matplotlib as mpl
plt.rcParams['font.sans-serif']=['SimHei']  #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False    #用来正常显示负号

%matplotlib inlin
代码语言:javascript
复制
fig = plt.figure(figsize=(12,12))
ax = fig.gca()

#plt.subplots_adjust(left=0.12, right=0.98, top=0.75, bottom=0)
basemap = Basemap(llcrnrlon= 80,llcrnrlat=10,urcrnrlon=150,urcrnrlat=50,projection='poly',lon_0 = 116.65,lat_0 = 40.02,ax = ax)
basemap.readshapefile(shapefile = 'china',name = "province", drawbounds=True)
basemap.readshapefile('china_nine_dotted_line',name ='section', drawbounds=True)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['left'].set_color('none')
ax.spines['bottom'].set_color('none')

df_mapData = pd.DataFrame(basemap.province_info)
df_mapData['OWNER'] = [x.strip('\x00') for x in df_mapData['OWNER']] #省份
df_mapData['FCNAME'] =[x.strip('\x00') for x in df_mapData['FCNAME']]

province=np.unique(df_mapData['OWNER'])
color = sns.husl_palette(len(province),h=15/360, l=.65, s=1).as_hex()
colors = dict(zip(province.tolist(),color))


for info, shape in zip(basemap.province_info, basemap.province): 
        pname = info['OWNER'].strip('\x00')
        fcname = info['FCNAME'].strip('\x00')
        if pname != fcname: # 不绘制海岛
            continue
        color = colors[pname]
        
        poly = Polygon(shape, facecolor=color, edgecolor='k')
        ax.add_patch(poly)


ax2= fig.add_axes([0.7, 0.25, 0.15, 0.15])
basemap2 = Basemap(llcrnrlon= 106.55,llcrnrlat=4.61,urcrnrlon=123.58,urcrnrlat=25.45,projection='poly',lon_0 = 116.65,lat_0 = 40.02,ax = ax2)
basemap2.readshapefile(shapefile = 'china',name = "province", drawbounds=True)
basemap2.readshapefile('china_nine_dotted_line',name ='section', drawbounds=True)

for info, shape in zip(basemap2.province_info, basemap2.province): 
        pname = info['OWNER'].strip('\x00')
        fcname = info['FCNAME'].strip('\x00')
        if pname != fcname: # 不绘制海岛
            continue       
        color = colors[pname] 
        poly = Polygon(shape, facecolor=color, edgecolor='k')
        ax2.add_patch(poly)
代码语言:javascript
复制
from datetime import datetime
from matplotlib import cm,colors

df_data=pd.read_csv('DXYArea.csv')
df_data['updateTime']=[datetime.strptime(d, '%Y-%m-%d %H:%M:%S.%f').date() for d in df_data['updateTime']]


df_data['month']=[d.month for d in df_data['updateTime']]
df_data['day']=[d.strftime('%d') for d in df_data['updateTime']]
df_data['date']=[d.strftime('%m-%d') for d in df_data['updateTime']]
df_data=df_data.drop_duplicates(subset = ['month','day','provinceName']).reset_index()

labels = [ '1-9', '10-99', '100-999', '1000-10000','>10000']
n_colors=len(labels)
color=[colors.rgb2hex(x) for x in cm.get_cmap( 'YlOrRd',n_colors)(np.linspace(0, 1, n_colors))]
color_array=[x for x in cm.get_cmap( 'YlOrRd',n_colors)(np.linspace(0, 1, n_colors))]

df_data['lablels']=pd.cut(df_data['province_confirmedCount'], [0,10,100,1000,10000,100000], labels=labels)
df_data['color']=[color[i] for i in df_data['lablels'].values.codes]
df_data=df_data.set_index('provinceName',drop=False)

days=[ '24', '25', '26', '27', '28', '29', '30', '31','01', '02', '03']#np.unique(df_data['day'])

df_day=df_data[df_data['day']==days[7]][['provinceName','province_confirmedCount','day','month','color','date']]
代码语言:javascript
复制
def draw_ChinaMap(Num_day):
    ax.clear()

    df_day=df_data[df_data['day']==days[Num_day]][['provinceName','province_confirmedCount','day','month','color','date']]

    basemap = Basemap(llcrnrlon= 80,llcrnrlat=10,urcrnrlon=150,urcrnrlat=50,projection='poly',lon_0 = 116.65,lat_0 = 40.02,ax = ax)
    basemap.readshapefile(shapefile = 'C:/Users/Peter_Zhang/Desktop/Hex_Map/china_shapefiles_master/china',
                      name = "province", drawbounds=True)
    basemap.readshapefile('C:/Users/Peter_Zhang/Desktop/Hex_Map/china_shapefiles_master/china_nine_dotted_line',
                       name ='section', drawbounds=True)
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.spines['left'].set_color('none')
    ax.spines['bottom'].set_color('none')


    for info, shape in zip(basemap.province_info, basemap.province): 
            pname = info['OWNER'].strip('\x00')
            fcname = info['FCNAME'].strip('\x00')
            if pname != fcname: # 不绘制海岛
                continue

            color='white'
            if sum(df_day['provinceName']==pname)>0:
                color = df_day.loc[pname,'color']

            poly = Polygon(shape, facecolor=color, edgecolor='k')
            ax.add_patch(poly) 

    patches = [ mpatches.Patch(color=color_array[i], label=labels[i]) for i in range(n_colors) ]
    # put those patched as legend-handles into the legend
    legend=ax.legend(handles=patches, borderaxespad=0,loc="center right",markerscale=1.3,
          edgecolor='none',facecolor='none',fontsize=15,title='')

    ax.text(0.02,1.07, s='全国各省新型冠状病毒疫情状况', transform=ax.transAxes, size=30, weight='bold',color='k')
    ax.text(0.02,1.0, s='全国新型冠状病毒确诊总数为:'+str(df_day['province_confirmedCount'].sum())+';  湖北省新型冠状病毒确诊总数为:'+ str(df_day.loc['湖北省','province_confirmedCount']),
        transform=ax.transAxes, size=20,weight='light', color='k')
    ax.text(0.05,0.22, s=df_day['date'][0], transform=ax.transAxes, size=70, color='gray',weight='bold',family='Arial')
    ax.text(0.02,0.05, s='数据来源:https://github.com/BlankerL/DXY-2019-nCoV-Data/blame/master/DXYArea.csv', transform=ax.transAxes, size=10, color='k')    
    
    basemap2 = Basemap(llcrnrlon= 106.55,llcrnrlat=4.61,urcrnrlon=123.58,urcrnrlat=25.45,projection='poly',lon_0 = 116.65,lat_0 = 40.02,ax = ax2)
    basemap2.readshapefile(shapefile = 'china',name = "province", drawbounds=True)
    basemap2.readshapefile('china_nine_dotted_line',name ='section', drawbounds=True)

    for info, shape in zip(basemap2.province_info, basemap2.province): 
            pname = info['OWNER'].strip('\x00')
            fcname = info['FCNAME'].strip('\x00')
            if pname != fcname: # 不绘制海岛
                continue 

            color='white'
            if sum(df_day['provinceName']==pname)>0:
                color = df_day.loc[pname,'color']
            poly = Polygon(shape, facecolor=color, edgecolor='k')
            ax2.add_patch(poly)

fig = plt.figure(figsize=(12,12))
ax = fig.gca()
ax2= fig.add_axes([0.75, 0.2, 0.15, 0.15])
plt.subplots_adjust(left=0.12, right=0.98, top=0.85, bottom=0.1)   
draw_ChinaMap(2)

matplotlib包和plotnine包都可以实现动态数据的可视化演示。其中,在matplotlib包中,函数 FuncAnimation(fig,func,frames,init_func,interval,blit) 是绘制动图的主要函数,其参数如下:

(1) fig 为绘制动图的画布名称;

(2) func为自定义动画函数update(),比如11-4-1的 draw_barchart(year) 和11-4-2的 draw_areachart(Num_Date);

(3) frames为动画长度,一次循环包含的帧数,在函数运行时,其值会传递给函数update(n)的形参“n”;

(4) init_func为自定义开始帧,即初始化函数,可省略;

(5) interval为更新频率,以ms计算;

(6) blit为选择更新所有点,还是仅更新产生变化的点。应选择True,但mac用户请选择False,否则无法显示。

plotnine包的PlotnineAnimation()函数也可以绘制动态图表,但是对于不断更新的数据绘制动态图表时,动态图表生成速度很慢。

代码语言:javascript
复制
import matplotlib.animation as animation
from IPython.display import HTML
fig = plt.figure(figsize=(12,12))
ax = fig.gca()
ax2= fig.add_axes([0.75, 0.2, 0.15, 0.15])
plt.subplots_adjust(left=0.12, right=0.98, top=0.85, bottom=0.1)    
animator = animation.FuncAnimation(fig, draw_ChinaMap, frames=np.arange(0,len(days),1),interval=1000)
HTML(animator.to_jshtml())

ps:源代码与数据的Github下载地址:

https://github.com/EasyChart/Beautiful-Visualization-with-python/tree/master

Python数据可视化之美

本文源自博文视点即将出版的新书《Python数据可视化之美》中的动态图表的绘制。

本书主要介绍如何使用python中的matplotlib、seaborn、plotnine、geoplot等包绘制专业图表。本书先介绍了python语言编程基础知识,以及使用numpy和pandas两个包的数据操作方法;再对比了matplotlib、seaborn和plotnine三个包的图形语法。本书系统性地介绍了使用matplotlib、seaborn和plotnine绘制类别对比型、数据关系型、时间序列型、整体局部型、地理空间型等常见的二维和三维图表的绘制方法。另外,本书也介绍了商业图表与学术图表的规范与差异,以及如何使用matplotlib包绘制HTML交互页面动画。

除此之外,书中还介绍了动态条形图动态三维柱形地图的绘制。

http://mpvideo.qpic.cn/0af2n3khyqzveaylbyaaicyjaeaflupetgr4mvbmbqhq6aiebmaq.f10002.mp4?dis_k=cab0623627eca11fc4aabef33c911894&dis_t=1591779391

http://mpvideo.qpic.cn/0af2rm7kzyyfeaihb4dambaaaqffnvxjt6umw5wmbegqgdafbaba.f10002.mp4?dis_k=2849f4a54dc32707f94c1712dd5f60ec&dis_t=1591779391

图书推荐

▊ 《R语言数据可视化之美:专业图表绘制指南(增强版)》

张杰 著

本书主要内容

① R语言编程基础知识,以及使用dplyr、tidyr、reshape2等包的数据操作方法; base、lattice 和ggplot2包的图形语法。

② 使用ggplot2包及其拓展包绘制类别对比型、数据关系型、时间序列型、整体局部型、地理空间型等常见的二维图表的方法,ggraph、igraph circlize等包绘制层次、 网络关系型图表,以及使用plot3D包绘制三维图表(包括三维散点图、柱形图和曲面图等)的方法。

③ 论文中学术图表的图表配色、规范格式等相关技能与知识。

关于作者

张杰

  • 数据分析与可视化极客
  • EasyCharts微信公众号联合主创
  • 著有15篇SCI(E)和SSCI学术论文
  • 出版专著《Excel 数据之美:科学图表与商业图表的绘制》和《R语言数据可视化之美:专业图表绘制指南》
  • 第11届和第12届中国R会议数据可视化演讲嘉宾
  • 学术研究方向为颜色科学、机器视觉、数据分析与可视化等
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档