Um ano atrás eu publiquei o post Rotas Aéreas no Brasil, no qual eu traçava as rotas aéreas nacionais entre todos os aeroportos comerciais brasileiros. Hoje vou retornar àquele conjunto de dados, mas de uma outra forma.

Decidi utilizar um gráfico chamado circos plot, muito utilizado em genética, para essa visualização. O resultado está ao final desse bloco de código abaixo.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
theme_set(theme_bw())
library(brazilmaps)
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
# leitura dos dados

aeroportos_br <- clean_names(read.csv(file = "dados/aeroportos_br.csv"))
aeroportos    <- clean_names(read.csv(file = "dados/Full_Merge_of_All_Unique Airports.csv"))
rotas         <- clean_names(read.csv(file = "dados/Full_Merge_of_All_Unique_Routes.csv"))

# manter apenas as rotas dentro do brasil

rotas_br <-
  rotas %>%
  filter(departure %in% aeroportos_br$id) %>%
  filter(destination %in% aeroportos_br$id)
  
# juntar rotas e localizacao dos aeroportos

rotas_br <- 
  rotas_br %>%
  rename(id = departure) %>%
  left_join(aeroportos, by = "id") %>%
  select(departure = id, destination, latitude_dep = latitude, longitude_dep = longitude) %>%
  rename(id = destination) %>%
  left_join(aeroportos, by = "id") %>%
  select(departure, destination = id, latitude_dep, longitude_dep, latitude_des = latitude, longitude_des = longitude)

# numero de voos por rota

rotas_br <- 
  rotas_br %>%
  group_by(departure, destination) %>%
  count() %>%
  left_join(rotas_br, by = c("departure", "destination")) %>%
  arrange(n)

# visualizacao

library(circlize)
## ========================================
## circlize version 0.4.16
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
## 
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
##   in R. Bioinformatics 2014.
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(circlize))
## ========================================
maiores_aeroportos <- 
  rotas_br %>%
  group_by(departure) %>%
  summarise(rotas_de_saida = sum(n)) %>%
  arrange(desc(rotas_de_saida))

k <- 10

maiores_aeroportos_nomes <- head(maiores_aeroportos$departure, k)

rotas_br_simplificadas <- 
  rotas_br %>%
  select(departure, destination, n) %>%
  mutate(departure = ifelse(departure %in% maiores_aeroportos_nomes, departure, "Outros"),
         destination = ifelse(destination %in% maiores_aeroportos_nomes, destination, "Outros"))

chordDiagram(rotas_br_simplificadas, 
             row.col = brewer.pal(k, "Paired"),
             column.col = brewer.pal(k, "Paired"))

Como é possível ver, para melhorar a visualização, eu mantive apenas os 10 aeroportos mais movimentados do país. Coloquei todos os aeroportos da 11a até a última posição dentro da categoria Outros.

Cada aeroporto é representado por uma cor. As faixas que saem de cada aeroporto são proporcionais ao número de voos: quanto mais voos, mais larga é a faixa. Além disso, as faixas que possuem a mesma cor do aeroporto são referentes às partidas, enquanto as faixas de cores diferentes indicam as chegadas.