forked from sillasgonzaga/livro_intro_r
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path13-htmlwidgets.Rmd
326 lines (243 loc) · 13.1 KB
/
13-htmlwidgets.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# Visualizações Interativas {#htmlwidgets}
```{r 13-htmlwidgets-1, include=FALSE, warning=FALSE, message=FALSE}
knitr::opts_chunk$set(fig.align='center', fig.width = 7, fig.asp = 0.618,
out.width = '100%', message = FALSE)
library(ggplot2)
library(plotly)
theme_set(theme_gray())
```
## 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](http://rmarkdown.rstudio.com/) e no [Shiny](http://shiny.rstudio.com/). 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:
1. [D3](https://d3js.org/)
2. [D3plus](https://d3plus.org/)
3. [Highcharts](http://www.highcharts.com/)
4. [C3](http://c3js.org/)
5. [Leaflet](http://leafletjs.com/)
6. [Plotly](https://plot.ly)
Existe uma quantidade significativa de pacotes que utilizam o `htmlwidgets`. Para se ter uma noção, visite [esta galeria](http://gallery.htmlwidgets.org/).
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.
## 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.
```{r 13-htmlwidgets-2}
# criando grafico estatico
library(gapminder)
p <- gapminder %>%
filter(year == 2007) %>%
ggplot(aes(x = gdpPercap, y = lifeExp)) +
geom_point(aes(color = continent))
p
```
```{r 13-htmlwidgets-3}
# converter para interativo
ggplotly(p)
```
<br>
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`:
```{r 13-htmlwidgets-4, warning = FALSE}
# mostrar apenas a aesthetic x,
# na qual foi mapeada a variavel de expectativa de vida
ggplotly(p, tooltip = "x")
```
<br>
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:
```{r 13-htmlwidgets-5}
nome <- c("Lucas", "Eduardo", "Flávio")
sobrenome <- c("Silva", "Oliveira", "Dias")
# concatenar os dois vetores acima, juntando nome e sobrenome com espaço no meio
paste0(nome, " ", sobrenome)
```
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:
```{r 13-htmlwidgets-6, warning = FALSE}
# refazer o grafico, definindo uma nova aesthetic chamada text:
p <- gapminder %>%
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")
```
<br>
## dygraphs
O dygraphs é uma biblioteca para visualizações de séries temporais. Os detalhes do pacote estão disponíveis [neste link](https://rstudio.github.io/dygraphs/).
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()`:
```{r 13-htmlwidgets-7, eval = FALSE}
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 ao `start`, 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:
```{r 13-htmlwidgets-8}
x <- rnorm(24, mean = 100, sd = 10)
# Trasnformando em série mensal a partir de janeiro de 2010
x <- ts(x, freq = 12, start = c(2010, 1))
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`.
```{r 13-htmlwidgets-9}
library(xts)
xts_df <- data.frame(y = rnorm(365, 100, 10))
xts_df$data <- seq.Date(as.Date("2011-01-01"), length.out = 365,
by = "1 day")
xts_df <- xts(x = xts_df[, "y"], order.by = xts_df[, "data"])
head(xts_df)
```
```{r 13-htmlwidgets-10}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)
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:
```{r 13-htmlwidgets-11}
# Alterar rótulos do eixo x e a legenda
axlabform <- "function(date, granularity, opts, dygraph) {
var months = ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio',
'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'];
return months[date.getMonth()] + \" \" + date.getFullYear()}"
valueform <- "function(ms) {
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()}"
valueformy <- "function(value) {
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()
```
## 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](https://rstudio.github.io/leaflet/). 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.
```{r 13-htmlwidgets-12, eval=FALSE, message=FALSE}
library(dplyr)
library(leaflet)
leaflet() %>%
addTiles()
```
```{r 13-htmlwidgets-13, echo=FALSE, message=FALSE}
library(dplyr)
library(leaflet)
leaflet() %>%
addTiles(urlTemplate = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')
```
### 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.
```{r 13-htmlwidgets-14, eval=FALSE, message = FALSE}
library(ggmap)
# Pegar Localização do ibpad (Google desatualizado)
#loc.ibpad <- geocode("IBPAD")
loc.ibpad <- data.frame(lon = -47.8838813, lat = -15.8010146)
loc.ibpad$popup <- "Estamos aqui! (teoricamente)"
leaflet(loc.ibpad) %>%
addTiles() %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~popup)
```
```{r 13-htmlwidgets-15, echo=FALSE, message = FALSE}
library(ggmap)
# Pegar Localização do ibpad (Google desatualizado)
#loc.ibpad <- geocode("IBPAD")
loc.ibpad <- data.frame(lon = -47.8838813, lat = -15.8010146)
loc.ibpad$popup <- "Estamos aqui! (teoricamente)"
leaflet(loc.ibpad) %>%
addTiles(urlTemplate = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png') %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~popup)
```
### 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](http://www.mdic.gov.br/comercio-exterior/estatisticas-de-comercio-exterior/empresas-brasileiras-exportadoras-e-importadoras). 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.
```{r 13-htmlwidgets-16, eval=FALSE}
dados.empresas.mt <- read_delim('dados/empresas_exp_mt.csv',
delim = ";",
locale = locale(encoding = 'ISO-8859-1',
decimal_mark = ","))
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA)
```
```{r 13-htmlwidgets-17, echo=FALSE}
dados.empresas.mt <- read_delim('dados/empresas_exp_mt.csv',
delim = ";",
locale = locale(encoding = 'ISO-8859-1',
decimal_mark = ","))
leaflet(dados.empresas.mt) %>%
addTiles('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png') %>%
addMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA)
```
Podemos também adicionar outros tipos de marcadores, como círculos:
```{r 13-htmlwidgets-18, eval=FALSE}
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3)
```
```{r 13-htmlwidgets-19, echo=FALSE}
leaflet(dados.empresas.mt) %>%
addTiles('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png') %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3)
```
Adicionalmente, é possível agrupar pontos próximos em clusters.
```{r 13-htmlwidgets-20, eval=FALSE}
leaflet(dados.empresas.mt) %>%
addTiles() %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3,
clusterOptions = markerClusterOptions())
```
```{r 13-htmlwidgets-21, echo=FALSE}
leaflet(dados.empresas.mt) %>%
addTiles(urlTemplate = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png') %>%
addCircleMarkers(lat = ~lat, lng = ~lon, popup = ~EMPRESA, fillOpacity = 0.3,
clusterOptions = markerClusterOptions())
```
### 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()`:
```{r 13-htmlwidgets-22}
# baixa
library(brmap) # remotes::install_github("italocegatta/brmap")
mapa_ufs <- brmap::brmap_estado
head(mapa_ufs)
mapa_estatico <- ggplot(mapa_ufs) +
geom_sf(aes(text = estado_nome))
# converter para interativo
ggplotly(mapa_estatico, tooltip = 'text')
```
## Exercícios
1. Usando os pacotes ggmap e leaflet, crie uma visualização marcando cinco localizações de Brasília.
2. Utilizando a base `gapminder` (`library(gapminder)`), crie uma visualização usando o pacote `plotly`.
3. A partir da base `economics` do pacote `ggplot2`, escolha uma variável e plote a série histórica utilizando o pacote `dygraphs`.
4. Entre na galeria de htmlwidgets [neste link], escolha alguma htmlwidget que você tenha achado interessante e replique um exemplo.
<style>
.ggiraph{
font-size: 8px !important;
}
.dygraph-axis-label{
font-size: 60% !important;
}
.leaflet-control{
font-size: small !important;
}
</style>