Globo interativo em R
Eu sou viciado em visualizações geográficas; eu acho que ela realmente colocam os dados em perspectiva, como se cada ponto tivesse seu lugar. Neste tutorial vou te ensinar a criar um globo 3D interativo bastante interessante com o pacote threejs
.
Introdução
Nosso objetivo é visualizar o comércio do Japão com arcos em uma animação tridimensional da Terra. A base de dados que utilizaremos (Japan Trade Statistics, por Tadashi Nagao) é um ótimo exemplo do que encontramos no dia-a-dia: os dados têm informação apenas sobre os países (seus nomes registrados de forma desordenada) e têm não tem absolutamente nenhum dado sobre suas coordenadas.
Criaremos a visualização em 3 passos: pegar as coordenadas da capital de cada país, converter os nomes dos países para um formado padrão e criar o globo em si.
Pegando as coordenadas
Nossa primeira tarefa é importar os dados.
Eu carreguei os dados com informação do comércio japonês, carreguei a tabela com a relação país/código e então juntei as duas em um data frame. Eu também converti os nomes das colunas para caixa baixa e agrupei a tabela por país (somando os valores de todo o comércio com cada país). Nada disso é mostrado aqui por ser muito pouco geral, mas este foi o resultado:
country_name | country | value |
---|---|---|
Afghanistan | 130 | 8764947 |
Albania | 229 | 1473130 |
Algeria | 503 | 59532804 |
American_Oceania | 622 | 4914 |
American_Samoa | 621 | 276510 |
Andorra | 212 | 29382 |
Depois desse setup inicial, podemos seguir em frente e pegar as coordenadas da capital de cada país com o pacote maps
(vamos usar as coordenadas das capitais como os “pontos de aterrissagem” dos arcos no globo 3D). Aqui vou carregar a tabela world.cities
e selecionar os nomes dos países, suas capitais e suas coordenadas.
# Pegar as coordenadas de cada capital
capitals <- world.cities %>%
filter(capital == 1) %>%
transmute(
country_name = country.etc,
lat = lat,
long = long
) %>%
rbind(c("Hong Kong", 22.39, 114.1))
Obs.: Não nos deixemos levar pela geopolítica, mas eu adicionei Hong Kong manualmente porque aparentemente ela é/não é parte da China, então ela não está na tabela world.cities
…
Essa é a cara da tabela capitals
:
country_name | lat | long |
---|---|---|
Jordan | 31.95 | 35.93 |
United Arab Emirates | 24.48 | 54.37 |
Nigeria | 9.18 | 7.17 |
Ghana | 5.56 | -0.2 |
Pitcairn | -25.05 | -130.1 |
Ethiopia | 9.03 | 38.74 |
Convertendo os nomes dos países
Preste atenção em como “American Samoa” e “United Arab Emirates” estão escritos nas duas tabelas acima (esse é o principal motivo pelo qual eu as incluí). Eles não estão formatados da mesma maneira.
Eu vou te poupar dos detalhes, mas esta é a parte mais difícil de trabalhar com dados geográficos: os nomes são um saco. As duas tabelas com as quais temos que trabalhar têm os nomes formatados de maneiras muito diferentes, então temos que padronizá-los.
Vamos fazer isso com o pacote countrycodes
, mais especificamente com a base countrycode_data
. Ela têm uma coluna com comandos regex que conseguem encontrar o nome de cada país quase independentemente da forma que ele estiver escrito. Primeiramente eu faço uma pequena limpeza em trades\$country_name
, mas depois é simples assim:
# Pegar o regex de cada país
regex <- countrycode::countrycode_data$country.name.en.regex
# Pegar a correspondência entre os países de 'totals' e
# 'capitals'
trades_capitals <- as_tibble(cbind(
regex,
trades_countries = match_country(regex, trades$country_name),
capitals_countries = match_country(regex, capitals$country_name)
))
No código acima estou omitindo a função match_country
, que simplesmente associa cada entrada em regex
com uma entrada do segundo argumento, mas o código em si é bem simples! E agora temos a tabela que conecta os nomes em trades
com os nomes em capitals
, que pode ser usada para juntas as duas em uma nova tabela chamada geo_trades
.
Criando o globo
Para criar os arcos no globo precisamos de uma tabela com um formato bastante especial. Ela precisa conter 4 colunas: origin_lat
, origin_long
, dest_lat
, e dest_long
que serão os pontos iniciais e finais para cada arco no globo.
Eu vou usar geo_trades
para criar uma nova tabela chamada arcs
(nossa tabela também terá o valor da comércio entre as duas pontas, mas vamos excluir essa coluna quando passarmos a tabela para a função que gerará o globo). É assim que eu criei arcs
:
# Criar origem e destino dos arcos (origem é sempre Tóquio)
arcs <- geo_trades %>%
cbind(
origin_lat = 35.68,
origin_long = 139.69
) %>%
select(-country_name) %>%
transmute(
origin_lat = origin_lat,
origin_long = origin_long,
dest_lat = lat,
dest_long = long,
value = value
)
E agora o grand finale: essa é a função que usamos para gerar o globo 😁 Se você olhar com cuidado para a imagem abaixo, é possível ver que a grossura de cada linha representa o volume monetário total das trocas comerciais entre o Japão e cada país.
# Pegar a imagem do globo
earth <- system.file("images/world.jpg", package = "threejs")
# Criar globo
globejs(
img = earth, lat = arcs$dest_lat, long = arcs$dest_long,
arcs = arcs[, 1:4], arcsOpacity = 0.6, arcsHeight = 0.8,
arcsLwd = arcs$value, arcsColor = "green", atmosphere = TRUE,
height = 800, width = 800, bg = "white", value = 4
)
E se você quiser interagir com o globo, por favor vá para o meu Kaggle kernel onde o HTML funciona melhor.