HomeCódigo

Código para a geração da visualização

As biblitecas utilizadas são ggplot2, algumas extensões do ggplot, dplyr e geobr (para a obtenção do mapa do estado de São Paulo).

#necessary packages
library(ggplot2)
library(sf)
library(geobr)
library(dplyr)
library(ggrepel)
library(grid)
library(gridExtra)

Em cada um dos plots teremos que ajustar os dados de acordo com a informação que será apresentada. Para o primeiro plot, separamos as cidades em três grupos: pequenas (até 100 mil habitantes), médias (até 300 mil habitantes) e grandes (maiores do que 300 mil habitantes). Em seguida, com os dados agrupados exibimos a média móvel de 7 dias.

data_original <- read.csv("dados_covid_sp2.csv", sep = ";", encoding = "UTF-8")
data_sp <- data_original %>%
  select(nome_munic, dia, mes, datahora, casos, casos_novos, casos_pc, casos_mm7d, 
         obitos, obitos_novos, obitos_pc, obitos_mm7d, letalidade, pop, pop_60, semana_epidem) %>%
  mutate(datahora = as.Date(datahora, "%d/%m/%Y")) %>%
  mutate(tamanho_cidade = ifelse(pop > 500000, "grande", ifelse(pop > 100000, "média", "pequena")))

data_sp.plot1 <- data_sp %>% group_by(tamanho_cidade, datahora) %>%
  summarise(casos_novos = sum(casos_novos), casos_mm7d = sum(casos_mm7d))

#setting plot information
title <- "Casos diários no estado de São Paulo agrupados pelo\ntamanho das cidades (pop.)"
x_lab <- "Data"
x_lim <- c(as.Date("2020-03-30"),max(unique(data_sp.plot1$datahora)) - 7)
y_lab <- "Número de casos"
y_ticks <- seq(0, 6000, 1000)
color_title <- "Cidades"
color_lab <- c("pequena", "média", "grande")
color_val <- c("#450256","#21908d", "#f9e721")


plot1 <- ggplot(data_sp.plot1) +
  geom_area(aes(x = datahora, y = casos_mm7d, fill = tamanho_cidade), position = position_stack(reverse = TRUE)) +
  geom_vline(xintercept = as.Date("2020-06-01"), color = "grey20") +
  geom_text(aes(x =as.Date("2020-05-23"), y = 5000, label = "         Inicio da\n   flexibilização"),  color = "black") +
  scale_x_date(x_lab, date_breaks = "2 week", date_labels = "%d/%m", limits = x_lim) +
  scale_y_continuous(y_lab, breaks = y_ticks, limits = c(0, 6000)) +
  scale_colour_manual(color_title, values = color_val, aesthetics = "fill") +
  ggtitle(title) +
  theme_classic() +
  theme(legend.position="none")

Esse plot será um plot auxiliar para o inicial, iremos apresentar um retângulo e para cada dia iremos representar a proporção dos casos para cada um dos grupos como a área deste retângulo.

data_sp.plot3 <- data_sp.plot1 %>% 
  mutate(casos_mm7d = ifelse(casos_mm7d < 0, 0, casos_mm7d)) %>%
  group_by(datahora) %>% 
  mutate(porcentagem = casos_mm7d/sum(casos_mm7d))
data_sp.plot3[is.na(data_sp.plot3$porcentagem), "porcentagem"] <- 0
data_sp.plot3[data_sp.plot3$porcentagem > 1, "porcentagem"] <- 1
data_sp.plot3[data_sp.plot3$porcentagem < 0, "porcentagem"] <- 0

plot3 <- ggplot(data_sp.plot3) +
  geom_area(aes(x = datahora, y = porcentagem, fill = tamanho_cidade), 
            position = position_stack(reverse =  TRUE)) +
  scale_x_date(limits = x_lim) +
  scale_y_continuous(limits = c(-0, 1)) +
  scale_colour_manual(color_title, values = color_val, aesthetics = "fill") +
  theme(axis.line=element_blank(),
      axis.text.x=element_blank(),
      axis.text.y=element_blank(),
      axis.ticks=element_blank(),
      axis.title.x=element_blank(),
      axis.title.y=element_blank(),
      legend.position = "bottom",
      panel.background=element_blank(),
      panel.border=element_blank(),
      panel.grid.major=element_blank(),
      panel.grid.minor=element_blank(),
      plot.background=element_blank())

No terceiro plot é apresentado o número total de casos para o último dia registrado em cada uma das cidades, para apresentar no estado de São Paulo utilizamos o polígono oferecido pela biblioteca geobr (obtido do IBGE).

mun <- read_municipality(code_muni = "SP", year = 2018, simplified = TRUE)
data_sp.plot2 <- left_join(mun, 
                           data_sp %>% filter(datahora == max(data_sp$datahora)), 
                           by = c("name_muni" = "nome_munic"))
#setting plot information
fill_title <- "Casos acumulados"
fill_breaks <- c(10, 100, 1000, 10000, 100000)
fill_labs <- c("10", "100", "1mil", "10mil", "100mil")
cidades <- c("São Paulo", "Campinas", "Santos")

plot2 <- ggplot(data_sp.plot2) +
  geom_sf(aes(fill = casos)) +
  scale_fill_continuous(fill_title, type = "viridis", trans = "pseudo_log",
                        breaks = fill_breaks, labels =  fill_labs) +
  geom_label_repel(data = data_sp.plot2 %>% 
                     filter(name_muni %in% cidades), 
                   aes(label = name_muni, geometry = geom),
                       stat = "sf_coordinates",
                       min.segment.length = 0) +
  theme(axis.line = element_blank(),
        axis.ticks = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank(),
        panel.background = element_blank(),
        panel.grid = element_blank())

