使用 Python 來視覺化 COVID-19 預測

2020-05-01 19:37:00

我將演示如何利用提供的全球病毒傳播的開放資料,使用開源庫來建立兩個可視效果。

使用 Python 和一些圖形庫,你可以預測 COVID-19 確診病例總數,也可以顯示一個國家(本文以印度為例)在給定日期的死亡總數。人們有時需要幫助解釋和處理資料的意義,所以本文還演示了如何為五個國家建立一個動畫橫條形圖,以顯示按日期顯示病例的變化。

印度的確診病例和死亡人數預測

這要分三步來完成。

1、下載資料

科學資料並不總是開放的,但幸運的是,許多現代科學和醫療機構都樂於相互之間及與公眾共用資訊。關於 COVID-19 病例的資料可以在網上查到,並且經常更新。

要解析這些資料,首先必須先下載。 https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv

直接將資料載入到 Pandas DataFrame 中。Pandas 提供了一個函數 read_csv(),它可以獲取一個 URL 並返回一個 DataFrame 物件,如下所示。

import pycountryimport plotly.express as pximport pandas as pdURL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'df1 = pd.read_csv(URL_DATASET)print(df1.head(3))  # 獲取資料框中的前 3 項print(df1.tail(3))  # 獲取資料框中的後 3 項

資料集的頂行包含列名。

  1. Date
  2. Country
  3. Confirmed
  4. Recovered
  5. Deaths

head 查詢的輸出包括一個唯一的識別符號(不作為列列出)和每個列的條目。

0 2020-01-22 Afghanistan 0 0 01 2020-01-22 Albania 0 0 01 2020-01-22 Algeria 0 0 0

tail 查詢的輸出類似,但包含資料集的尾端。

12597 2020-03-31 West Bank and Gaza 119 18 112598 2020-03-31 Zambia 35 0 012599 2020-03-31 Zimbabwe 8 0 1

從輸出中,可以看到 DataFrame(df1)有以下幾個列:

  1. 日期
  2. 國家
  3. 確診
  4. 康復
  5. 死亡

此外,你可以看到 Date 欄中的條目從 1 月 22 日開始到 3 月 31 日。這個資料庫每天都會更新,所以你會有當前的值。

2、選擇印度的資料

在這一步中,我們將只選擇 DataFrame 中包含印度的那些行。這在下面的指令碼中可以看到。

#### ----- Step 2 (Select data for India)----df_india = df1[df1['Country'] == 'India']print(df_india.head(3))

3、資料繪圖

在這裡,我們建立一個條形圖。我們將把日期放在 X 軸上,把確診的病例數和死亡人數放在 Y 軸上。這一部分的指令碼有以下幾個值得注意的地方。

  • plt.rcParams["figure.figsize"]=20,20 這一行程式碼只適用於 Jupyter。所以如果你使用其他 IDE,請刪除它。
  • 注意這行程式碼:ax1 = plt.gca()。為了確保兩個圖,即確診病例和死亡病例的圖都被繪製在同一個圖上,我們需要給第二個圖的 ax 物件。所以我們使用 gca() 來完成這個任務。(順便說一下,gca 代表 “獲取當前坐標軸get current axis”)

完整的指令碼如下所示。

#  Author:- Anurag Gupta # email:- [email protected]%matplotlib inlineimport matplotlib.pyplot as pltimport pandas as pd#### ----- Step 1 (Download data)----URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'df1 = pd.read_csv(URL_DATASET)# print(df1.head(3))  # Uncomment to see the dataframe#### ----- Step 2 (Select data for India)----df_india = df1[df1['Country'] == 'India']print(df_india.head(3))#### ----- Step 3 (Plot data)----# Increase size of plotplt.rcParams["figure.figsize"]=20,20  # Remove if not on Jupyter# Plot column 'Confirmed'df_india.plot(kind = 'bar', x = 'Date', y = 'Confirmed', color = 'blue')ax1 = plt.gca()df_india.plot(kind = 'bar', x = 'Date', y = 'Deaths', color = 'red', ax = ax1)plt.show()

整個指令碼可在 GitHub 上找到

為五個國家建立一個動畫水平條形圖

關於 Jupyter 的注意事項:要在 Jupyter 中以動態動畫的形式執行,而不是靜態 png 的形式,你需要在單元格的開頭新增一個神奇的命令,即: %matplotlib notebook。這將使圖形保持動態,而不是顯示為靜態的 png 檔案,因此也可以顯示動畫。如果你在其他 IDE 上,請刪除這一行。

