In [2]:
!pip install -U plotly
!pip install dash
!pip install dash-html-components
!pip install dash-core-components
!pip install dash-table
!pip install dash_bootstrap_components
!pip install pycountry
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import os
import plotly
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.express as px
import imageio
import json
import pycountry
from google.colab import drive, files
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from getpass import getpass
drive.mount("/content/drive")
%cd "/content/drive/My Drive/Coronavirus"
!rm -rf coronavirus-data
!git config --global user.email "johan.d.s.vonk@gmail.com"
!git config --global user.name "Johan Vonk"
!git clone https://github.com/jvonk/coronavirus-data.git
%cd coronavirus-data
In [101]:
INPUT_PATH = "/content/drive/My Drive/Coronavirus/coronavirus-data/input"
INPUT_URL = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data"
LOOKUP_CSV_PATH = os.path.join(INPUT_PATH, 'lookup.csv')
CONFIRMED_CSV_PATH = os.path.join(INPUT_PATH, 'confirmed.csv')
DEATHS_CSV_PATH = os.path.join(INPUT_PATH, 'deaths.csv')
RECOVERED_CSV_PATH = os.path.join(INPUT_PATH, 'recovered.csv')
!wget -nv -cO "$LOOKUP_CSV_PATH" $INPUT_URL/UID_ISO_FIPS_LookUp_Table.csv
!wget -nv -cO "$CONFIRMED_CSV_PATH" $INPUT_URL/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv
!wget -nv -cO "$DEATHS_CSV_PATH" $INPUT_URL/csse_covid_19_time_series/time_series_covid19_deaths_global.csv
!wget -nv -cO "$RECOVERED_CSV_PATH" $INPUT_URL/csse_covid_19_time_series/time_series_covid19_recovered_global.csv
df_lookup = pd.read_csv(LOOKUP_CSV_PATH);
def transform_and_standardize(df, var_name):
df = df.drop(columns=['Lat', 'Long']).merge(
df_lookup.rename(columns={'Country_Region': 'Country/Region', 'Province_State': 'Province/State'})[['Country/Region', 'Province/State', 'iso3','Population']],
how='outer',
on=['Country/Region', 'Province/State']
).dropna(subset=["iso3"])
df = df.groupby(['iso3','Country/Region']).sum().reset_index()
df = df.melt(id_vars=[df.columns[0],df.columns[1],df.columns[-1]],
value_vars=df.columns[2:-1],
var_name='date',
value_name=var_name
).dropna()
df['date']=pd.to_datetime(df['date'])
return df.sort_values(by=['iso3', 'date'])
df_confirmed = transform_and_standardize(pd.read_csv(CONFIRMED_CSV_PATH), 'confirmed')
df_deaths = transform_and_standardize(pd.read_csv(DEATHS_CSV_PATH), 'deaths')
df_recovered = transform_and_standardize(pd.read_csv(RECOVERED_CSV_PATH), 'recovered')
df = df_confirmed.merge(df_deaths,how='outer',on=['date', 'iso3', 'Population','Country/Region']).merge(df_recovered,how='outer',on=['date', 'iso3', 'Population','Country/Region'])
for col in ['confirmed', 'deaths', 'recovered']:
df[f'{col}_rate'] = df[col]/df_merged['Population']
df
Out[101]:
In [106]:
!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
!unzip ngrok-stable-linux-amd64.zip
get_ipython().system_raw('./ngrok http 8050 &')
! curl -s http://localhost:4040/api/tunnels | python3 -c "import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])"
In [112]:
import time
from flask import request
unixTimeMillis = lambda dt: int(time.mktime(dt.timetuple()))
app = dash.Dash("Coronavirus Dashboard", external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css'])
app.layout = html.Div([
dcc.Graph(id='indicator-graphic'),
dcc.Slider(
id='date-slider',
min=unixTimeMillis(df['date'].min()),
max=unixTimeMillis(df['date'].max()),
value=[unixTimeMillis(df['date'].min()),unixTimeMillis(df['date'].min())],
marks={unixTimeMillis(date):str(date.strftime('%Y-%m-%d')) for date in df['date']},
step=None
)
])
def shutdown():
func = request.environ.get('werkzeug.server.shutdown'),
if func is None:
raise RuntimeError('Not running with the Werkzeug Server')
func()
@app.callback(
Output('indicator-graphic', 'figure'),
[Input('url', 'pathname'), Input('date-slider', 'value')])
def update_graph(pathname, date_value):
if pathname =='/shutdown':
shutdown()
dff = df[df['date'] == date_value]
return {
'data': [
go.Choropleth(
locations=dff['iso3'],
z=dff['confirmed_rate'],
text=dff['Country/Region'],
autocolorscale=False,
colorscale="YlGnBu",
marker={'line': {'color': 'rgb(180,180,180)','width': 0.5}},
colorbar={"thickness": 10,"len": 0.3,"x": 0.9,"y": 0.7}
)
],
'layout': go.Layout(height=800,geo={'showframe': False,'showcoastlines': False})
}
if __name__ == '__main__':
app.run_server(debug=True)
In [111]:
scatter_confirmed = px.scatter_geo(df, title="Cases as a Scatter", locations="iso_alpha", color_discrete_sequence=["#cb181d"], size="Confirmed", animation_frame="Days_since_start", hover_name="Country/Region")
scatter_death = px.scatter_geo(df, title="Deaths as a Scatter", locations="iso_alpha", color_discrete_sequence=["#cb181d"], size="Deaths", animation_frame="Days_since_start", hover_name="Country/Region")
choropleth_confirmed = px.choropleth(df, title="Cases as a Choropleth", locations="iso_alpha", color="Rate", animation_frame="Days_since_start", hover_name="Country/Region")
choropleth_death = px.choropleth(df, title="Deaths as a Choropleth", locations="iso_alpha", color="Death Rate", animation_frame="Days_since_start", hover_name="Country/Region")
In [0]:
%cd "/content/drive/My Drive/Coronavirus/coronavirus-data"
fig.write_html("docs/index.html",include_plotlyjs='cdn',include_mathjax='cdn',default_width="100%",default_height="100%")
PASSWORD = getpass()
!git add --all
!git commit -a
!git config remote.origin.url 'https://jvonk:{PASSWORD}@github.com/jvonk/coronavirus-data.git'
!git push
%cd data