[PYTHON] Lassen Sie uns den Infektionsstatus des Corona-Virus mit Plotly [für Anfänger] visualisieren.

Nächstes Mal https://qiita.com/Naoya_Study/items/851f4032fb6e2a5cd5ed

Mit der Verbreitung der Coronavirus-Infektion haben verschiedene Organisationen coole Dashboards veröffentlicht, die den Infektionsstatus visualisieren.

Beispiel 1 WHO Novel Coronavirus (COVID-19) Situation WHO.PNG

Beispiel 2 Ministerium für Gesundheit, Arbeit und Soziales, neuer Fall einer Infektion mit dem Corona-Virus im Inland korousho.PNG

Beispiel 3 Toyo Keizai ONLINE-Status der häuslichen Infektion mit dem neuen Corona-Virus toyokeizai.PNG

Es ist cool! Ich möchte in der Lage sein, so etwas selbst zu machen. Das ultimative Ziel ist es, ein Dashboard wie im obigen Beispiel mit Pythons visualisierungsspezifischem Datenrahmen-Dash zu erstellen. Dieses Mal möchte ich mit der Visualisierungsbibliothek Plotly als vorläufige Vorbereitung zeichnen. Bitte verzeihen Sie mir das Code-Durcheinander.

1. Nutzungsdaten

Wir werden die von Toyo Keizai Online in Japan veröffentlichten Infektionsstatusdaten verwenden. https://github.com/kaz-ogiwara/covid19/

import requests
import io
import pandas as pd
import re
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime as dt
url = 'https://raw.githubusercontent.com/kaz-ogiwara/covid19/master/data/individuals.csv'
res = requests.get(url).content
df = pd.read_csv(io.StringIO(res.decode('utf-8')), header=0, index_col=0)

Die Daten haben dieses Format.

Neue Nr. Alte Nr. Bestätigtes Jahr Bestätigter Monat Festes Datum Alter Sex Wohnort 1 Wohnort 2
1 1 2020 1 15 30er Jahre Mann Präfektur Kanagawa
2 2 2020 1 24 Vierziger Jahre Mann China (Stadt Wuhan)
3 3 2020 1 25 30er Jahre Frau China (Stadt Wuhan)
4 4 2020 1 26 Vierziger Jahre Mann China (Stadt Wuhan)
5 5 2020 1 28 Vierziger Jahre Mann China (Stadt Wuhan)
6 6 2020 1 28 60er Jahre Mann Präfektur Nara

Wie Sie sehen können, sind auch die Daten für in China lebende Personen enthalten, diesmal jedoch auf Japan beschränkt, sodass sie ausgeschlossen werden.

def Get_Df():

    url = 'https://raw.githubusercontent.com/kaz-ogiwara/covid19/master/data/individuals.csv'
    res = requests.get(url).content
    df = pd.read_csv(io.StringIO(res.decode('utf-8')), header=0, index_col=0)

    pattern = r'China(...)'
    df['China'] = np.nan
    for i in range (1, len(df)+1):
        if re.match(pattern, df['Wohnort 1'][i]):
            df['China'][i] = "T"
        else:
            df['China'][i] = "F"
    df = df[df["China"] != "T"].reset_index()
    
    return df
Index. Neue Nr. Alte Nr. Bestätigtes Jahr Bestätigter Monat Festes Datum Alter Sex Wohnort 1 Wohnort 2 China
0 1 1 2020 1 15 30er Jahre Mann Präfektur Kanagawa NaN F
1 6 6 2020 1 28 60er Jahre Mann Präfektur Nara NaN F
2 8 8 2020 1 29 Vierziger Jahre Frau Präfektur Osaka NaN F
3 9 10 2020 1 30 50er Jahre Mann Präfektur Mie NaN F
4 11 12 2020 1 30 20er Jahre Frau Kyoto NaN F

2. Kumulierte Anzahl infizierter Personen nach Präfektur (horizontales Balkendiagramm)

def Graph_Pref():

    df = Get_Df()
    df_count_by_place = df.groupby('Wohnort 1').count().sort_values('China')
    fig = px.bar(
        df_count_by_place,
        x="China",
        y=df_count_by_place.index,
        #Wenn Sie die Ausrichtung auf horizontal einstellen, wird ein horizontales Balkendiagramm erstellt.
        orientation='h',
        width=800,
        height=1000,
        )
    fig.update_layout(
        title="Die Präfektur, in der die Infektion gemeldet wird",
        xaxis_title="Anzahl der infizierten Personen",
        yaxis_title="",
     #Geben Sie einfach die Vorlage an und es handelt sich um ein Diagramm, das ohne Erlaubnis auf Schwarz basiert
        template="plotly_dark",
        )
    fig.show()

aaa.png

Plotly erstellt eigenständig interaktive und modische Diagramme.

3. Zeichnen Sie eine Streukarte auf die Karte

