Skip to content

Latest commit

 

History

History
185 lines (150 loc) · 7.34 KB

7.1 Comparações entre Países.md

File metadata and controls

185 lines (150 loc) · 7.34 KB

Comparações entre países

  • Traça gráfico compararativo entre países.

  • A variável min_casos na terceira célula determina o ponto inicial a ser traçado.

  • Cada pais atingiu este limite em datas diferentes, logo a escala em x é relativa.

  • A data inicial da cada país é mostrada na legenda ao lado do nome do país.

  • OBS: Como os dados são diários, pode não acontecer um dia com dados confirmados exatamente igual a min_casos. Neste caso, a primeira data com número de casos igual ou superior é escolhida como inicial. A série é, então normalizada pela constante casos_min dividido pelo número de casos na data inicial. Isto pode levar a distorções, especialmente quando o mínimo de casos é grande.

# Nesta célula, as seguintes operações são feitas:
# 1. A url do banco de dados é aberta.
# 2. Os dados são baixa numa string em formato csv
# 3. Os dados são convertidos em lista
# 4. A url é fechada com o fim da indentação da clásula with

import urllib       # https://docs.python.org/3.8/library/urllib.html
import csv          # https://docs.python.org/3.8/library/csv.html
import io           # https://docs.python.org/3.8/library/io.html

# https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv
url = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv'

# Library
with urllib.request.urlopen(url) as f:                  # Abre a url
    string_recebida_da_url = f.read().decode('utf-8')   # Lê o conteúdo e decodifica em utf-8
    conteudo_csv = csv.reader(io.StringIO(string_recebida_da_url)) # Transforma em iterador csv
    lista_com_dados = list(conteudo_csv)                # Desempacota numa lista

# print(lista_com_dados)  # Observe o formato.
d = {'Brazil':3}
print(d.get('Brazil', 0))
print(d.get('France', 0))
# print(lista_com_dados[2])
print(int('34'))

3
0
34

# Nesta célula, as seguintes operações são feitas:
# 1. Define-se a varável cabecalho com a primeira linha dos dados.
# 2. Cria-se o dicionário dados cujas chaves são os nomes dos países.
#    A cada chave, associa-se série temporal como número de casos. Ex:
#     {'Brazil': [0, 10, 30, ...], 'France': [1, 2, 30, 40, ...]}    
#
#    Como alguns países são listados divididos em regiões, precisamos
#    somar as diversas linhas com o mesmo nome de país.
#
#    Usamos os arrays do numpy para somar linhas, já que soma de lista
#    resulta em concatenação e não em soma termo a termo.
#
#    A função map(f, lista) aplica a função f a cada termo de lista.
#    Aqui, a função int converte string em inteiro, ex: int('12') = 12.

import numpy as np

cabecalho = lista_com_dados.pop(0) # Retira primeira linha com cabeçalho

dados = {}  # Inicializa dicionário vazio

# Alguns países são listados divididos em regiões, aqui somamos.
for linha in lista_com_dados:
    pais = linha[1]
    dados[pais] = dados.get(pais, 0) + np.array([*map(int, linha[4:])])
    # obs: dados.get(key, default) # Retorna dados[key] se a chave existe, senão o valor padrão

# print(dados.keys())    # Mostra países listados
print(dados['Brazil']) # Mostra série temporal para o país

[ 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 2 2
2 2 4 4 13 13 20 25 31 38
52 151 151 162 200 321 372 621 793 1021
1546 1924 2247 2554 2985 3417 3904 4256 4579 5717
6836 8044 9056 10360 11130 12161 14034 16170 18092 19638
20727 22192 23430 25262 28320 30425 33682 36658 38654 40743
43079 45757 50036 54043 59324 63100 67446 73235 79685 87187
92202 97100 101826 108620 115455 126611 135773 146894 156061 162699
169594 178214 190137 203165 220291 233511 241080 255368 271885 291579
310087 330890 347398 363211 374898 391222 411821 438238 465166 498440
514849 526447 555383 584016 614941 645771 672846 691758 707412 739503]

# Nesta célula, as seguintes operações são feitas:
# 1. Um dicionário indicando quais países devem ser analisados.
#    Use 0 para não analisar o país e 1 para analisar.
#
# 2. Constroi o dicionário dados_a_serem_plotados contendo apenas os países a
#    serem mostrados e já com as séries temporais podadas a partir da data
#    quando atingiram o número de casos mínimos.
#
# 3. Constroi o dicionário data_de_inicio com a data quando cada país atingiu
#    o número de casos mínimos. Isto será usado apenas na legenda do gráfico.
#    Observe o uso da função datetime.datetime.strptime() para converter
#    string em datetime.

# Importa módulo datetime.datetime
from datetime import datetime as dt

# Use 1 para mostrar e 0 para não mostrar
# Estão em ordem de número de casos (11/05).
# Há outros países listados, basta acrescentar.

paises_a_serem_mostrados ={
  'US':0, 'Spain':1, 'United Kingdom':1, 'Italy':1, 'Russia':0, 'France':1,
  'Germany':1, 'Brazil':1, 'Turkey':0, 'Iran':0, 'China':0, 'Canada':0,
  'Peru':0, 'India':0, 'Belgium':0, 'Netherlands':0, 'Saudi Arabia':0,
  'Mexico':0, 'Pakistan':0, 'Switzerland':0}

# Número de casos a partir do dia quando de deseja plotar
min_casos = 100

dados_a_serem_plotados = {}
data_de_inicio = {}

# Filtra dados antes de min_casos.
for pais in paises_a_serem_mostrados:
    if paises_a_serem_mostrados[pais]:  # Verdadeiro se diferente de 0
        lista = dados[pais]
        indice = np.min((lista>=min_casos).nonzero())
        lista = lista[indice:]
        lista = lista * (min_casos / lista[0]) # normaliza para que todos comecem com min_casos
        dados_a_serem_plotados[pais] = lista

        # Registra o dia quando atingingiu casos_min.
        # Será usado apenas na legenda.
        data_de_inicio[pais] =  dt.strptime(cabecalho[indice + 4], '%m/%d/%y')
# Aqui os dados são plotados

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig, ax = plt.subplots()

legenda = []

# Calcula o número de caractere do país com nome mais longo.
# Será usado para alinhar as datas.
comprimento_da_legenda = max(len(pais) for pais in dados_a_serem_plotados)

for pais in dados_a_serem_plotados:
    espessura_de_linha = 2 if pais=='Brazil' else 1
    ax.plot(dados_a_serem_plotados[pais], linewidth=espessura_de_linha)
    legenda.append(('{: <' + str(comprimento_da_legenda) + '} ({:%d/%m})').format(pais, data_de_inicio[pais]))

# Ajusta ticks a 45 graus
plt.xticks(rotation=45)
ax.xaxis.set_major_locator(ticker.AutoLocator())

# Adiciona rótulo aos eixos
plt.ylabel("Número de casos", fontsize=14)

# Adiciona grade
ax.grid(True)

# Escala logaritmica
ax.set_yscale('log')

# Mostra legenda
ax.legend(legenda,  loc='upper left', bbox_to_anchor=(1, 1), fontsize=12,
          prop={'family':'monospace'})

# Título
fig.suptitle('Evolução desde os {} primeiros casos.'.format(min_casos))
fig.patch.set_facecolor('white')
fig.set_size_inches(10, 4)
x = np.array([1, 2, 3, 10, 30])
indice = (x>=5).nonzero()
print(indice)

(array([3, 4]),)