Sí, otra gráfica más sobre el coronavirus

Casi como Han Solo

Sí, ya sé que estamos saturados de gráficas y sesudos análisis epidemiológicos sobre el SARS-CoV-2 y la COVID-19, pero no encontraba la que yo quería: escala logarítmica con los casos de contagiados y fallecidos para Asturias. Podéis ver el resultado en esta web.

ACTUALIZACIÓN

Estaba registrando a diario en una Excel los valores, pero he pensado que mejor automatizarlo.

He añadido alguna gráfica más para ver los valores incrementales diarios y gráficas de tendencias.

En la versión cuatro, las gráficas generadas se han añadido directamente al post de WordPress. También permanecen en una web aparte. He tenido que añadir un plugin para poder cargar la parte HTML de la página generada en remoto vía PHP. He reducido el ancho de las gráficas para que cupiesen dentro del tema actual.

En la versión cinco, he añadido las líneas horizontales menores, un fondo gris y un parámetro de tamaño automático dependiendo de la pantalla en la que se muestren, para intentar hacerlas responsive.

Aquí va el código del script en Python:


# -*- coding: latin-1 -*-

# 27/04/2020
# asturias.v5.py
# Añado líneas horizontales y verticales al fondo de las gráficas
# así como un color gris.
# Genero las gráficas de manera que ocupen el tamaño posible en la pantalla
# para que sea responsive 

# 16/04/2020
# asturias.v4.py
# Integración dentro de WordPress
# La documentación de Bokeh para embeber gráficas está aquí:
# https://docs.bokeh.org/en/latest/docs/user_guide/embed.html


# 04/04/2020
# asturias.v3.py
# Intento introducir una línea con la media de los valores
# diarios de casos y fallecimientos, calcolando el valor
# medio entre cada día. Para ello voy a intentar usar las funciones "rolling windows" de
# pandas para generar una nueva columna de datos promedio

# 03/04/2020
# asturias.v2.py
# Quiero mostrar la variación en % de un valor respecto al siguiente
# de manera que se pueda seguir visualmente los incrementos 
# de los casos/fallecimientos. Lógicamente cuando no haya más infecciones
# ni muertos, el incremento será 0 
#
 

# 02/04/2020
# asturias.v1.py
# Cacharreando con las gráficas
# He añadido gráficas de puntos cuyo color varía
# en función de los valores

# 01/04/2020
# asturias.v0.py
#
# Estoy generando una gráfica logarítmica en excel
# Con los casos de contagiados por SARS-CoV-2 y los fallecidos por COVID-19
# en Asturias, ya que no encuentro publciada una gráfica de este tipo.
#
# He pensado que podría ser interesante automatizar el proceso de importaciónote
# de los datos y generación de la misma.
#
# ORIGEN DE LOS datos
# Voy a tomar como referencia los que publica en abierto Datadista
# del siguiente repositorio de GitHub
#
# https://github.com/datadista/datasets/tree/master/COVID%2019
#
# Seleccionaremos por tanto los siguientes archivos CSV
#
# Descripción: Acumulado del número de casos confirmados registrados por Comunidad Autónoma. Description: Accumulated number of confirmed cases registered by Autonomous Community
# Nivel administrativo: Comunidad Autónoma
# Nombre del archivo: ccaa_covid19_casos_long.csv
# URL: https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_covid19_casos_long.csv
#
# Nivel administrativo: Comunidad Autónoma
# Descripción: Acumulado del número de fallecidos registrados por Comunidad Autónoma.
# Description: Accumulated number of deceased cases registered by Autonomous Community
# Nombre del archivo: ccaa_covid19_fallecidos_long.csv
# URL: https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_covid19_fallecidos_long.csv

import pandas as pd
from bokeh.plotting import figure, output_file, save
from bokeh.models import ColumnDataSource, HoverTool, NumeralTickFormatter
from bokeh.transform import linear_cmap
from bokeh.palettes import Inferno11
from bokeh.layouts import column
from bokeh.embed import components