No quarto plot apresentamos as séries temporais dos casos diários registrador por 100 mil habitantes, dessa forma, não apenas os municípios com grande populações apareceram como os com mais casos. No entanto, para apresentar os dados, não apresentamos os dias em que os dados são repetidos, apresentamos os pontos em que os registros são atualizados.

data_sp.plot4 <- data_sp %>%
                  group_by(nome_munic) %>% filter(casos_pc != lag(casos_pc))
data_sp.plot4_l <- data_sp.plot4 %>% filter(nome_munic %in% cidades)
data_sp.plot4_m <- data_sp.plot4 %>% group_by(datahora) %>%
  summarise(casos_pc = mean(casos_pc))

x_lim4 <- c(as.Date("2020-03-30"),max(unique(data_sp.plot1$datahora)))
y_lab4 <- "Casos por 100 mil habitantes"
y_ticks4 <- c(10, 100, 500, 1000, 2500, 5000)

plot4 <- ggplot(data_sp.plot4) +
  geom_line(aes(x = datahora, y = casos_pc, group = nome_munic), alpha = 0.05) +
  geom_line(data = data_sp.plot4_l, aes(x = datahora, y = casos_pc, group = nome_munic), color = "#21908d") +
  geom_line(data = data_sp.plot4_m, aes(x = datahora, y = casos_pc), color =  "#f9e721", size = 1) +
  geom_text_repel(data = data_sp.plot4_m %>%
              filter(datahora == max(datahora) - 30), aes(x = datahora, y = casos_pc, label = "Média")) +
  geom_text_repel(data = data_sp.plot4_l %>%
                  filter(datahora == max(datahora) - 10), 
                  aes(x = datahora, y = casos_pc, label = nome_munic)) +
  scale_y_continuous(y_lab4, breaks = y_ticks4, 
                     limits = c(0, 5000), trans = "pseudo_log") +
  scale_x_date(x_lab, date_breaks = "2 week", date_labels = "%d/%m", limits = x_lim4) +
  theme_classic()

O quinto de último plot utilizaremos as informações de isolamento social. Discretizamos os valores do isolamento médio das cidades em 4 grupos e também discretizamos os valores dos casos totais em 4 grupos. Em seguida contamos a frequência de cada um desses grupos e apresentamos a informação em um mapa de calor.

data_sp_isolamento <- read.csv("isolamento.csv", sep = ";", encoding = "UTF-8")
data_sp_isolamento <- data_sp_isolamento %>% select(nome_munic, media)
data_sp.plot5 <- data_sp  %>%
  filter(datahora == max(datahora) - 1) %>% 
  select(nome_munic, casos_pc) 
data_sp.plot5 <- left_join(data_sp_isolamento, data_sp.plot5, by = c("nome_munic" = "nome_munic")) %>%
  filter(!is.na(casos_pc))

data_sp.plot5$casos_pc_d <- "a"
data_sp.plot5$media_d <- "a"
for(i in 1:length(data_sp.plot5$media)){
  aux1 <- data_sp.plot5[i, "media"]
  aux2 <- data_sp.plot5[i, "casos_pc"]
  if(aux1 > 0.55){
    data_sp.plot5[i, "media_d"] <- "4"
  }else if(aux1 > 0.5){
    data_sp.plot5[i, "media_d"] <- "3"
  }else if(aux1 > 0.45){
    data_sp.plot5[i, "media_d"] <- "2"
  }else if(aux1 >= 0.4){
    data_sp.plot5[i, "media_d"] <- "1"
  }
  
  if(aux2 > 1000){
    data_sp.plot5[i, "casos_pc_d"] <- "4"
  }else if(aux2 > 500){
    data_sp.plot5[i, "casos_pc_d"] <- "3"
  }else if(aux2 > 100){
    data_sp.plot5[i, "casos_pc_d"] <- "2"
  }else if(aux2 >= 0.){
    data_sp.plot5[i, "casos_pc_d"] <- "1"
  }
}
data_sp.plot5_df <- as.data.frame(table(data_sp.plot5$media_d, data_sp.plot5$casos_pc_d))

xlabs.plot5 <- c("[0.4, 0.45]", "(0.45, 0.5]", "(0.5, 0.55]", "(0.55, 0.6]")
ylabs.plot5 <- c("[0, 100]", "(100, 500]", "(500, 1000]", "(1000, 2000]")
plot5 <- ggplot(data_sp.plot5_df) +
  geom_tile(aes(x = Var1, y = Var2, fill = Freq), colour = "white") +
  scale_fill_continuous(type = "viridis") +
  geom_text(aes(x = Var1, y = Var2, label = Freq), color = "white") +
  scale_x_discrete("Média do isolamento social", labels = xlabs.plot5) +
  scale_y_discrete("Casos por 100 mil habitantes", labels = ylabs.plot5) +
  theme(panel.background = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        legend.position = "none")

Por fim unimos os 5 plots para gerar a visualização.

plotGrob <- rbind(ggplotGrob(plot1), ggplotGrob(plot3), ggplotGrob(plot4))
panels <- plotGrob$layout$t[grep("panel", plotGrob$layout$name)]
plotGrob$heights[panels] <- unit(c(0.4, 0.1, 0.5), "null")
grid <- grid.arrange(plotGrob, plot2, plot5, layout_matrix = cbind(c(1, 1), c(2, 3)))

ggsave("plot.png", plot = grid, width = 297, height = 210, units = "mm")