1. 程式人生 > 程式設計 >Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

執行結果(2020-2-4日資料)

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

資料來源

news.qq.com/zt2020/page/feiyan.htm

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

抓包分析

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項

日報資料格式

"chinaDayList": [{
		"date": "01.13","confirm": "41","suspect": "0","dead": "1","heal": "0"
	},{
		"date": "01.14",{
		"date": "01.15","dead": "2","heal": "5"
	},{
	。。。。。。

全國各地疫情資料格式

	"lastUpdateTime": "2020-02-04 12:43:19","areaTree": [{
		"name": "中國","children": [{
			"name": "湖北","children": [{
				"name": "武漢","total": {
					"confirm": 6384,"suspect": 0,"dead": 313,"heal": 303
				},"today": {
					"confirm": 1242,"dead": 48,"heal": 79
				}
			},{
				"name": "黃岡","total": {
					"confirm": 1422,"dead": 19,"heal": 36
				},"today": {
					"confirm": 176,"dead": 2,"heal": 9
				}
			},{
			。。。。。。

地圖資料

github.com/dongli/china-shapefiles

程式碼實現

#%%

import time,json,requests
from datetime import datetime
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.font_manager import FontProperties
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
import numpy as np
import jsonpath

plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號

#%%

# 全國疫情地區分佈(省級確診病例)
def catch_cn_disease_dis():
 timestamp = '%d'%int(time.time()*1000)
 url_area = ('https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
    '&callback=&_=') + timestamp
 world_data = json.loads(requests.get(url=url_area).json()['data'])
 china_data = jsonpath.jsonpath(world_data,expr='$.areaTree[0].children[*]')
 list_province = jsonpath.jsonpath(china_data,expr='$[*].name')
 list_province_confirm = jsonpath.jsonpath(china_data,expr='$[*].total.confirm')
 dic_province_confirm = dict(zip(list_province,list_province_confirm)) 
 return dic_province_confirm

area_data = catch_cn_disease_dis()
print(area_data)

#%%

# 抓取全國疫情按日期分佈
'''
資料來源:
"chinaDayList": [{
		"date": "01.13","heal": "0"
	}
'''
def catch_cn_daily_dis():
 timestamp = '%d'%int(time.time()*1000)
 url_area = ('https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5'
    '&callback=&_=') + timestamp
 world_data = json.loads(requests.get(url=url_area).json()['data'])
 china_daily_data = jsonpath.jsonpath(world_data,expr='$.chinaDayList[*]')

 # 其實沒必要單獨用list儲存,json可讀性已經很好了;這裡這樣寫僅是為了少該點老版本的程式碼  
 list_dates = list() # 日期
 list_confirms = list() # 確診
 list_suspects = list() # 疑似
 list_deads = list() # 死亡
 list_heals = list() # 治癒  
 for item in china_daily_data:
  month,day = item['date'].split('.')
  list_dates.append(datetime.strptime('2020-%s-%s'%(month,day),'%Y-%m-%d'))
  list_confirms.append(int(item['confirm']))
  list_suspects.append(int(item['suspect']))
  list_deads.append(int(item['dead']))
  list_heals.append(int(item['heal']))  
 return list_dates,list_confirms,list_suspects,list_deads,list_heals  

list_date,list_confirm,list_suspect,list_dead,list_heal = catch_cn_daily_dis() 
print(list_date)
 

#%%

# 繪製每日確診和死亡資料
def plot_cn_daily():
 # list_date,list_heal = catch_cn_daily_dis() 
 
 plt.figure('novel coronavirus',facecolor='#f4f4f4',figsize=(10,8))
 plt.title('全國新型冠狀病毒疫情曲線',fontsize=20)
 print('日期元素數:',len(list_date),"\n確診元素數:",len(list_confirm))
 plt.plot(list_date,label='確診')
 plt.plot(list_date,label='疑似')
 plt.plot(list_date,label='死亡')
 plt.plot(list_date,list_heal,label='治癒')
 xaxis = plt.gca().xaxis 
 # x軸刻度為1天
 xaxis.set_major_locator(matplotlib.dates.DayLocator(bymonthday=None,interval=1,tz=None))
 xaxis.set_major_formatter(mdates.DateFormatter('%m月%d日'))
 plt.gcf().autofmt_xdate() # 優化標註(自動傾斜)
 plt.grid(linestyle=':') # 顯示網格
 plt.xlabel('日期',fontsize=16)
 plt.ylabel('人數',fontsize=16)
 plt.legend(loc='best')
 
plot_cn_daily()

#%%

# 繪製全國省級行政區域確診分佈圖
count_iter = 0
def plot_cn_disease_dis():
 # area_data = catch_area_distribution()
 font = FontProperties(fname='res/coure.fon',size=14)
 
 # 經緯度範圍
 lat_min = 10 # 緯度
 lat_max = 60
 lon_min = 70 # 經度
 lon_max = 140
  
 # 標籤顏色和文字 
 legend_handles = [
    matplotlib.patches.Patch(color='#7FFFAA',alpha=1,linewidth=0),matplotlib.patches.Patch(color='#ffaa85',matplotlib.patches.Patch(color='#ff7b69',matplotlib.patches.Patch(color='#bf2121',matplotlib.patches.Patch(color='#7f1818',]
 legend_labels = ['0人','1-10人','11-100人','101-1000人','>1000人']

 fig = plt.figure(facecolor='#f4f4f4',8)) 
 # 新建區域
 axes = fig.add_axes((0.1,0.1,0.8,0.8)) # left,bottom,width,height,figure的百分比,從figure 10%的位置開始繪製,寬高是figure的80%
 axes.set_title('全國新型冠狀病毒疫情地圖(確診)',fontsize=20) # fontproperties=font 設定失敗 
 # bbox_to_anchor(num1,num2),num1用於控制legend的左右移動,值越大越向右邊移動,num2用於控制legend的上下移動,值越大,越向上移動。
 axes.legend(legend_handles,legend_labels,bbox_to_anchor=(0.5,-0.11),loc='lower center',ncol=5) # prop=font
 
 china_map = Basemap(llcrnrlon=lon_min,urcrnrlon=lon_max,llcrnrlat=lat_min,urcrnrlat=lat_max,resolution='l',ax=axes)
 # labels=[True,False,False] 分別代表 [left,right,top,bottom]
 china_map.drawparallels(np.arange(lat_min,lat_max,10),labels=[1,0]) # 畫經度線
 china_map.drawmeridians(np.arange(lon_min,lon_max,labels=[0,1]) # 畫緯度線
 china_map.drawcoastlines(color='black') # 洲際線
 china_map.drawcountries(color='red') # 國界線
 china_map.drawmapboundary(fill_color = 'aqua')
 # 畫中國國內省界和九段線
 china_map.readshapefile('res/china-shapefiles-master/china','province',drawbounds=True)
 china_map.readshapefile('res/china-shapefiles-master/china_nine_dotted_line','section',drawbounds=True)
 
 global count_iter
 count_iter = 0
 
 # 內外迴圈不能對調,地圖中每個省的資料有多條(繪製每一個shape,可以去查一下第一條“臺灣省”的資料)
 for info,shape in zip(china_map.province_info,china_map.province):
  pname = info['OWNER'].strip('\x00')
  fcname = info['FCNAME'].strip('\x00')
  if pname != fcname: # 不繪製海島
   continue
  is_reported = False # 西藏沒有疫情,資料來源就不取不到其資料 
  for prov_name in area_data.keys():    
   count_iter += 1
   if prov_name in pname:
    is_reported = True
    if area_data[prov_name] == 0:
     color = '#f0f0f0'
    elif area_data[prov_name] <= 10:
     color = '#ffaa85'
    elif area_data[prov_name] <= 100:
     color = '#ff7b69'
    elif area_data[prov_name] <= 1000:
     color = '#bf2121'
    else:
     color = '#7f1818'
    break
   
  if not is_reported:
   color = '#7FFFAA'
   
  poly = Polygon(shape,facecolor=color,edgecolor=color)
  axes.add_patch(poly)
  

plot_cn_disease_dis()
print('迭代次數',count_iter)

以上就是我們小編整理的全部知識點內容,感謝大家的學習和對我們的支援。