Python: COVID-19のインターアクティブな世界地図の作成, plotly, dash ver. 4

Last Updated on

赤字部分を追加しました。

I.何をする?

 

次にしたがい、Python+Plotly+DashでCOVID-19の感染状況を示すインターアクティブなグラフを作成します。

 

How to create outstanding animated scatter maps with Plotly and Dash

 

II.地図+散布図の作成

 

7月28日の感染数で地図を描きます。

 

1.Mapboxでトークンを取得し、ファイルに保存

 

地図情報を得るため、Mapboxに登録しトークンを取得します。メールアドレスだけで登録でき、制限はありますが無料です。

トークンをPythonのスクリプトに直接書いてもよいのですが、別のファイルで保存して隠すために、.iniファイルを作成、保存しします。ライブラリconfigparserで呼び出して使用します。

エディタであれば何で書いてもよいのですが、Neovimを使って.iniファイルを作成しました。手順は次です。

ターミナルを開き次を実行すると、config.iniの名のファイルが開きます。

 

neovim config.ini

 

次を実行し、Insert Mode(書き込むモード)に変更します。

 

i

 

次を書きます。

 

[mapbox]
secret_token=あなたのtoken

 

Escを押しNormal Modeにもどり、次を実行しファイルを保存します。これにより、ホームディレクトリにトークンを書いたconfig.iniファイルが保存されました。

 

w

 

2.スクリプト

 

スクリプトは次です。Iの参考文書のスクリプトはそのままでは実行できなかったので、一部追加、変更していますが、データを地図に配置できるよう整える関数はそのままです。

ホバーで表示するデータには国名が必要ですが、国名の列(zone)は、データtmpではindex(行名)です。しかも、indexは2列(dateとzone)あります。

このため、先にreset_index()で通常の列にもどしてからseriesとして取得します。

 

# imoprt libraries
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from configparser import ConfigParser
import plotly.io as pio # for spyder
# Load the data
df = pd.read_csv('https://public.opendatasoft.com/explore/dataset/covid-19-pandemic-worldwide-data/download/?format=csv&timezone=Europe/Berlin&lang=fr&use_labels_for_header=true&csv_separator=%3B', sep=';')
# display first 5 lines
df.head()

# create a function for processing data
def process_pandemic_data(df):

    # Columns renaming
    df.columns = [col.lower() for col in df.columns]

    # Create a zone per zone/subzone
    df['zone'] = df['zone'].apply(str) + ' ' + df['sub zone'].apply(lambda x: str(x).replace('nan', ''))
    
    # Extracting latitute and longitude
    df['lat'] = df['location'].apply(lambda x: x.split(',')[0])
    df['lon'] = df['location'].apply(lambda x: x.split(',')[1])

    # Saving countries positions (latitude and longitude per subzones)
    country_position = df[['zone', 'lat', 'lon']].drop_duplicates(['zone']).set_index(['zone'])

    # Pivoting per category
    df = pd.pivot_table(df, values='count', index=['date', 'zone'], columns=['category'])
    df.columns = ['confirmed', 'deaths', 'recovered']

    # Merging locations after pivoting
    df = df.join(country_position)

    # Filling nan values with 0
    df = df.fillna(0)

    # Compute bubble sizes
    df['size'] = df['confirmed'].apply(lambda x: (np.sqrt(x/100) + 1) if x > 500 else (np.log(x) / 2 + 1)).replace(np.NINF, 0)
    
    # Compute bubble color
    df['color'] = (df['recovered']/df['confirmed']).fillna(0).replace(np.inf , 0)
    
    return df

# select a subset
day = '2020-07-30'
df_day = df[df.Date=='2020-07-28']
tmp = process_pandemic_data(df_day)


# get token
config = ConfigParser()
config.read('config.ini')
mapbox_token = config['mapbox']['secret_token']

# Create the figure and feed it all the prepared columns
fig = go.Figure(
    go.Scattermapbox(
        lat=tmp['lat'],
        lon=tmp['lon'],
        mode='markers',
        marker=go.scattermapbox.Marker(
            size=tmp['size'],
            color=tmp['color'],
            showscale=True,
            colorbar={'title':'Recovered', 'titleside':'top', 'thickness':4, 'ticksuffix':' %'}),
        customdata=np.stack((pd.Series(tmp.reset_index()['zone']),tmp['confirmed'],tmp['recovered'],tmp['deaths']),axis=-1),
        hovertemplate="""
        <extra></extra>
        <em>%{customdata[0]}  </em><br>
        🚨  %{customdata[1]}<br>
        🏡  %{customdata[2]}<br>
        ⚰️  %{customdata[3]}
        """
        )
    )

# Specify layout information
fig.update_layout(
    mapbox=dict(
        accesstoken=mapbox_token, #
        center=go.layout.mapbox.Center(lat=45, lon=-73),
        zoom=1
    )
)

pio.renderers.default='browser'
# pio.renderers.default='svg'
fig.show()

 

 

マウスを日本の上にホバーすると次のように、感染者数、回復者数、死亡者数が表示されます。

 

 

 

About shibatau

I was born and grown up in Kyoto. I studied western philosophy at the University and specialized in analytic philosophy, especially Ludwig Wittgenstein at the postgraduate school. I'm interested in new technology, especially machine learning and have been learning R language for two years and began to learn Python last summer. Listening toParamore, Sia, Amazarashi and MIyuki Nakajima. Favorite movies I've recently seen: "FREEHELD". Favorite actors and actresses: Anthony Hopkins, Denzel Washington, Ellen Page, Meryl Streep, Mia Wasikowska and Robert DeNiro. Favorite books: Fyodor Mikhailovich Dostoyevsky, "The Karamazov Brothers", Shinran, "Lamentations of Divergences". Favorite phrase: Salvation by Faith. Twitter: @shibatau

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.