-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathargentina_covid19_viz.py
347 lines (273 loc) · 10.3 KB
/
argentina_covid19_viz.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#!/usr/bin/env python
# coding: utf-8
#
# # "COVID19- Argentina"
# > "Visualización de casos basado en [jupyter-nb](https://github.com/pratapvardhan/notebooks/blob/master/covid19/covid19-overview.ipynb) de [@PratapVardhan](https://twitter.com/PratapVardhan) "
# - toc: false
# - branch: master
# - badges: true
# - hide_binder_badge: true
# - comments: false
#
#
#
#
#
#
# In[1]:
#hide
import os
import numpy as np
import pandas as pd
import glob
import locale
import arcovid19 as arc19
import altair as alt
from altair import datum
#
from jinja2 import Template
from IPython.display import HTML,display
try:
# Set Language
_=locale.setlocale(locale.LC_TIME,'es_ES.utf8')
except:
pass
# In[2]:
#hide
running_nb=False
write_products=True
# In[3]:
#hide
## readers
def get_prc_df_local(data_src,sheets=['reporte_vespertino','reporte_fix','reporte_matutino']):
"""
"""
lst_df_=[]
for sn in sheets:
df_=pd.read_excel(data_src,sheet_name=sn,parse_dates=[0])
lst_df_.append(df_)
df_cat_=pd.concat(lst_df_,axis=0,)
df_cat_['fecha']=pd.to_datetime(df_cat_['fecha'].dt.strftime('%Y-%m-%d'))
# Group all with "FIX"
df_cat_=df_cat_.groupby(['provincia','fecha'])[['confirmados','muertes','recuperados']].sum().reset_index()
#
df_cumsum_=df_cat_.groupby(['provincia'])[['confirmados','muertes','recuperados']].cumsum().add_prefix('cumsum_')
# concat dfs
df_cat=pd.concat([df_cat_,df_cumsum_],axis=1)
return df_cat
def get_prc_df_arc19(url=arc19.CASES_URL,cached=True):
"""
"""
#
df_tmp=arc19.load_cases(cached=cached)
df_tmp.reset_index(inplace=True)
df_tmp.drop(['provincia_status','Pcia_status'],axis=1,inplace=True)
df_tmp.dropna(inplace=True)
# arc19 nos da los acumulados diarios
cmra_daily={'C':'confirmados','R':'recuperados','D':'muertes','A':'activos'}
cmra_cumsum={'C':'cumsum_confirmados','R':'cumsum_recuperados','D':'cumsum_muertes','A':'cumsum_activos'}
cmra_cumsum_list=list(cmra_cumsum)
cmra_daily_list=list(cmra_daily)
df_cat_list=[]
for provincia in list(set(df_tmp.cod_provincia)):
#provincia='ARG'
df_tmp_prov=df_tmp[df_tmp.cod_provincia==provincia].T
status_names=df_tmp_prov.loc['cod_status'].to_dict()
df_tmp_prov.rename(columns=status_names,inplace=True)
df_tmp_prov.drop(['cod_provincia','cod_status'],inplace=True)
df_tmp_prov.reset_index(inplace=True)
df_tmp_prov['provincia']=provincia
df_tmp_prov.rename(columns={'index':'fecha'},inplace=True)
df_tmp_prov['fecha']=pd.to_datetime(df_tmp_prov['fecha'].dt.strftime('%Y-%m-%d'))
d=df_tmp_prov[cmra_cumsum_list].diff()
d.loc[0]=df_tmp_prov[cmra_cumsum_list].loc[0]
d.rename(columns=cmra_daily,inplace=True)
df_prov=pd.concat([df_tmp_prov,d],axis=1).rename(columns=cmra_cumsum)
df_cat_list.append(df_prov)
df_=pd.concat(df_cat_list)
provDict=arc19.CODE_TO_POVINCIA
provDict.update({'ARG':'Argentina_Nacion','BA': 'Buenos Aires'})
#
df_['provincia']=df_['provincia'].map(provDict)
return df_
#
def get_frame_unstack(df_,oncol,group_by_lst=['provincia','fecha']):
s=df_.groupby(group_by_lst)[oncol].sum().unstack()
return s
def get_template(path):
from urllib.parse import urlparse
if bool(urlparse(path).netloc):
from urllib.request import urlopen
return urlopen(path).read().decode('utf8')
return open(path).read()
def write_report(hmtl,out_name):
with open(out_name,'w') as f:
f.write(html)
#
provDict={'Ciudad Autónoma de Buenos Aire':'CABA'}
# In[4]:
#hide
## make products folders
data_includes_ = '_includes'
os.makedirs(data_includes_, exist_ok=True)
# ### Pre-Procesamiento
#
# #### Unimos los DataFrames
#
# Importamos los datos como DataFrames y los unimos.
# In[5]:
#hide_input
# CSV sources
local=True # if false import from arcovid
if local:
data_src_= 'data/casos.xlsx'
#
df_ = get_prc_df_local(data_src_)
df_['provincia'] = df_['provincia'].apply(
lambda x: provDict[x] if x in provDict else x)
else:
data_src_=arc19.CASES_URL
df_=get_prc_df_arc19(url=data_src_,cached=True)
arc19.load_cases()
print('Importando desde: {}'.format(data_src_))
df_.head()
# ### Procesamiento
#
# Procesamos los datos y dejamos los mismos en el formato que seran utilizados en el reporte.
# In[6]:
#hide_input
ndays_=-3
# Get cases
dft_cases = get_frame_unstack(df_,'confirmados')
dft_deaths = get_frame_unstack(df_,'muertes')
dft_recovered = get_frame_unstack(df_,'recuperados')
# dates
last_=dft_cases.columns[-1]
nlast_=dft_cases.columns[ndays_]
# stats
dfc_cases = dft_cases.cumsum(axis=1)[last_]
dfc_deaths = dft_deaths.cumsum(axis=1)[last_]
dfc_recovered = dft_recovered.cumsum(axis=1)[last_]
dfp_cases = dft_cases.cumsum(axis=1)[nlast_]
dfp_deaths = dft_deaths.cumsum(axis=1)[nlast_]
dfp_recovered = dft_recovered.cumsum(axis=1)[nlast_]
#
cstr=['confirmados','muertes','recuperados']
#hide
df_table = (pd.DataFrame(dict(
confirmados=dfc_cases, muertes=dfc_deaths, recuperados=dfc_recovered,
Pconfirmados=dfp_cases, Pmuertes=dfp_deaths, Precuperados=dfp_recovered))
.sort_values(by=['confirmados', 'muertes'], ascending=[False, False])
.reset_index())
for c in cstr:
df_table[f'{c} (+)'] = (df_table[c] - df_table[f'P{c}']).clip(0) # DATA BUG
df_table['Tasa Fatalidad'] = (100 * df_table['muertes'] / df_table['confirmados']).round(1)
df_table=df_table.fillna(0)
#
metrics = ['confirmados', 'muertes', 'recuperados', 'confirmados (+)', 'muertes (+)', 'recuperados (+)']
s_caba = df_table[df_table['provincia'].eq('CABA')][metrics].sum().add_prefix('CABA ')
s_bsas = df_table[df_table['provincia'].eq('Buenos Aires')][metrics].sum().add_prefix('BSAS ')
s_cba = df_table[df_table['provincia'].eq('Córdoba')][metrics].sum().add_prefix('CBA ')
s_nacion=df_table[df_table['provincia'].eq('Argentina_Nacion')][metrics].sum().add_prefix('')
summary = {'updated': pd.to_datetime(last_), 'since': pd.to_datetime(nlast_)}
summary = {**summary, **s_nacion, **s_caba, **s_bsas, **s_cba}
#
dft_ct_cases = dft_cases.cumsum(axis=1)
dft_ct_new_cases = dft_ct_cases.diff(axis=1).fillna(0).astype(int)
#
print('Visualizamos algunos:')
df_table.head(10)
# In[7]:
#hide_input
template = Template(get_template('viz_template/overview_argentina.tpl'))
html = template.render(
D=summary, table=df_table,
newcases=dft_ct_new_cases.loc[:,:],
np=np, pd=pd, enumerate=enumerate)
reporte_html=f'<div>{html}</div>'
if write_products:
name_html=os.path.join(data_includes_,last_.strftime('%Y%m%d')+'_reporte.html')
latest_html=os.path.join(data_includes_,'ultimo_reporte.html')
write_report(reporte_html,name_html)
write_report(reporte_html,latest_html)
#
if running_nb:
display(HTML(reporte_html))
# ### Curvas
#
# Visualizamos algunas curvas y graficos relacionados al covid 19.
# En el grafico central podemos ver la evolucion de casos confirmados:
# - el radio indica la cantidad de casos confirmados en el dia (tooltip)
# - la selección de un dado dia activa el grafico de barra indicando la distribucion por provincia.
# In[8]:
#hide_input
width_=660
height_curve_=400
height_bar_=220
source=df_
pts = alt.selection(type="single", encodings=['x'],empty='none')
#
tooltip_points=[alt.Tooltip('confirmados:Q', title='#Confirmados @Fecha'), alt.Tooltip('fecha:T', title='Fecha'), alt.Tooltip('provincia:N', title='Provincia'), alt.Tooltip('muertes:Q', title='Muertes'), alt.Tooltip('recuperados:Q', title='Recuperados')]
points = alt.Chart(source).mark_circle(color='orange').encode(
alt.X('fecha:T',title='Fecha'),
alt.Y('cumsum_confirmados:Q',scale=alt.Scale(type='log'),title='#Confirmados Totales en Argentina (log scale)'),
size=alt.Size('confirmados',title='Confirmados x dia'),
color=alt.condition(pts, 'confirmados:Q', alt.value('orange'),legend=None),
tooltip=tooltip_points
).properties( width=width_,
height=height_curve_).transform_filter((datum.provincia == 'Argentina_Nacion')).add_selection(pts)
tooltip_bars=[alt.Tooltip('cumsum_confirmados:Q', title='#Confirmados Totales'),alt.Tooltip('fecha:T', title='Fecha'),alt.Tooltip('provincia:N', title='Provincia')]
bars = alt.Chart(source).mark_bar().encode(
alt.X('provincia:N',axis=alt.Axis(minExtent=100),title='Provincia de Residencia'),
alt.Y('cumsum_confirmados:Q',title='Confirmados x Provincia'),
color=alt.Color('cumsum_confirmados:Q',title='Confirmados x Provincia',legend=None),
tooltip=tooltip_bars).properties(
width=width_,
height=height_bar_
).transform_filter(datum.provincia != 'Argentina_Nacion').transform_filter((pts)).interactive()
texts = alt.Chart(source).mark_text(dy=0, size=20).encode(
text='fecha:T'
).transform_filter(
pts
)
if write_products:
lines_html=os.path.join(data_includes_,'ultimo_reporte_lines.html')
alt.vconcat(points, bars+texts,data=source).save(lines_html)
if running_nb:
display(alt.vconcat(points, bars+texts))
# #### Heatmap
#
# Y observamos el heatmap correspondiente a los casos confirmados por dia
# In[9]:
#hide_input
#
width_=660
height_heatmap_=660
#
source_provincia=source[source.provincia!='Argentina_Nacion']
tooltip_bars=[alt.Tooltip('cumsum_confirmados:Q', title='#Confirmados Totales'), alt.Tooltip('fecha:T', title='Fecha'), alt.Tooltip('provincia:N', title='Provincia')]
rect=alt.Chart(source_provincia).mark_rect().encode(
alt.Y('provincia:O', title='Provincias',scale=alt.Scale(paddingInner=0)),
alt.X('monthdate(fecha):O', title='Fecha',scale=alt.Scale(paddingInner=0)),
alt.Color('confirmados:Q', title='#Confirmados x dia',scale=alt.Scale(scheme='lightgreyred')),
tooltip=tooltip_bars
).properties(width=width_, height=height_heatmap_)
# Configure text
text = rect.mark_text(baseline='middle').encode(
text=alt.Text('confirmados:Q'),
color=alt.condition(
alt.datum.confirmados < 20,
alt.value('black'),
alt.value('white')
)
)
heatmap_=(rect + text).configure_axis(
labelFontSize=12,
titleFontSize=14
)
if write_products:
heatmap_html=os.path.join(data_includes_,'ultimo_reporte_heatmap.html')
heatmap_.save(heatmap_html)
if running_nb:
display(heatmap_)
# In[ ]: