Artigo escrito em colaboração com Carolina Jacomini.
Plotly é uma empresa de computação técnica (2012) com sede em Montreal, Quebec, que desenvolve análises de dados online e ferramentas de visualização. Plotly fornece gráficos, análises e ferramentas estatísticas para indivíduos e empresas, bem como bibliotecas de gráficos científicos para Python, R, MATLAB, Perl, Julia, Arduino e REST.
O pacote Plotly cria gráficos interativos da web a partir de gráficos ‘ggplot2’ e/ou uma interface personalizada para a biblioteca JavaScript (MITlicensed) ‘plotly.js’ inspirada na gramática dos gráficos. Para rodar os exemplos nesse artigo vamos usar o dplyr então é preciso ter o tidyverse já instalado.
library(dplyr)
library(plotly)
Gráficos básicos
Scatter plot
Exemplo
O banco utilizado é o iris. Ele contém três espécies de flores (setosa, virginica, versicolor) e outras 4 variáveis relacionadas as suas medidas:
- Comprimento da sépala
- Largura da sépala
- Comprimento da pétala
- Largura da pétala
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
Scatter <- plot_ly(data = iris,
x = ~Sepal.Length,
y = ~Petal.Length,
color = ~Species,
type = 'scatter',
mode = 'markers') %>%
layout(xaxis = list(title = "Comprimento da sépala"),
yaxis = list(title = "Comprimento da pétala"))
Scatter
Line plot
Exemplo
O banco de dados contém informações das temperaturas médias (mais baixa e mais alta por dia) de Nova York por mês em 3 anos (2000, 2007, 2014). Sendo assim as variáveis do banco são:
- Ano
- Mês
- Médias das temperaturas altas
- Médias das temperaturas baixas
head(Temp.New.york)
## month high_2000 low_2000 high_2007 low_2007 high_2014 low_2014
## 1 January 32.5 13.8 36.5 23.6 28.8 12.7
## 2 February 37.6 22.3 26.6 14.0 28.5 14.3
## 3 March 49.9 32.5 43.6 27.0 37.0 18.6
## 4 April 53.0 37.2 52.3 36.8 56.8 35.5
## 5 May 69.1 49.9 71.5 47.6 69.7 49.9
## 6 June 75.4 56.1 81.4 57.7 79.7 58.0
line <- plot_ly(Temp.New.york,
x = ~month,
y = ~high_2014,
name = 'High 2014',
type = 'scatter',
mode = 'lines',
line = list(color = 'rgb(205, 12, 24)',
width = 4)) %>%
add_trace(y = ~low_2014,
name = 'Low 2014',
line = list(color = 'rgb(22, 96, 167)',
width = 4)) %>%
add_trace(y = ~high_2007,
name = 'High 2007',
line = list(color = 'rgb(205, 12, 24)',
width = 4,
dash = 'dash')) %>%
add_trace(y = ~low_2007,
name = 'Low 2007',
line = list(color = 'rgb(22, 96, 167)',
width = 4,
dash = 'dash')) %>%
add_trace(y = ~high_2000,
name = 'High 2000',
line = list(color = 'rgb(205, 12, 24)',
width = 4,
dash = 'dot')) %>%
add_trace(y = ~low_2000,
name = 'Low 2000',
line = list(color = 'rgb(22, 96, 167)',
width = 4,
dash = 'dot')) %>%
layout(title = "Temperaturas médias alta e baixa em New York",
xaxis = list(title = "Mês"),
yaxis = list (title = "Temperatura (ºF)"))
line
Density plot
Exemplo
O banco utilizado é o diamonds do pacote ggplot2. Ele contém preços de mais de 50.000 cortes de diamantes. As variáveis são:
- Preço em dolár
- Peso
- Corte
- Cor
- Pureza
- x – comprimento em mm
- y – comprimento em mm
- z – comprimento em mm
- Profundidade
- Largura do topo do diamante
library(ggplot2)
dens <- with(diamonds,
tapply(price,
INDEX = cut,
density))
data.dens <- data.frame(x = unlist(lapply(dens, "[[", "x")),
y = unlist(lapply(dens, "[[", "y")),
cut = rep(names(dens),
each = length(dens[[1]]$x)))
head(data.dens)
## x y cut
## Fair1 -1114.8694 6.744087e-08 Fair
## Fair2 -1073.4981 9.022150e-08 Fair
## Fair3 -1032.1268 1.196403e-07 Fair
## Fair4 -990.7555 1.572893e-07 Fair
## Fair5 -949.3842 2.064376e-07 Fair
## Fair6 -908.0129 2.708506e-07 Fair
density <- plot_ly(data.dens,
x = ~x,
y = ~y,
color = ~cut) %>%
add_lines() %>%
layout(xaxis = list(title = "Preço"),
yaxis = list(title = ""))
density
Bar chart
Exemplo
Também usa o banco de dados diamonds.
data.bar <- ggplot2::diamonds %>%
count(cut,
clarity)
head(data.bar)
## # A tibble: 6 x 3
## cut clarity n
## <ord> <ord> <int>
## 1 Fair I1 210
## 2 Fair SI2 466
## 3 Fair SI1 408
## 4 Fair VS2 261
## 5 Fair VS1 170
## 6 Fair VVS2 69
bar <- data.bar %>%
plot_ly(x = ~cut,
y = ~n,
color = ~clarity) %>%
layout(xaxis = list(title = "Corte"),
yaxis = list(title = "Frequência absoluta (N)"))
bar
Bar chart with error bars
Exemplo
O banco de dados utilizado é o ToothGrowth. A resposta é o comprimento dos odontoblastos (células responsáveis pelo crescimento dos dentes) em 60 cobaias. Cada porquinho-da-índia recebeu um dos três níveis de dose de vitamina C (0,5, 1 e 2 mg/dia) por um dos dois métodos de entrega, suco de laranja ou ácido ascórbico. As variáveis são:
- Comprimento do dente
- Tipo de suplemento
- Dose
library(plyr)
data_mean <- ddply(ToothGrowth,
c("supp",
"dose"),
summarise,
length = mean(len))
data_sd <- ddply(ToothGrowth,
c("supp",
"dose"),
summarise,
length = sd(len))
vitamin <- data.frame(data_mean,
data_sd$length)
vitamin <- rename(vitamin,
c("data_sd.length" = "sd"))
vitamin$dose <- as.factor(vitamin$dose)
head(vitamin)
## supp dose length sd
## 1 OJ 0.5 13.23 4.459709
## 2 OJ 1 22.70 3.910953
## 3 OJ 2 26.06 2.655058
## 4 VC 0.5 7.98 2.746634
## 5 VC 1 16.77 2.515309
## 6 VC 2 26.14 4.797731
error <- plot_ly(data = vitamin[which(vitamin$supp == 'OJ'),],
x = ~dose,
y = ~length,
type = 'bar',
name = 'OJ',
error_y = ~list(array = sd,
color = '#000000')) %>%
add_trace(data = vitamin[which(vitamin$supp == 'VC'),],
name = 'VC') %>%
layout(xaxis = list(title = "Dose"),
yaxis = list(title = "Comprimento"))
error
Histogram
Exemplo
Duas variáveis aleatórias que seguem distribuição normal.
plot_ly(alpha = 0.6) %>%
add_histogram(x = ~rnorm(500)) %>%
add_histogram(x = ~rnorm(500) + 1) %>%
layout(barmode = "overlay")
Boxplots
Exemplo
Também usa o pacote diamonds.
head(diamonds)
## # A tibble: 6 x 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
## 4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
plot_ly(diamonds,
y = ~price,
color = ~cut,
type = "box")
Pie chart
Exemplo
O banco de dados é o USPersonalExpenditure. Este conjunto de dados consiste em despesas pessoais dos Estados Unidos (em bilhões de dólares) para os anos de 1940, 1945, 1950, 1955 e 1960 nas categorias:
- comida e tabaco,
- operação doméstica,
- medicina e saúde,
- cuidados pessoais e
- educação privada.
USPersonalExpenditure <- data.frame("Categorie" = rownames(USPersonalExpenditure),
USPersonalExpenditure)
data.pie <- USPersonalExpenditure[, c('Categorie',
'X1960')]
head(data.pie)
## Categorie X1960
## Food and Tobacco Food and Tobacco 86.80
## Household Operation Household Operation 46.20
## Medical and Health Medical and Health 21.10
## Personal Care Personal Care 5.40
## Private Education Private Education 3.64
colors <- c('rgb(211,94,96)',
'rgb(128,133,133)',
'rgb(144,103,167)',
'rgb(171,104,87)',
'rgb(114,147,203)')
pie <- plot_ly(data.pie,
labels = ~Categorie,
values = ~X1960,
type = 'pie',
textposition = 'inside',
textinfo = 'label+percent',
insidetextfont = list(color = '#FFFFFF'),
hoverinfo = 'text',
text = ~paste('$',
X1960,
' billions'),
marker = list(colors = colors,
line = list(color = '#FFFFFF',
width = 1)),
showlegend = FALSE) %>%
layout(title = 'United States Personal Expenditures by Categories in 1960',
xaxis = list(showgrid = FALSE,
zeroline = FALSE,
showticklabels = FALSE),
yaxis = list(showgrid = FALSE,
zeroline = FALSE,
showticklabels = FALSE))
pie
Bubble chart
Exemplo
O banco de dados é do github e ele contém 4 variáveis:
- Universidades americanas
- Salário de homens
- Salário de mulheres
- Diferença entre o salário de homens e mulheres
data.bubble <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/school_earnings.csv")
head(data.bubble)
## School Women Men Gap
## 1 MIT 94 152 58
## 2 Stanford 96 151 55
## 3 Harvard 112 165 53
## 4 U.Penn 92 141 49
## 5 Princeton 90 137 47
## 6 Chicago 78 118 40
bubble <- plot_ly(data.bubble,
x = ~Women,
y = ~Men,
text = ~School,
type = 'scatter',
mode = 'markers',
marker = list(size = ~Gap,
opacity = 0.5)) %>%
layout(title = 'Gender Gap in Earnings per University',
xaxis = list(showgrid = FALSE),
yaxis = list(showgrid = FALSE))
bubble
Gráficos diferentes
Sunburst chart
Exemplo
Os bancos de dados são do github e ambos são a respeito de sabores de café, sendo o segundo banco mais completo que o primeiro. As variáveis são:
- Ids
- Labels
- Parents
d1 <- read.csv('https://raw.githubusercontent.com/plotly/datasets/master/coffee-flavors.csv')
head(d1)
## ids labels parents
## 1 Enzymatic-Flowery Flowery
## 2 Enzymatic-Fruity Fruity
## 3 Enzymatic-Herby Herby
## 4 Sugar Browning-Nutty Nutty
## 5 Sugar Browning-Carmelly Carmelly
## 6 Sugar Browning-Chocolatey Chocolatey
d2 <- read.csv('https://raw.githubusercontent.com/plotly/datasets/718417069ead87650b90472464c7565dc8c2cb1c/sunburst-coffee-flavors-complete.csv')
head(d2)
## ids labels parents
## 1 Aromas Aromas
## 2 Tastes Tastes
## 3 Aromas-Enzymatic Enzymatic Aromas
## 4 Aromas-Sugar Browning Sugar Browning Aromas
## 5 Aromas-Dry Distillation Dry Distillation Aromas
## 6 Tastes-Bitter Bitter Tastes
sunburst <- plot_ly() %>%
add_trace(ids = d1$ids,
labels = d1$labels,
parents = d1$parents,
type = 'sunburst',
maxdepth = 2,
domain = list(column = 0)) %>%
add_trace(ids = d2$ids,
labels = d2$labels,
parents = d2$parents,
type = 'sunburst',
maxdepth = 3,
domain = list(column = 1)) %>%
layout(grid = list(columns = 2,
rows = 1),
margin = list(l = 0,
r = 0,
b = 0,
t = 0),
sunburstcolorway = c("#636efa","#EF553B","#00cc96","#ab63fa","#19d3f3",
"#e763fa", "#FECB52","#FFA15A","#FF6692","#B6E880"),
extendsunburstcolors = TRUE)
sunburst
Dumbbell plot
Exemplo
O banco de dados é o mesmo utilizado anteriormente, relacionado às universidades.
Data.dumbbell <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/school_earnings.csv")
Data.dumbbell$School <- factor(Data.dumbbell$School,
levels = Data.dumbbell$School[order(Data.dumbbell$Men)])
head(Data.dumbbell)
## School Women Men Gap
## 1 MIT 94 152 58
## 2 Stanford 96 151 55
## 3 Harvard 112 165 53
## 4 U.Penn 92 141 49
## 5 Princeton 90 137 47
## 6 Chicago 78 118 40
Dumbbell <- plot_ly(Data.dumbbell,
color = I("gray80")) %>%
add_segments(x = ~Women,
xend = ~Men,
y = ~School,
yend = ~School,
showlegend = FALSE) %>%
add_markers(x = ~Women,
y = ~School,
name = "Women",
color = I("pink")) %>%
add_markers(x = ~Men,
y = ~School,
name = "Men",
color = I("blue")) %>%
layout(title = "Gender earnings disparity",
xaxis = list(title = "Annual Salary (in thousands)"),
margin = list(l = 65))
Dumbbell
3D Scatter plot
Exemplo
O banco utilizado é o mtcars. Os dados foram extraídos da revista Motor Trend US de 1974 e abrangem o consumo de combustível e 10 aspectos do design e desempenho do automóvel para 32 automóveis. As variáveis são:
- Milhas/galão
- Número de cilindros
- Deslocamento
- Potência bruta
- Relação do eixo traseiro
- Peso
- 1/4 de milha
- Tipo de motor
- Transmissão
- Número de marchas para frente
- Modelo do carro
- Montadora
mtcars$am[which(mtcars$am == 0)] <- 'Automatic'
mtcars$am[which(mtcars$am == 1)] <- 'Manual'
mtcars$am <- as.factor(mtcars$am)
head(mtcars)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 Manual 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 Manual 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 Manual 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 Automatic 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 Automatic 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 Automatic 3 1
Scatter3D <- plot_ly(mtcars,
x = ~wt,
y = ~hp,
z = ~qsec,
color = ~am,
colors = c('#BF382A',
'#0C4B8E')) %>%
add_markers() %>%
layout(scene = list(xaxis = list(title = 'Weight'),
yaxis = list(title = 'Gross horsepower'),
zaxis = list(title = '1/4 mile time')))
Scatter3D
3D Surface Plot
Exemplo
Fazer uma pirâmide de base triangular.
Surface <- plot_ly(x = c(0, 1, 2, 0),
y = c(0, 0, 1, 2),
z = c(0, 2, 0, 1),
i = c(0, 0, 0, 1),
j = c(1, 2, 3, 2),
k = c(2, 3, 1, 3),
facecolor = toRGB(viridisLite::viridis(4)))
Surface
Mapas usando plotly
Choropleth map
Exemplo
O banco de dados utilizado é do Githube e ele contém as variáveis de todos os países em 2014:
- País
- PIB (em bilhões de dólares)
- Sigla do país
Data.choropleth <- read.csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
head(Data.choropleth)
## COUNTRY GDP..BILLIONS. CODE
## 1 Afghanistan 21.71 AFG
## 2 Albania 13.40 ALB
## 3 Algeria 227.80 DZA
## 4 American Samoa 0.75 ASM
## 5 Andorra 4.80 AND
## 6 Angola 131.40 AGO
l <- list(color = toRGB("grey"),
width = 0.5)
g <- list(showframe = FALSE,
showcoastlines = FALSE,
projection = list(type = 'Mercator'))
Choropleth <- plot_geo(Data.choropleth) %>%
add_trace(z = ~GDP..BILLIONS.,
color = ~GDP..BILLIONS.,
colors = 'Blues',
text = ~COUNTRY,
locations = ~CODE,
marker = list(line = l)) %>%
colorbar(title = 'GDP Billions US$',
tickprefix = '$') %>%
layout(title = '2014 Global GDP<br>Source:<ahref="https://www.cia.gov/library/publications/the-world-factbook/fields/2195.html">CIA World Factbook</a>',
geo = g)
Choropleth
Bubble Map
Exemplo
O banco de dados utilizado é do Githube e ele contém as variáveis de todos as cidades dos EUA em 2014:
- Nome da cidade
- População
- Latitude
- Longitude
- Quantile
Data.bmap <- read.csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_us_cities.csv')
Data.bmap$q <- with(Data.bmap,
cut(pop,
quantile(pop)))
levels(Data.bmap$q) <- paste(c("1st",
"2nd",
"3rd",
"4th",
"5th"),
"Quantile")
Data.bmap$q <- as.ordered(Data.bmap$q)
head(Data.bmap)
## name pop lat lon q
## 1 New York 8287238 40.73060 -73.98658 4th Quantile
## 2 Los Angeles 3826423 34.05372 -118.24273 4th Quantile
## 3 Chicago 2705627 41.87555 -87.62442 4th Quantile
## 4 Houston 2129784 29.75894 -95.36770 4th Quantile
## 5 Philadelphia 1539313 39.95233 -75.16379 4th Quantile
## 6 Phoenix 1465114 33.44677 -112.07567 4th Quantile
g <- list(scope = 'usa',
projection = list(type = 'albers usa'),
showland = TRUE,
landcolor = toRGB("gray85"),
subunitwidth = 1,
countrywidth = 1,
subunitcolor = toRGB("white"),
countrycolor = toRGB("white"))
Bubble.map <- plot_geo(Data.bmap,
locationmode = 'USA-states',
sizes = c(1, 250)) %>%
add_markers(x = ~lon,
y = ~lat,
size = ~pop,
color = ~q,
hoverinfo = "text",
text = ~paste(Data.bmap$name, "<br />",
Data.bmap$pop/1e6,
" million")) %>%
layout(title = '2014 US city populations<br>(Click legend to toggle)',
geo = g)
Bubble.map
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
## Warning: `line.width` does not currently support multiple values.
Gráficos animados no plotly
Exemplo: Gráfico de bolhas
Banco de dados
O pacote “gapminder” é um trecho dos dados disponíveis em https://www.gapminder.org/. Para cada um dos 142 países, o pacote fornece valores para expectativa de vida, PIB per capita e população, a cada cinco anos, de 1952 a 2007.
library(gapminder)
Banco.de.dados <- gapminder
head(Banco.de.dados)
## # A tibble: 6 x 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Afghanistan Asia 1952 28.8 8425333 779.
## 2 Afghanistan Asia 1957 30.3 9240934 821.
## 3 Afghanistan Asia 1962 32.0 10267083 853.
## 4 Afghanistan Asia 1967 34.0 11537966 836.
## 5 Afghanistan Asia 1972 36.1 13079460 740.
## 6 Afghanistan Asia 1977 38.4 14880372 786.
Objetivo
O objetivo é fazer um gráfico que contenha todas as informções desse banco de dados.
figura <- Banco.de.dados %>%
plot_ly(x = ~gdpPercap,
y = ~lifeExp,
size = ~pop,
color = ~continent,
frame = ~year,
text = ~country,
hoverinfo = "text",
type = 'scatter',
mode = 'markers') %>%
layout(xaxis = list(type = "log",
title = "PIB per capita"),
yaxis = list(title = "Expectativa de vida"))
figura
animation_opts
- frame: a quantidade de tempo entre os quadros (em milissegundos). Observe que esse valor deve incluir a transição.
- transition: a duração da transição suave entre os quadros (em milissegundos).
- easing: O tipo de atenuação da transição. Veja a lista de opções aqui https://github.com/plotly/plotly.js/blob/master/src/plots/animation_attributes.js
figura2 <- figura %>%
animation_opts(frame = 1000,
easing = 'sin')
figura2
animation_button
- xanchor: posição no eixo x
- yanchor: posição no eixo y
figura3 <- figura2 %>%
animation_button(x = 1,
xanchor = "right",
y = 0,
yanchor = "bottom")
figura3
animation_slider
- currentvalue: sinalizar o tempo que está durante a animação.
- hide: esconder a barra do tempo.
figura4 <- figura3 %>%
animation_slider(currentvalue = list(prefix = "YEAR ",
font = list(color="red")))
figura4
Exemplo: gráfico de linhas
Banco de dados
O banco de dados é o txhousing. Ele contém informações sobre o mercado imobiliário no Texas fornecidas pelo centro imobiliário TAMU, http://recenter.tamu.edu/. As variáveis são:
- Cidade
- Data
- Mês
- Ano
- Número de vendas
- Valor total de vendas
- Preço médio de venda
- Total de listagens ativas
- Quantidade de tempo que levaria para vender todas as listagens atuais no ritmo atual de vendas
library(plotly)
accumulate_by <- function(dat, var) {
var <- lazyeval::f_eval(var, dat)
lvls <- plotly:::getLevels(var)
dats <- lapply(seq_along(lvls), function(x) {
cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]])
})
dplyr::bind_rows(dats)
}
Data.txhousing <- txhousing %>%
filter(year > 2005,
city %in% c("Abilene", "Bay Area")) %>%
accumulate_by(~date)
head(Data.txhousing)
## city year month sales volume median listings inventory date
## 1 Abilene 2006 1 107 11890000 90800 559 3.4 2006.000
## 2 Bay Area 2006 1 367 58297417 133100 3038 5.7 2006.000
## 3 Abilene 2006 1 107 11890000 90800 559 3.4 2006.000
## 4 Abilene 2006 2 152 16875000 98200 561 3.4 2006.083
## 5 Bay Area 2006 1 367 58297417 133100 3038 5.7 2006.000
## 6 Bay Area 2006 2 471 77665581 138900 3157 5.8 2006.083
## frame
## 1 2006.000
## 2 2006.000
## 3 2006.083
## 4 2006.083
## 5 2006.083
## 6 2006.083
Gráfico final
fig <- Data.txhousing %>%
plot_ly(x = ~date,
y = ~median,
split = ~city,
frame = ~frame,
type = 'scatter',
mode = 'lines',
line = list(simplyfy = F)) %>%
layout(xaxis = list(title = "Date",
zeroline = F),
yaxis = list(title = "Median",
zeroline = F)) %>%
animation_opts(frame = 100,
transition = 0,
redraw = FALSE) %>%
animation_slider(hide = T) %>%
animation_button(x = 1,
xanchor = "right",
y = 0,
yanchor = "bottom")
fig
Podemos usar o plotly com o ggplot para tornar a visualização de dados interativa. Os gráficos saem do jeito que você já conhece no ggplot com algumas opções oferecidas pelo plotly.
Você pode ler mais sobre o pacote no site do plotly ou então já partir para o código no R usando essa folha de atalhos com os gráficos mais usados.