Als nächstes möchte ich die Anzahl der Infizierten nach Präfektur auf einer Karte von Japan als Streukarte darstellen. Erhalten Sie dazu zunächst die Breiten- und Längengrade der Präfekturhauptstadt jeder Präfektur und kombinieren Sie diese mit den CSV-Daten von Toyo Keizai Online. Der Standort des Präfekturbüros Die verwendeten Breiten- und Längengrade stammen aus Jedermanns Wissen, ein kleines praktisches Buch. Extrahieren Sie nur die erforderlichen Daten für Breiten- und Längengrade und kombinieren Sie sie mithilfe von Pandas Merge.

def Df_Merge():

    df = Get_Df()
    df_count_by_place = df.groupby('Wohnort 1').count().sort_values('China')
    df_latlon = pd.read_excel("https://www.benricho.org/chimei/latlng_data.xls", header=4)
    df_latlon = df_latlon.drop(df_latlon.columns[[0,2,3,4,7]], axis=1).rename(columns={'Unnamed: 1': 'Wohnort 1'})
    df_latlon = df_latlon.head(47)
    df_merge = pd.merge(df_count_by_place, df_latlon, on='Wohnort 1')
    return df_merge
index Wohnort 1 Neue Nr. Alte Nr. Bestätigtes Jahr Bestätigter Monat Festes Datum Alter Sex Wohnort 2 China Breite Längengrad
0 Präfektur Gifu 1 1 1 1 1 1 1 0 1 35.39111 136.72222
1 Präfektur Ehime 1 1 1 1 1 1 1 0 1 33.84167 132.76611
2 Präfektur Hiroshima 1 1 1 1 1 1 1 0 1 34.39639 132.45944
3 Präfektur Saga 1 1 1 1 1 1 1 0 1 33.24944 130.29889
4 Akita 1 1 1 1 1 1 1 0 1 39.71861 140.10250
5 Präfektur Yamaguchi 1 1 1 1 1 1 1 0 1 34.18583 131.47139

Zeichnen Sie mit dem obigen Datenrahmen auf der Karte.

