13 Visualizações Interativas
13.1 Introdução
No R, as visualizações interativas são, geralmente, criadas a partir de pacotes que utilizam um framework chamado htmlwidgets
. O hmtlwidgets
é um pacote/framework que facilita o uso de bibliotecas javascript de visualizações para o ambiente R, sendo possível usá-las no console, no RMarkdown e no Shiny. Basicamente, javascript é uma linguagem client-side, ou seja, aquelas onde o processamento ocorre no lado do cliente. É utilizada, principalmente, para alterar códigos HTML e CSS (estilos) interativamente.
O htmlwidgets
busca fazer a ponte entre o R e alguma biblioteca javascript de visualização, fazendo com que o usuário do R consiga utilizar essas bibliotecas sem necessariamente precisar escrever uma linha de código em javascript. Apesar de não ser necessário, pode ser que, em algum momento, a fim de customizar uma visualização, seja necessário algum código em javascript, mas isto não será tratado aqui.
Abaixo estão listados alguns projetos de visualização de dados em javascript:
Existe uma quantidade significativa de pacotes que utilizam o htmlwidgets
. Para se ter uma noção, visite esta galeria.
O objetivo deste capítulo é fazer uma pequena apresentação sobre alguns pacotes. Cada pacote possui um conjunto de detalhes que torna inviável apresentá-los neste curso. Dessa forma, faremos um breve tour por alguns pacotes, começando com o plotly.
13.2 Plotly
É possível ainda dar ainda mais vida aos seus gráficos os transformando em interativos de maneira muito fácil. O pacote plotly
, além de ser um ótimo pacote para produzir gráficos interativos em R ou Python, possui uma funcão chamada ggplotly()
que transforma um gráfico estático do ggplot2 em interativo.
# criando grafico estatico
library(gapminder)
<- gapminder %>%
p filter(year == 2007) %>%
ggplot(aes(x = gdpPercap, y = lifeExp)) +
geom_point(aes(color = continent))
p
# converter para interativo
ggplotly(p)
Com apenas uma simples função, temos um gráfico cheio de recursos interativos, como possibilidade de dar zoom em áreas específicos do gráfico e tooltips, que é a pequena tabela de dados que aparece na tela ao passar o mouse em um ponto.
Como era de se esperar, as tooltips também podem ser customizadas. A função ggplotly
possui um parâmetro chamado tooltip
onde pode ser especificada a aesthetic que será mostrada na tooltip. Por padrão, como você viu, a tooltip mostra todas as aesthetics definidas no gráfico. Caso você queira mudar esse aspecto, pode mudar o valor desse parâmetro em ggplotly
:
# mostrar apenas a aesthetic x,
# na qual foi mapeada a variavel de expectativa de vida
ggplotly(p, tooltip = "x")
Incrivelmente, dá para ficar ainda melhor. É definindo uma nova aesthetic chamada text
, que por padrão não pertence ao ggplot2 mas é usada pelo plotly para construir a tooltip.
Essa nova aesthetic, usada em combinação com a função paste0
, pode criar tooltips informativas e elegantes.
Caso não conheça a função paste0()
, ela serve para concatenar vetores de strings em um só, de maneira paralelizada.
Segue alguns exemplos:
<- c("Lucas", "Eduardo", "Flávio")
nome <- c("Silva", "Oliveira", "Dias")
sobrenome # concatenar os dois vetores acima, juntando nome e sobrenome com espaço no meio
paste0(nome, " ", sobrenome)
## [1] "Lucas Silva" "Eduardo Oliveira" "Flávio Dias"
Usando essa função, vamos definir a aesthetic
de forma que mostre o nome dos países e os valores das variáveis dos eixos:
# refazer o grafico, definindo uma nova aesthetic chamada text:
<- gapminder %>%
p filter(year == 2007) %>%
ggplot(aes(x = gdpPercap, y = lifeExp)) +
geom_point(aes(
color = continent,
text = paste0("País: ", country, '\n',
"Expectativa de vida: ", round(lifeExp), "\n",
"PIB per capita: ", gdpPercap)
))
ggplotly(p, tooltip = "text")
13.3 dygraphs
O dygraphs é uma biblioteca para visualizações de séries temporais. Os detalhes do pacote estão disponíveis neste link.
Antes dos exemplos, será necessário falar sobre objetos de séries de tempo no R.
Para criar um objeto de séries de tempo usaremos a função ts()
:
ts(data = NA, start = 1, end = numeric(), frequency = 1,
deltat = 1, ts.eps = getOption("ts.eps"), class = , names = )
Os parâmetros relevantes são:
data
: um vetor ou uma matriz de valores da(s) série(s) de tempo. Um data.frame é transformado automaticamente em uma matriz;start
: o período da primeira observação. Pode ser um valor único ou um vetor de dois inteiros. Geralmente, utiliza-se a segunda opção. Por exemplo, Janeiro de 1997:start = c(1997, 1)
;end
: o período da última observação. Similar aostart
, porém não é obrigatório;frequency
: frequência dos dados. Mensal(12), Trimestral (4), Anual(1) etc.
Exemplo de criação de uma série de tempo:
<- rnorm(24, mean = 100, sd = 10)
x # Trasnformando em série mensal a partir de janeiro de 2010
<- ts(x, freq = 12, start = c(2010, 1))
x plot(x)
Outra maneira de declarar um objeto de série de tempo é utilizando a função xts()
do pacote de mesmo nome. No entanto, para essa função, precisamos de um vetor ordenado de datas do tipo Date
, POSIXct
, timeDate
, yearmon
e yearqtr
.
library(xts)
<- data.frame(y = rnorm(365, 100, 10))
xts_df $data <- seq.Date(as.Date("2011-01-01"), length.out = 365,
xts_dfby = "1 day")
<- xts(x = xts_df[, "y"], order.by = xts_df[, "data"])
xts_df
head(xts_df)
## [,1]
## 2011-01-01 90.87153
## 2011-01-02 100.81501
## 2011-01-03 112.04756
## 2011-01-04 109.55455
## 2011-01-05 101.10612
## 2011-01-06 99.33796
library(dygraphs)
<- cbind(mdeaths, fdeaths)
lungDeaths dygraph(lungDeaths,
main = "Mortes por Doenças Pulmonares - Reino Unido - 1874-1979",
ylab = "Número de Morets") %>%
dySeries("mdeaths", color = "blue", label = "Homens") %>%
dySeries("fdeaths", color = "green", label = "Mulheres") %>%
dyRangeSelector()
Aqui fica o código para alterar os padrões dos números e datas:
# Alterar rótulos do eixo x e a legenda
<- "function(date, granularity, opts, dygraph) {
axlabform var months = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio',
'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
return months[date.getMonth()] + \" \" + date.getFullYear()}"
<- "function(ms) {
valueform var months = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio',
'Junho', 'Julho', 'Agosto', 'Setembro',
'Outubro', 'Novembro', 'Dezembro'];
var ms = new Date(ms);
return months[ms.getMonth()] + '/' + ms.getFullYear()}"
<- "function(value) {
valueformy return (Math.round(value * 100)/100).toString()
.replace('.', ',')
.replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.')}"
dygraph(lungDeaths,
main = "Mortes por Doenças Pulmonares - Reino Unido - 1874-1979",
ylab = "Número de Morets") %>%
dySeries("mdeaths", color = "blue", label = "Homens") %>%
dySeries("fdeaths", color = "green", label = "Mulheres") %>%
dyAxis("y", valueFormatter = valueformy) %>%
dyAxis("x", axisLabelFormatter = axlabform, valueFormatter = valueform) %>%
dyRangeSelector()
13.4 Leaflet
O leaflet é, provavelmente, a principal biblioteca javascript para visualizações interativas de mapas. Mais informações sobre o pacote estão disponíveis neste link. Para iniciarmos uma visualização com leaflet, basta executar o código abaixo. A função addTiles()
adiciona uma camada de mapas ao leaflet que foi inicializado.
library(dplyr)
library(leaflet)
leaflet() %>%
addTiles()
13.4.1 Primeiro exemplo
No primeiro exemplo, incluiremos um marcador na localização do IBPAD. Para isso, obteremos a latitude e a longitude usando a função geocode()
do pacote ggmap
. Além disso, foi incluída uma coluna chamada popup
, que receberá um texto que será mostrado no mapa.
library(ggmap)
# Pegar Localização do ibpad (Google desatualizado)
#loc.ibpad <- geocode("IBPAD")
<- data.frame(lon = -47.8838813, lat = -15.8010146)
loc.ibpad $popup <- "Estamos aqui! (teoricamente)"
loc.ibpadleaflet(loc.ibpad) %>%
addTiles() %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~popup)
13.4.2 Marcadores
No exemplo abaixo, criaremos uma visualização com a posição de algumas empresas exportadoras de Mato Grosso, a partir de dados disponibilizados pelo MDIC. Como a busca da localização foi feita usando o endereço, nem sempre a localização estará perfeitamente correta. No entanto, para exemplificar o uso do pacote, não há problemas.
<- read_delim('dados/empresas_exp_mt.csv',
dados.empresas.mt delim = ";",
locale = locale(encoding = 'ISO-8859-1',
decimal_mark = ","))
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA)
Podemos também adicionar outros tipos de marcadores, como círculos:
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3)
Adicionalmente, é possível agrupar pontos próximos em clusters.
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3,
clusterOptions = markerClusterOptions())
13.4.3 Polígonos
Também é possível criar-se polígonos a partir de shapefiles.
Para isso, o caminho mais fácil é importar um shapefile usando o pacote sf
, criar um gráfico estático com geom_sf()
e o converter para interativo com plotly::ggplotly()
:
# baixa
library(brmap) # remotes::install_github("italocegatta/brmap")
<- brmap::brmap_estado
mapa_ufs
head(mapa_ufs)
## Simple feature collection with 6 features and 4 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -73.99045 ymin: -13.6937 xmax: -46.07095 ymax: 5.271841
## Geodetic CRS: SIRGAS 2000
## # A tibble: 6 × 5
## estado_cod regiao_cod estado_nome estado_sigla geometry
## <int> <int> <chr> <chr> <POLYGON [°]>
## 1 11 1 Rondônia RO ((-62.86662 -7.975868, -62.86017 -7.982323, -62.85336 -7.987563, -62.84506 -7.98…
## 2 12 1 Acre AC ((-73.18253 -7.335496, -73.05413 -7.381955, -72.90031 -7.437681, -72.7132 -7.505…
## 3 13 1 Amazonas AM ((-67.32609 2.029714, -67.31682 2.00125, -67.3104 1.966763, -67.3002 1.92667, -6…
## 4 14 1 Roraima RR ((-60.20051 5.264343, -60.19828 5.260453, -60.1969 5.257114, -60.19328 5.252951,…
## 5 15 1 Pará PA ((-54.95431 2.583692, -54.93542 2.518585, -54.91956 2.499682, -54.91117 2.489685…
## 6 16 1 Amapá AP ((-51.1797 4.000081, -51.17784 3.997409, -51.17739 3.994021, -51.17803 3.990301,…
<- ggplot(mapa_ufs) +
mapa_estatico geom_sf(aes(text = estado_nome))
## Warning: Ignoring unknown aesthetics: text
# converter para interativo
ggplotly(mapa_estatico, tooltip = 'text')