我如何使用 Python 绘制 COVID-19 的全球传播地图

使用这些开源脚本创建一个病毒潜在传播的彩色编码地理地图。
110 位读者喜欢这篇文章。
Introduction to the Domain Name System (DNS)

Jason Baker。CC BY-SA 4.0。来源:Cloud, Globe。均为 CC0。

在全球旅行普遍的世界中,疾病的传播是一个真正令人担忧的问题。一些组织跟踪重大流行病(和任何大流行病),幸运的是,他们以开放数据的形式发布他们的工作成果。然而,原始数据可能难以让人类处理,这就是数据科学如此重要的原因。例如,使用 Python 和 Pandas 可视化 COVID-19 在全球范围内的传播可能很有用。

当您面对大量原始数据时,可能很难知道从哪里开始。然而,您做得越多,就越多的模式开始出现。这是一个应用于 COVID-19 数据的常见场景

  1. 从 GitHub 下载 COVID-19 国家/地区每日传播数据到 Pandas DataFrame 对象中。为此,您需要 Python Pandas 库。
  2. 处理和清理下载的数据,使其适合可视化。下载的数据(您将亲眼看到)状况良好。此数据的一个问题是它使用国家/地区的名称,但最好使用三位数的 ISO 3 代码。要生成三位数的 ISO 3 代码,请使用一个名为 pycountry 的小型 Python 库。生成这些代码后,您可以向 DataFrame 添加一个额外的列,并用这些代码填充它。
  3. 最后,对于可视化,请使用名为 Plotly 的库的 express 模块。本文使用所谓的等值区域地图(在 Plotly 中可用)来可视化疾病在世界范围内的传播。

步骤 1:新冠数据

我们将从以下位置下载最新的新冠数据

https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv

我们将直接将数据加载到 Pandas DataFrame 中。Pandas 提供了一个函数 read_csv(),它可以接受 URL 并返回 DataFrame 对象,如下所示

import pycountry
import plotly.express as px
import pandas as pd
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))  # Get first 3 entries in the dataframe
print(df1.tail(3))  # Get last 3 entries in the dataframe

输出(在 Jupyter 上)的屏幕截图是

Jupyter screenshot

从输出中,您可以看到 DataFrame (df1) 具有以下列

  1. 日期
  2. 国家/地区
  3. 确诊
  4. 治愈
  5. 死亡

此外,您可以看到 Date 列的条目从 1 月 22 日开始到 3 月 31 日。此数据库每天更新,因此您将获得当前值。

步骤 2:清理和修改数据帧

