這裏是採用新浪疫情實時數據
最新數據是運行前一天(這裏是2月7號)
所有資料github地址:
以下是所有代碼:
from datetime import datetime
import numpy as np
import json, re
import requests
import matplotlib
import time
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.font_manager import FontProperties
from matplotlib.patches import Polygon
from mpl_toolkits.basemap import Basemap
from matplotlib.backends.backend_agg import FigureCanvasAgg
plt.rcParams['font.sans-serif'] = ['FangSong'] # 設置默認字體
plt.rcParams['axes.unicode_minus'] = False # 解決保存圖像時'-'顯示爲方塊的問題
def get_daily_cn():
"""獲取全國每日數據"""
time_stamp = int(time.time()) * 1000
url = f'https://interface.sina.cn/news/wap/fymap2020_data.d.json?_={time_stamp}&callback='
resp = requests.get(url=url, )
resp_data = resp.content.decode("unicode_escape")
raw_data = json.loads(re.search("\(+([^)]*)\)+", resp_data).group(1)).get('data')['historylist']
# 處理數據
cn_conNum_list = list() # 確診
cn_deathNum_list = list() # 死亡
cn_cureNum_list = list() # 治癒
cn_susNum_list = list() # 疑似
date_list = list()
for item in raw_data:
month, day = item['date'].split('.')
date_list.append(datetime.strptime('2020-%s-%s' % (month, day), '%Y-%m-%d'))
cn_conNum_list.append(int(item.get('cn_conNum', 0)))
cn_deathNum_list.append(int(item.get('cn_deathNum', 0)))
cn_cureNum_list.append(int(item.get('cn_cureNum', 0)))
cn_susNum_list.append(item.get('cn_susNum', 0))
# 因爲新浪網數據有null值,這裏操作有點多
cn_susNum_list = [x for x in cn_susNum_list if x is not None]
for i in range(len(cn_conNum_list) - len(cn_susNum_list)):
cn_susNum_list.append(1)
cn_susNum_list = [int(x) for x in cn_susNum_list]
return cn_conNum_list, cn_deathNum_list, cn_susNum_list, cn_cureNum_list, date_list
def plot_date():
"""繪製全國每日疫情數據折線圖"""
cn_conNum_list, cn_deathNum_list, cn_susNum_list, cn_cureNum_list, date_list = get_daily_cn()
plt.figure('2019-nCoV疫情統計圖表', facecolor='#f4f4f4', figsize=(10, 8))
plt.title('2019-nCoV疫情折線圖', fontsize=20)
plt.plot(date_list, cn_conNum_list, label='確診')
plt.plot(date_list, cn_susNum_list, label='疑似')
plt.plot(date_list, cn_deathNum_list, label='死亡')
plt.plot(date_list, cn_cureNum_list, label='治癒')
ax = plt.gca().xaxis
ax.set_major_formatter(mdates.DateFormatter('%Y/%m/%d')) # 格式化時間軸標註
ax.set_major_locator(matplotlib.dates.DayLocator(bymonthday=None, interval=1, tz=None))
plt.gcf().autofmt_xdate() # 優化標註(自動傾斜)
plt.grid(linestyle=':') # 顯示網格
plt.xlabel('日期', fontsize=16)
plt.ylabel('人數', fontsize=16)
plt.legend(loc='best')
plt.savefig('2019-nCoV.png')
plt.show()
def china_value():
"""繪製全國每日疫情數據全國地圖"""
time_stamp = int(time.time()) * 1000
url = f'https://interface.sina.cn/news/wap/fymap2020_data.d.json?_={time_stamp}&callback='
resp = requests.get(url=url, )
resp_data = resp.content.decode("unicode_escape")
raw_data = json.loads(re.search("\(+([^)]*)\)+", resp_data).group(1)).get('data')['list']
# 處理數據,獲取每個省份確診數據
china_all = list()
city_value = {}
for item in raw_data:
city = item.get('name')
value = item.get('value')
city_value[city] = int(value)
china_all.append(city_value)
return city_value
def plot_distribution():
"""繪製行政區域確診分佈數據"""
china_data = china_value()
print(china_data)
# 經緯度範圍
lat_min = 10 # 緯度
lat_max = 60
lon_min = 70 # 經度
lon_max = 140
font = FontProperties(fname='simsun/simsun.ttf', size=14)
# 標籤顏色和文本
legend_handles = [
matplotlib.patches.Patch(color='#7FFFAA', alpha=1, linewidth=0),
matplotlib.patches.Patch(color='#ffaa85', alpha=1, linewidth=0),
matplotlib.patches.Patch(color='#ff7b69', alpha=1, linewidth=0),
matplotlib.patches.Patch(color='#bf2121', alpha=1, linewidth=0),
matplotlib.patches.Patch(color='#7f1818', alpha=1, linewidth=0),
]
legend_labels = ['0人', '1-10人', '11-100人', '101-1000人', '>1000人']
fig = plt.figure(facecolor='#f4f4f4', figsize=(10, 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,False] 分別代表 [left,right,top,bottom]
china_map.drawparallels(np.arange(lat_min, lat_max, 10), labels=[1, 0, 0, 0]) # 畫經度線
china_map.drawmeridians(np.arange(lon_min, lon_max, 10), labels=[0, 0, 0, 1]) # 畫緯度線
china_map.drawcoastlines(color='black') # 洲際線
china_map.drawcountries(color='red') # 國界線
china_map.drawmapboundary(fill_color='aqua')
# 畫中國國內省界和九段線
china_map.readshapefile('china-shapefiles-master/china', 'province', drawbounds=True)
china_map.readshapefile('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 china_data.keys():
count_iter += 1
if prov_name in pname:
is_reported = True
if china_data[prov_name] == 0:
color = '#f0f0f0'
elif china_data[prov_name] <= 10:
color = '#ffaa85'
elif china_data[prov_name] <= 100:
color = '#ff7b69'
elif china_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)
axes.legend(legend_handles, legend_labels, bbox_to_anchor=(0.5, -0.11), loc='lower center', ncol=4, prop=font)
axes.set_title("2019-nCoV疫情地圖", fontproperties=font)
FigureCanvasAgg(fig)
fig.savefig('2019-nCoV疫情地圖.png')
if __name__ == '__main__':
plot_date()
plot_distribution()
參考文章:
蒜泥的冬天和天元浪子兩位大神,多謝