La prochaine fois https://qiita.com/Naoya_Study/items/851f4032fb6e2a5cd5ed
Avec la propagation de l'infection à coronavirus, diverses organisations ont publié des tableaux de bord sympas qui visualisent l'état de l'infection.
Exemple 1 Situation du nouveau coronavirus de l'OMS (COVID-19)
Exemple 3 Toyo Keizai ONLINE New Corona Virus Domestic Infection Status
C'est cool! Je veux pouvoir faire quelque chose comme ça moi-même. Le but ultime est de créer un tableau de bord comme l'exemple ci-dessus à l'aide de Dataframe Dash spécifique à la visualisation de Python. Cette fois, je voudrais dessiner en utilisant la bibliothèque de visualisation Plotly comme préparation préliminaire. Veuillez me pardonner pour le désordre de code.
Nous utiliserons les données sur l'état de l'infection publiées par Toyo Keizai Online au Japon. 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)
Les données sont dans ce format.
Nouveau Non. | Ancien Non. | Année confirmée | Mois confirmé | Date fixe | Âge | sexe | Lieu de résidence 1 | Lieu de résidence 2 |
---|---|---|---|---|---|---|---|---|
1 | 1 | 2020 | 1 | 15 | 30 s | Homme | Préfecture de Kanagawa | |
2 | 2 | 2020 | 1 | 24 | Quarante | Homme | Chine (ville de Wuhan) | |
3 | 3 | 2020 | 1 | 25 | 30 s | femme | Chine (ville de Wuhan) | |
4 | 4 | 2020 | 1 | 26 | Quarante | Homme | Chine (ville de Wuhan) | |
5 | 5 | 2020 | 1 | 28 | Quarante | Homme | Chine (ville de Wuhan) | |
6 | 6 | 2020 | 1 | 28 | Années 60 | Homme | Préfecture de Nara |
Comme vous pouvez le voir, les données sur les personnes vivant en Chine sont également incluses, mais cette fois elles seront limitées au Japon, elles seront donc exclues.
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'Chine(...)'
df['China'] = np.nan
for i in range (1, len(df)+1):
if re.match(pattern, df['Lieu de résidence 1'][i]):
df['China'][i] = "T"
else:
df['China'][i] = "F"
df = df[df["China"] != "T"].reset_index()
return df
Index. | Nouveau Non. | Ancien Non. | Année confirmée | Mois confirmé | Date fixe | Âge | sexe | Lieu de résidence 1 | Lieu de résidence 2 | China |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 2020 | 1 | 15 | 30 s | Homme | Préfecture de Kanagawa | NaN | F |
1 | 6 | 6 | 2020 | 1 | 28 | Années 60 | Homme | Préfecture de Nara | NaN | F |
2 | 8 | 8 | 2020 | 1 | 29 | Quarante | femme | Préfecture d'Osaka | NaN | F |
3 | 9 | 10 | 2020 | 1 | 30 | Années 50 | Homme | Préfecture de Mie | NaN | F |
4 | 11 | 12 | 2020 | 1 | 30 | 20 ans | femme | Kyoto | NaN | F |
def Graph_Pref():
df = Get_Df()
df_count_by_place = df.groupby('Lieu de résidence 1').count().sort_values('China')
fig = px.bar(
df_count_by_place,
x="China",
y=df_count_by_place.index,
#En définissant l'orientation sur horizontal, il devient un graphique à barres horizontales.
orientation='h',
width=800,
height=1000,
)
fig.update_layout(
title="La préfecture où l'infection est signalée",
xaxis_title="Nombre de personnes infectées",
yaxis_title="",
#Spécifiez simplement le modèle et ce sera un graphique basé sur le noir sans autorisation
template="plotly_dark",
)
fig.show()
Plotly crée lui-même des diagrammes interactifs et à la mode.
Ensuite, je voudrais tracer le nombre de personnes infectées par préfecture sur une carte du Japon sous forme de carte à dispersion. Pour ce faire, obtenez d'abord les informations de latitude et de longitude de la préfecture de chaque préfecture et combinez-les avec les données csv de Toyo Keizai Online. Localisation du bureau préfectoral Les données de latitude et de longitude utilisées provenaient de Everyone's Knowledge A little Convenient Book. Extrayez uniquement les données requises pour la latitude et la longitude et combinez-les à l'aide de pandas merge.
def Df_Merge():
df = Get_Df()
df_count_by_place = df.groupby('Lieu de résidence 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': 'Lieu de résidence 1'})
df_latlon = df_latlon.head(47)
df_merge = pd.merge(df_count_by_place, df_latlon, on='Lieu de résidence 1')
return df_merge
index | Lieu de résidence 1 | Nouveau Non. | Ancien Non. | Année confirmée | Mois confirmé | Date fixe | Âge | sexe | Lieu de résidence 2 | China | latitude | longitude |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Préfecture de Gifu | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 35.39111 | 136.72222 |
1 | Préfecture d'Ehime | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 33.84167 | 132.76611 |
2 | Préfecture d'Hiroshima | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 34.39639 | 132.45944 |
3 | Préfecture de 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éfecture de Yamaguchi | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 34.18583 | 131.47139 |
Tracez sur la carte en utilisant le bloc de données ci-dessus.
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['Lieu de résidence 1'][i] + ' : ' + str(df_merge['China'][i]) + 'Homme'
fig = go.Figure(data=go.Scattergeo(
lat = df_merge["latitude"],
lon = df_merge["longitude"],
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': "Répartition des personnes infectées",
'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()
Ceci est une image, mais si vous le faites en ligne, vous pouvez voir le nombre spécifique de personnes infectées en déplaçant le curseur sur le graphique, ce qui est cool. Essayez-le.
Vient ensuite un graphique à barres de l'évolution du nombre de personnes infectées. Comme auparavant, transformez d'abord les données avec des pandas.
def Df_Count_by_Date():
df = Get_Df()
df['date'] = np.nan
for i in range (len(df)):
tstr = "2020-" + str(df['Mois confirmé'][i]) + "-" + str(df['Date fixe'][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='Nombre cumulé jusqu'à la veille',
x=df_count_by_date.index,
y=df_count_by_date['gap'],
),
go.Bar(
name='Nouveau numéro',
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': "Changements dans le nombre de patients",
'font':{
'size':25
},
'y':0.9,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'
},
xaxis_title="Date",
yaxis_title="Nombre de personnes infectées",
)
fig.show()
Le scattergeo de Plotly reconnaît le pays avec un code ISO à 3 chiffres, alors empruntez le code du pays sur le net et fusionnez-le avec les pandas.
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': "Répartition des personnes infectées",
'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()
Vous pouvez également le remplir.
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': "Répartition des personnes infectées",
'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()
L'échelle de couleur est Il change avec GnBU de color_continuous_scale = px.colors.sequential.GnBu. Liste de couleurs https://plot.ly/python/builtin-colorscales/
J'étais en train de réécrire pour Dash, mais cela ne fonctionnait pas bien s'il était visualisé avec plotly.express, donc j'ai également fait un dessin en utilisant plotly.graph_object.
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 = 'Nombre de personnes infectées',
)
)
fig.update_layout(
template="plotly_dark",
width=700,
height=500,
title={
'text': "Répartition des personnes infectées",
'font':{
'size':25
},
'y':0.9,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
geo=dict(
projection_type='equirectangular'
)
)
fig.show()
Cela a presque le même aspect, sauf que l'échelle de couleurs est changée de GnBu à Plasma.
Lorsque la transformation et la visualisation des données sont prêtes, j'aimerais les refléter dans Dash (la prochaine fois)
Recommended Posts