我们需要向此 DataFrame 添加另一列,其中包含三字母 ISO alpha-3 代码。为此,我遵循了以下步骤

  1. 创建数据库中所有国家/地区的列表。这是必需的,因为在 df 中,在 Country 列中,每个国家/地区都针对每个日期进行计算。因此,实际上,Country 列包含每个国家/地区的多个条目。为此,我使用了 unique().tolist() 函数。
  2. 然后我创建了一个字典 d_country_code(最初为空),并用由国家/地区名称组成的键和由其三字母 ISO 代码组成的值填充它。
  3. 为了生成国家/地区的三字母 ISO 代码,我使用了函数 pycountry.countries.search_fuzzy(country)。您需要理解,此函数的返回值是“Country 对象列表”。我将此函数的返回值传递给名称 country_data。此外,在此对象列表中,第一个对象(即索引 0 处的对象)是最匹配的。此外,此对象具有属性 alpha_3。因此,我可以使用 country_data[0].alpha_3 “访问”三字母 ISO 代码。但是,DataFrame 中的某些国家/地区名称可能没有对应的 ISO 代码(例如,争议领土)。因此,对于此类国家/地区,我给出了一个 ISO 代码“即一个空字符串。此外,您需要将此代码包装在 try-except 块中。语句:print(‘could not add ISO 3 code for ->', country) 将打印出那些找不到 ISO 3 代码的国家/地区。实际上,您将在最终输出中找到以白色显示的此类国家/地区。
  4. 获取每个国家/地区的三字母 ISO 代码(或某些国家/地区的空字符串)后,我将国家/地区名称(作为键)及其对应的 ISO 代码(作为值)添加到字典 d_country_code 中。为了添加这些,我使用了 Python 字典对象的 update() 方法。
  5. 创建了国家/地区名称及其代码的字典后,我使用一个简单的 for 循环将它们添加到 DataFrame 中。

步骤 3:使用 Plotly 可视化传播

等值区域地图是由彩色多边形组成的地图。它用于表示数量的空间变化。我们将使用 Plotly 的 express 模块,通常称为 px。在这里,我们将向您展示如何使用函数 px.choropleth 创建等值区域地图。

此函数的签名是

plotly.express.choropleth(data_frame=None, lat=None, lon=None, locations=None, locationmode=None, geojson=None, featureidkey=None, color=None, hover_name=None, hover_data=None, custom_data=None, animation_frame=None, animation_group=None, category_orders={}, labels={}, color_discrete_sequence=None, color_discrete_map={}, color_continuous_scale=None, range_color=None, color_continuous_midpoint=None, projection=None, scope=None, center=None, title=None, template=None, width=None, height=None)

值得注意的点是 choropleth() 函数需要以下内容

  1. **geojson** 对象形式的几何图形。这就是事情有点令人困惑的地方,并且在其文档中没有明确提及。您可以提供或不提供 **geojson** 对象。如果您提供 **geojson** 对象,则该对象将用于绘制地球特征,但是如果您不提供 **geojson** 对象,则该函数默认情况下将使用内置几何图形之一。(在我们的示例中,我们将使用内置几何图形,因此我们不会为 **geojson** 参数提供任何值)
  2. 属性 data_frame 的 pandas DataFrame 对象。在这里,我们提供我们之前创建的 DataFrame,即 **df1**。
  3. 我们将使用 Confirmed 列的数据来决定每个国家/地区多边形的颜色。
  4. 此外,我们将使用 Date 列来创建 animation_frame。因此,当我们滑动日期时,国家/地区的颜色将根据 **Confirmed** 列中的值而变化。

完整的代码如下

import pycountry
import plotly.express as px
import pandas as pd
# ----------- Step 1 ------------
URL_DATASET = r'https://raw.githubusercontent.com/datasets/covid-19/master/data/countries-aggregated.csv'
df1 = pd.read_csv(URL_DATASET)
# print(df1.head) # Uncomment to see what the dataframe is like
# ----------- Step 2 ------------
list_countries = df1['Country'].unique().tolist()
# print(list_countries) # Uncomment to see list of countries
d_country_code = {}  # To hold the country names and their ISO
for country in list_countries:
    try:
        country_data = pycountry.countries.search_fuzzy(country)
        # country_data is a list of objects of class pycountry.db.Country
        # The first item  ie at index 0 of list is best fit
        # object of class Country have an alpha_3 attribute
        country_code = country_data[0].alpha_3
        d_country_code.update({country: country_code})
    except:
        print('could not add ISO 3 code for ->', country)
        # If could not find country, make ISO code ' '
        d_country_code.update({country: ' '})

# print(d_country_code) # Uncomment to check dictionary  

# create a new column iso_alpha in the df
# and fill it with appropriate iso 3 code
for k, v in d_country_code.items():
    df1.loc[(df1.Country == k), 'iso_alpha'] = v

# print(df1.head)  # Uncomment to confirm that ISO codes added
# ----------- Step 3 ------------
fig = px.choropleth(data_frame = df1, 
                    locations= "iso_alpha",
                    color= "Confirmed",  # value in column 'Confirmed' determines color
                    hover_name= "Country",
                    color_continuous_scale= 'RdYlGn',  #  color scale red, yellow green
                    animation_frame= "Date")

fig.show()

输出类似于以下内容

Map

您可以下载并运行 完整代码

总结一下,这里有一些关于 Plotly 中等值区域地图的优秀资源

接下来阅读什么
User profile image.
Anurag Gupta 是一名受过工程师教育,但职业是警察的专业人士。他是一位 Python 爱好者,最近与人合著了一本关于 Python 的书,名为《Python 编程:问题解决、包和库》,由 McGraw Hill 出版。您可以通过 999.anuraggupta@Gmail 联系到他,并且他很乐意听取读者关于 Python 相关主题的意见。

5 条评论

谢谢你。用这种方式学习 python 真酷

非常感谢您的解释!
这为我在一个整洁的项目中结合数据和 Phython 提供了正确的思路。

如果我想为印度各邦制作这个地图,我可以在 iso_alpha 列中使用什么来表示印度各邦?

我也在尝试印度各邦的数据,您能在此代码中读取您的数据集吗
https://raw.githubusercontent.com/ag999git/jupyter_notebooks/master/cor…
如果我只有一天具有不同日期的不同邦的数据,它可以读取,但不能读取所有不同日期和不同邦的数据。

回复 Goldy Mazumdar (未验证) 关于 What can I use for Indian 的评论

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.