from scipy.interpolate import CubicSpline


casos = 'https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_covid19_casos_long.csv'
fallecidos = 'https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_covid19_fallecidos_long.csv'


# Definimos las columnas que queremos leer
campos = ['fecha','CCAA','total']

dfcasos = pd.read_csv(casos, usecols=campos, index_col='fecha', parse_dates=True)

# Filtramos los casos para Asturias: CCAA = Asturias
# Hacemos lo que se recomienda: primero generamos una Serie con valores True/False con un filtrado previo
# que usaremos para generar la selección final.

# En filtro tenemos una serie con los índices (que en nuestro caso son las fechas) y los valores True/False
# que se adecúan a la condición

filtro = dfcasos['CCAA'] == 'Asturias'

dfcasosasturias=dfcasos.loc[filtro]

# Mapeamos los colores
# Tenemos que quedarnos con la serie de los datos sobre los que mapear los colores
# y no con todo el dataframe que contiene las fechas también
ycasos = dfcasosasturias['total']
Inferno11.reverse()
mappercasos = linear_cmap(field_name='total',
	palette=Inferno11,
	low=min(ycasos),
	high=max(ycasos))

# Calculamos las variaciones de un día a otro con la función diff
# Creamos un DataFrame sobre la serie ycasos que habíamos utilizado 
# para hacer el mapeo de colores. Lo hacemos porque queremos tener
# una gráfica aparte, no solo de los acumulados.

# Calculamos el valor medio diario
# Añadimos una nueva columna y usamos las funciones rolling y mean para que caculle
# con una ventana de dos valores, la media. Queremos el valor medio que hay entre varios días consecutivos
# para dibujar la tendencia. Podemos elegir el tamaño de ventana que consideremos. 
variacionescasos = pd.DataFrame(data=ycasos.diff())
variacionescasos['media_diaria']=variacionescasos['total'].rolling(4).mean()


fuentevariacioncasos=ColumnDataSource(variacionescasos)
fuentecasos = ColumnDataSource(dfcasosasturias)

# Procesamos los datos de los fallecidos
dffallecidos = pd.read_csv(fallecidos, usecols=campos, index_col='fecha', parse_dates=True)
dffallecidosfiltroasturias = dffallecidos['CCAA']=='Asturias'
dffallecidosasturias = dffallecidos[dffallecidosfiltroasturias]
yfallecidos = dffallecidosasturias['total']
mapperfallecidos = linear_cmap(field_name='total',
	palette=Inferno11,
	low=min(yfallecidos),
	high=max(yfallecidos))
variacionesfallecidos = pd.DataFrame(data=yfallecidos.diff())
variacionesfallecidos['media_diaria']=variacionesfallecidos['total'].rolling(4).mean()
fuentevariacionesfallecidos=ColumnDataSource(variacionesfallecidos)

fuentefallecidos = ColumnDataSource(dffallecidosasturias)


hover_tool=HoverTool()
hover_tool.tooltips = [
                ('Fecha', '@fecha{%F}'),
                ('Valor', '@total')
        ]
hover_tool.formatters = {
                '@fecha' : 'datetime'
        }

hover_tool_variaciones=HoverTool()

hover_tool_variaciones.tooltips = [
                ('Fecha', '@fecha{%F}'),
                ('Valor', '@total')
        ]
hover_tool_variaciones.formatters = {
                '@fecha' : 'datetime',
        }


p = figure(title="Asturias",
            #plot_height=300,
            #plot_width=650,
            y_axis_type="log",
	    background_fill_color="#fafafa",
            x_axis_type="datetime")

p1 = figure(title="Incremental casos en Asturias",
            #plot_height=300,
            #plot_width=650,
	    background_fill_color="#fafafa",
            x_axis_type="datetime")

p2 = figure(title="Incremental muertes en Asturias",
            #plot_height=300,
            #plot_width=650,
	    background_fill_color="#fafafa",
            x_axis_type="datetime")