def Graph_JapMap():
    df_merge = Df_Merge()
    df_merge['text'] = np.nan
    for i in range (len(df_merge)):
        df_merge['text'][i] = df_merge['Wohnort 1'][i] + ' : ' + str(df_merge['China'][i]) + 'Mann'

    fig = go.Figure(data=go.Scattergeo(
        lat = df_merge["Breite"],
        lon = df_merge["Längengrad"],
        mode = 'markers',
        marker = dict(
                color = 'red',
                size = df_merge['China']/5+6,
                opacity = 0.8,
                reversescale = True,
                autocolorscale = False
                ),
        hovertext = df_merge['text'],
        hoverinfo="text",
    ))
    fig.update_layout(
        width=700,
        height=500,
        template="plotly_dark",
        title={
            'text': "Verteilung infizierter Personen",
            'font':{
                'size':25
            },
            'y':0.9,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'},
        margin = {
            'b':3,
            'l':3,
            'r':3,
            't':3
            },
        geo = dict(
            resolution = 50,
            landcolor = 'rgb(204, 204, 204)',
            coastlinewidth = 1,
            lataxis = dict(
                range = [28, 47],
            ),
            lonaxis = dict(
                range = [125, 150],
            ),
        )
    )
    fig.show()

map.png

Dies ist ein Bild, aber wenn Sie es online machen, können Sie die spezifische Anzahl infizierter Personen sehen, indem Sie den Cursor auf das Diagramm bewegen, was cool ist. Versuch es bitte.

4. Änderungen in der Anzahl der infizierten Personen (gestapeltes Balkendiagramm)

Als nächstes sehen Sie ein Balkendiagramm mit Änderungen der Anzahl infizierter Personen. Transformieren Sie nach wie vor zuerst die Daten mit Pandas.

def Df_Count_by_Date():
    
    df = Get_Df()
    df['date'] = np.nan
    for i in range (len(df)):
        tstr = "2020-" + str(df['Bestätigter Monat'][i]) + "-" + str(df['Festes Datum'][i])
        tdatetime = dt.strptime(tstr, '%Y-%m-%d')
        df['date'][i] = tdatetime

    df_count_by_date = df.groupby("date").count()

    df_count_by_date["total"] = np.nan
    df_count_by_date['gap'] = np.nan
    df_count_by_date["total"][0] = df_count_by_date["China"][0]
    df_count_by_date["gap"][0] = 0

    for i in range (1, len(df_count_by_date)):
        df_count_by_date["total"][i] = df_count_by_date['total'][i-1] + df_count_by_date['China'][i]
        df_count_by_date['gap'][i] = df_count_by_date['total'][i] - df_count_by_date['China'][i]
    df_count_by_date['total'] = df_count_by_date['total'].astype('int')
    df_count_by_date['gap'] = df_count_by_date['gap'].astype('int')

    return df_count_by_date
def Graph_total():

    df_count_by_date = Df_Count_by_Date()

    fig = go.Figure(data=[
        go.Bar(
            name='Kumulative Anzahl bis zum Vortag',
            x=df_count_by_date.index,
            y=df_count_by_date['gap'],
            ),
        go.Bar(
            name='Neue Nummer',
            x=df_count_by_date.index,
            y=df_count_by_date['China']
            )
    ])
    # Change the bar mode
    fig.update_layout(
        barmode='stack',
        template="plotly_dark",
        title={
            'text': "Veränderungen in der Anzahl der Patienten",
            'font':{
                'size':25
                },
            'y':0.9,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'
            },
        xaxis_title="Date",
        yaxis_title="Anzahl der infizierten Personen",
        )
    fig.show()

total.png

5. Plotten Sie auf der Weltkarte

Plotlys Scattergeo erkennt das Land mit einem dreistelligen ISO-Code. Leihen Sie sich also den Ländercode aus dem Netz aus und führen Sie ihn mit Pandas zusammen.

INDEX COUNTRY Confirmed Deaths ISO CODES code size
0 China 81049 3230 CN / CHN CHN 82049.0
1 Italy 27980 2158 IT / ITA ITA 28980.0
2 Iran 14991 853 IR / IRN IRN 15991.0
3 South Korea 8236 75 KR / KOR KOR 9236.0
4 Spain 7948 342 ES / ESP ESP 8948.0
fig = px.scatter_geo(
        df_globe_merge,
        locations="code",
        color='Deaths',
        hover_name="COUNTRY",
        size="size",
        projection="natural earth"
        )
fig.update_layout(
        width=700,
        height=500,
        template="plotly_dark",
        title={
            'text': "Verteilung infizierter Personen",
            'font':{
                'size':25
            },
            'y':0.9,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'},
        geo = dict(
            resolution = 50,
            landcolor = 'rgb(204, 204, 204)',
            coastlinewidth = 1,
            ),
        margin = {
            'b':3,
            'l':3,
            'r':3,
            't':3
        })
fig.show()

world.png

Sie können es auch füllen.

fig = px.choropleth(
    df_globe_merge,
    locations="code",
    color='Confirmed',
    hover_name="COUNTRY",
    color_continuous_scale=px.colors.sequential.GnBu
    )
fig.update_layout(
        width=700,
        height=500,
        template="plotly_dark",
        title={
            'text': "Verteilung infizierter Personen",
            'font':{
                'size':25
            },
            'y':0.9,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'},
        geo = dict(
            resolution = 50,
            landcolor = 'rgb(204, 204, 204)',
            coastlinewidth = 0.1,
            ),
        margin = {
            'b':3,
            'l':3,
            'r':3,
            't':3
        }
    )
fig.show()

map2.png

Die Farbskala ist Es ändert sich mit GnBU von color_continuous_scale = px.colors.sequential.GnBu. Farbliste https://plot.ly/python/builtin-colorscales/

Ich habe für Dash neu geschrieben, aber es hat nicht gut funktioniert, wenn es mit plotly.express visualisiert wurde. Deshalb habe ich auch eine Zeichnung mit plotly.graph_object erstellt.

fig = go.Figure(
    data=go.Choropleth(
        locations = df_globe_merge['code'],
        z = df_globe_merge['Confirmed'],
        text = df_globe_merge['COUNTRY'],
        colorscale = 'Plasma',
        marker_line_color='darkgray',
        marker_line_width=0.5,
        colorbar_title = 'Anzahl der infizierten Personen',
    )
)
fig.update_layout(
    template="plotly_dark",
    width=700,
    height=500,
    title={
        'text': "Verteilung infizierter Personen",
        'font':{
             'size':25
            },
        'y':0.9,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'},
    geo=dict(
        projection_type='equirectangular'
    )
)

fig.show()

map3.png

Es sieht fast gleich aus, außer dass die Farbskala von GnBu auf Plasma geändert wird.

Wenn die Datentransformation und -visualisierung fertig sind, möchte ich diese in Dash wiedergeben (nächstes Mal).

Recommended Posts

Lassen Sie uns den Infektionsstatus des Corona-Virus mit Plotly [für Anfänger] visualisieren.
Erstellen Sie mit Python + Plotly eine animierte Zeitreihenkarte des Infektionsstatus des Corona-Virus
INSERT in MySQL mit Python [Für Anfänger]
[Python] Bilder mit OpenCV lesen (für Anfänger)
WebApi-Erstellung mit Python (CRUD-Erstellung) Für Anfänger
[Für Anfänger] Versuchen Sie Web Scraping mit Python
Pandas-Grundlagen für Anfänger ③ Erstellen Sie ein Histogramm mit matplotlib
Kausales Denken und kausale Suche von Python (für Anfänger)
~ Tipps für Python-Anfänger mit Liebe von Pythonista ① ~
~ Tipps für Python-Anfänger mit Liebe von Pythonista ② ~
[Einführung für Anfänger] Umgang mit MySQL mit Python
Visualisieren Sie mit Plotly die Zeitreihenvorhersagen des Propheten klarer
[Für Anfänger] Skript innerhalb von 10 Zeilen (8. Plotkarte mit Folium [2]
Visualisieren Sie mit OpenCV den Wertschätzungsstatus von Kunstwerken
[Für Anfänger] Quantifizieren Sie die Ähnlichkeit von Sätzen mit TF-IDF
Seaborn-Grundlagen für Anfänger ③ Streudiagramm (Jointplot) * Mit Histogramm