Python抓新型冠狀病毒肺炎疫情資料並繪製全國疫情分佈的程式碼例項
阿新 • • 發佈:2020-02-06
執行結果(2020-2-4日資料)
資料來源
news.qq.com/zt2020/page/feiyan.htm
抓包分析
日報資料格式
"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)
以上就是我們小編整理的全部知識點內容,感謝大家的學習和對我們的支援。