1、下載資料

這一步和前面的指令碼完全一樣,所以不需要重複。

2、建立一個所有日期的列表

如果你檢查你下載的資料,你會發現它有一列 Date。現在,這一列對每個國家都有一個日期值。因此,同一個日期會出現多次。我們需要建立一個只具有唯一值的日期列表。這會用在我們條形圖的 X 軸上。我們有一行程式碼,如 list_dates = df[‘Date’].unique()unique() 方法將只提取每個日期的唯一值。

3、挑選五個國家並建立一個 ax 物件。

做一個五個國家的名單。(你可以選擇你喜歡的國家,也可以增加或減少國家的數量。)我也做了一個五個顏色的列表,每個國家的條形圖的顏色對應一種。(如果你喜歡的話,也可以改一下。)這裡有一行重要的程式碼是:fig, ax = plt.subplots(figsize=(15, 8))。這是建立一個 ax 物件所需要的。

4、編寫回撥函數

如果你想在 Matplotlib 中做動畫,你需要建立一個名為 matplotlib.animation.FuncAnimation 的類的物件。這個類的簽名可以在網上查到。這個類別建構函式,除了其他引數外,還需要一個叫 func 的引數,你必須給這個引數一個回撥函數。所以在這一步中,我們會寫個回撥函數,這個回撥函數會被反復呼叫,以渲染動畫。

5、建立 FuncAnimation 物件

這一步在上一步中已經部分說明了。

我們建立這個類的物件的程式碼是:

my_anim = animation.FuncAnimation(fig = fig, func = plot_bar,                    frames = list_dates, blit = True,                    interval=20)

要給出的三個重要引數是:

  • fig,必須給出一個 fig 物件,也就是我們之前建立的 fig 物件。
  • func,必須是回撥函數。
  • frames,必須包含要做動畫的變數。在我們這裡,它是我們之前建立的日期列表。

6、將動畫儲存為 mp4 檔案

你可以將建立的動畫儲存為 mp4 檔案。但是,你需要 ffmpeg。你可以用 pip 下載:pip install ffmpeg-python,或者用 conda(在 Jupyter 上):install -c conda-forge ffmpeg

最後,你可以使用 plt.show() 執行動畫。請注意,在許多平台上,ffmpeg 可能無法正常工作,可能需要進一步“調整”。

%matplotlib notebook#  Author:- Anurag Gupta # email:- [email protected] pandas as pdimport matplotlib.pyplot as pltimport matplotlib.animation as animationfrom time import sleep#### ---- Step 1:- Download dataURL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'df = pd.read_csv(URL_DATASET, usecols = ['Date', 'Country', 'Confirmed'])# print(df.head(3)) # uncomment this to see output#### ---- Step 2:- Create list of all dateslist_dates = df['Date'].unique()# print(list_dates) # Uncomment to see the dates#### --- Step 3:- Pick 5 countries. Also create ax objectfig, ax = plt.subplots(figsize=(15, 8))# We will animate for these 5 countries onlylist_countries = ['India', 'China', 'US', 'Italy', 'Spain']# colors for the 5 horizontal barslist_colors = ['black', 'red', 'green', 'blue', 'yellow']### --- Step 4:- Write the call back function# plot_bar() is the call back function used in FuncAnimation class objectdef plot_bar(some_date):    df2 = df[df['Date'].eq(some_date)]    ax.clear()    # Only take Confirmed column in descending order    df3 = df2.sort_values(by = 'Confirmed', ascending = False)    # Select the top 5 Confirmed countries    df4 = df3[df3['Country'].isin(list_countries)]    # print(df4)  # Uncomment to see that dat is only for 5 countries    sleep(0.2)  # To slow down the animation    # ax.barh() makes a horizontal bar plot.    return ax.barh(df4['Country'], df4['Confirmed'], color= list_colors)###----Step 5:- Create FuncAnimation object---------my_anim = animation.FuncAnimation(fig = fig, func = plot_bar,                    frames= list_dates, blit=True,                    interval=20)### --- Step 6:- Save the animation to an mp4# Place where to save the mp4. Give your file path insteadpath_mp4 = r'C:\Python-articles\population_covid2.mp4'  # my_anim.save(path_mp4, fps=30, extra_args=['-vcodec', 'libx264'])my_anim.save(filename = path_mp4, writer = 'ffmpeg',             fps=30,             extra_args= ['-vcodec', 'libx264', '-pix_fmt', 'yuv420p'])plt.show()

完整的指令碼可以在 GitHub 上找到