利用Python實現2019-nCoV疫情曲線圖

這裏是採用新浪疫情實時數據

最新數據是運行前一天(這裏是2月7號)

2019-nCoV疫情地圖
2019-nCoV全國數據折線圖

所有資料github地址:

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()

參考文章:
蒜泥的冬天和天元浪子兩位大神,多謝

讀到這兒了,有興趣的可以添加下我的微信公衆號

一丁點技術

發佈了48 篇原創文章 · 獲贊 72 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章