# Cositas de https://docs.bokeh.org/en/latest/docs/gallery/stocks.html

p.line(x='fecha',
	y='total',
	source=fuentecasos,
	line_color="orange",
	legend_label="Casos confirmados",
	line_width=3)

p.line(x='fecha', y='total',source=fuentefallecidos,
              line_color="tomato", legend_label="Fallecimientos confirmados", line_width=3)

# Gráfica con puntos para los casos
p.circle(x='fecha',
	y='total',
	source=fuentecasos,
	line_color=mappercasos,
	color=mappercasos,
	size=8,
	alpha=0.6)

# Gráfica con puntos para los decesos 
p.circle(x='fecha',
	y='total',
	source=fuentefallecidos,
	line_color=mapperfallecidos,
	color=mapperfallecidos,
	size=8,
	alpha=0.6)

p.add_tools(hover_tool)
p.legend.location = "top_left"

# Gráfica para valores absolutos de casos diarios
p1.line(x='fecha',
	y='total',
	source=fuentevariacioncasos,
	legend_label="Casos confirmados diarios",
	line_width=4)
p1.line(x='fecha',
	y='media_diaria',
	line_width=12,
	alpha=0.4,
	source=fuentevariacioncasos,
	legend_label="Media 4 dias casos confirmados")
# Gráfica para valores absolutos de muertes
p2.line(x='fecha',
	y='total',
	legend_label="Muertes confirmadas",
	source=fuentevariacionesfallecidos,
	color='tomato',
	line_width=4)

p2.line(x='fecha',
	y='media_diaria',
	line_width=12,
	alpha=0.4,
	source=fuentevariacionesfallecidos,
	legend_label="Media 4 dias muertes confirmadas",
	color='tomato')

p1.add_tools(hover_tool_variaciones)
p1.legend.location = "top_left"
p2.add_tools(hover_tool_variaciones)
p2.legend.location = "top_left"

# Añadimos las líneas horizontales y verticales menores
p.ygrid.minor_grid_line_color = 'navy'
p.ygrid.minor_grid_line_alpha = 0.1

p.xgrid.minor_grid_line_color = 'navy'
p.xgrid.minor_grid_line_alpha = 0.1

p1.ygrid.minor_grid_line_color = 'navy'
p1.ygrid.minor_grid_line_alpha = 0.1

p1.xgrid.minor_grid_line_color = 'navy'
p1.xgrid.minor_grid_line_alpha = 0.1

p2.ygrid.minor_grid_line_color = 'navy'
p2.ygrid.minor_grid_line_alpha = 0.1

p2.xgrid.minor_grid_line_color = 'navy'
p2.xgrid.minor_grid_line_alpha = 0.1

# Ajuste al tamaño de display disponible
p.sizing_mode="stretch_both"
p1.sizing_mode="stretch_both"
p2.sizing_mode="stretch_both"


# Definimos el fichero de salida
output_file("/home/aorviz/tecnologia/_site/SARS-CoV-2/asturias.html")
save(column(p,p1,p2), title="Casos confirmados y muertes por la COVID-19 en Asturias")

# Para generar el código embebido a insertar en WordPress
plots = {'Total': p, 'Casos': p1, 'Fallecidos': p2}
script, div = components(plots)

# Escribimos el javascript
fscript = open("/home/aorviz/tecnologia/_site/SARS-CoV-2/asturias_include.html","w")
fscript.write(script)

# Escribimos los div
fscript.write(div['Total'])
fscript.write(div['Casos'])
fscript.write(div['Fallecidos'])
fscript.close()

#print(script)
#print(div)

Por último la entrada en el cron:

# Ejecutamos dos veces al día (a las 12 del mediodía y 
# a las 17) el generador de estadísticas
# con los contagiados y fallecidos por la COVID-19
0 12,17 * * * /usr/bin/python3.5 /home/aorviz/tecnologia/_site/SARS-CoV-2/asturias.v0.py
URL corta del artículo: https://wp.me/p575FY-nP

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.