Esquemas Avanzados
Introducción
Existe varios paquetes en R
exclusivos para generar gráficos estadÃsticos, asà como existen paquetes de análisis de datos en los cuales los desarrolladores personalizan sus gráficos utilizando base
u otros paquetes de graficación. En este módulo veremos algunos de estos paquetes para este fin.
ggplot
El paquete ggplot2
es un sistema declarativo para construir gráficos basado en el libro The Grammar of Graphics. Hace parte de la colección tidyverse
diseñado para Data Science, la cual es una modificación del legueje R
con la filosofÃa de hacer más simple la programación y la lectura de código.
Para graficar con este paquete se requiere establecer qué es lo que se quiere graficar, es decir, cuáles argumentos y papel son los que se quiere visualizar. Luego se agregan las funciones geom
que transforma los datos y genera los gráficos por capas.
Para agregar los argumentos se utiliza el comando aes
que recibe las variables que se quieren graficar y el papel estético que cumple.
Para especificar el gráfico que se quiere, se utiliza la baterÃa geom
precedido de +
.
En la página de referencia de ggplot pueden encontrar todas las capas disponibles en el paquete.
ggplot(mtcars,aes(x=mpg,y=disp,colour=drat))+
geom_point(aes(size=hp))+
ggtitle("Desplazamientos vs Consumo\ndado los caballos de fuerza y eje trasero")+
theme_bw()
ggplot(mtcars,aes(x=mpg,y=disp,colour=drat))+
geom_point(aes(size=hp))+
ggtitle("Desplazamientos vs Consumo\ndado los caballos de fuerza y eje trasero")+
theme_bw()+scale_color_gradient(low=c("red","gold"),high = c("forestgreen"))
ggplot(mtcars,aes(x=mpg,y=disp,colour=drat))+
geom_point(aes(size=hp))+geom_smooth()+
ggtitle("Desplazamientos vs Consumo\ndado los caballos de fuerza y eje trasero")+
theme_bw()+scale_color_gradient(low=c("red","gold"),high = c("forestgreen"))
set.seed(1234)
wdata = data.frame(
sex = factor(rep(c("F", "M"), each=200)),
weight = c(rnorm(200, 55), rnorm(200, 58)))
head(wdata)
# Box-plot básico desde el data.frame
qplot(sex, weight, data = wdata,
geom= "boxplot", fill = sex)
# Dot plot
qplot(sex, weight, data = wdata, geom = "dotplot",
stackdir = "center", binaxis = "y", dotsize = 0.5)
# Density plot
# Color por grupo (sexo) cambiando el tipo de linea
qplot(weight, data = wdata, geom = "density",
color = sex, linetype = sex)
# Se puede asignar la base del gráfico a una variable
a <- ggplot(wdata, aes(x = weight))
# gráfico área
a + geom_area(stat = "bin")
# Media por grupos
# install.packages("plyr",dependencies = T)
library(plyr)
(mu <- ddply(wdata, "sex", summarise, grp.mean=mean(weight)))
# Agregar la media como lÃnea con color manual
a + geom_density(aes(color = sex)) +
geom_vline(data=mu, aes(xintercept=grp.mean, color=sex),
linetype="dashed") +
scale_color_manual(values=c("#999999", "#E69F00"))
# Color manual
a + geom_dotplot(aes(fill = sex)) +
scale_fill_manual(values=c("#999999", "#E69F00"))
Pueden consultar la GuÃa práctica ggplot2 que tiene una colección de gráficos ggplot2
y los códigos para replicarlos.
Gráficos interactivos
Este tipo de gráficos se emplean para aplicaciones web o dispositivos móviles. Existen varios paquetes en R
que integran los métodos de visualización del software con HTML
y JavaScript
.
plotly
Plot.ly es una empresa de computación técnica que ofrece soluciones gráficas para analÃtica, tienen sus propios software y productos, pero han contribuÃdo al mundo de código abierto con implementaciones en R
, Python
, JavaScript
, MATLAB
, Julia
o Scala
.
Si bien Plotly tiene una versión empresarial paga, realmente lo que se paga son la herramientas desarrolladas por la empresa para construir dashboards y gráficos de manera más interactiva sin la necesidad de códigos. Por fortuna, es posible crear gráficos interactivos con el paquete plotly
, los cuales se pueden guardar en .html
para agregarlos posteriormente a las páginas web o aplicaciones.
Los gráficos se construyen similar a ggplot2
agregando capas, y para guardar el archivo se emplea el comando api_create
, sin embargo, el archivo se guarda en la nube de Plotly. Para guardar el archivo como HTML
sin necesidad de subirlo a la nube se emplea el paquete htmlwidgets
.
plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length,
marker = list(size = 10,color = 'rgba(255, 182, 193, .9)',
line = list(color = 'rgba(152, 0, 0, .8)',
width = 2))) %>%
layout(title = 'Styled Scatter',
yaxis = list(zeroline = FALSE),
xaxis = list(zeroline = FALSE))
d <- diamonds[sample(nrow(diamonds), 1000), ]
plot_ly(d, x = ~carat, y = ~price,
color = ~carat, size = ~carat)
plot_ly(d, x = ~carat, y = ~price,
# Hover text:
text = ~paste("Price: ", price, '$<br>Cut:', cut),
color = ~carat, size = ~carat)
dens <- with(diamonds, tapply(price, INDEX = cut, density))
df <- data.frame(x = unlist(lapply(dens, "[[", "x")),
y = unlist(lapply(dens, "[[", "y")),
cut = rep(names(dens), each = length(dens[[1]]$x)))
p <- plot_ly(df, x = ~x, y = ~y, color = ~cut) %>%
add_lines()
# Con ggplot2
library(ggplot2)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
# Boxplot en ggplot
p <- ggplot(df, aes(cut, price, fill = cut)) +
geom_boxplot()+
ggtitle("Lineas horizonales en los bigotes (ggplot2)")
ggplotly(p)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,] 100 100 101 101 101 101 101 100 100 100 101 101 102 102
## [2,] 101 101 102 102 102 102 102 101 101 101 102 102 103 103
## [3,] 102 102 103 103 103 103 103 102 102 102 103 103 104 104
## [4,] 103 103 104 104 104 104 104 103 103 103 103 104 104 104
## [5,] 104 104 105 105 105 105 105 104 104 103 104 104 105 105
## [6,] 105 105 105 106 106 106 106 105 105 104 104 105 105 106
## [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
## [1,] 102 102 103 104 103 102 101 101 102 103 104 104
## [2,] 103 103 104 105 104 103 102 102 103 105 106 106
## [3,] 104 104 105 106 105 104 104 105 106 107 108 110
## [4,] 105 105 106 107 106 106 106 107 108 110 111 114
## [5,] 105 106 107 108 108 108 109 110 112 114 115 118
## [6,] 106 107 109 110 110 112 113 115 116 118 119 121
## [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35] [,36] [,37] [,38]
## [1,] 105 107 107 107 108 108 110 110 110 110 110 110
## [2,] 107 109 110 110 110 110 111 112 113 114 116 115
## [3,] 111 113 114 115 114 115 116 118 119 119 121 121
## [4,] 117 118 117 119 120 121 122 124 125 126 127 127
## [5,] 121 122 121 123 128 131 129 130 131 131 132 132
## [6,] 124 126 126 129 134 137 137 136 136 135 136 136
## [,39] [,40] [,41] [,42] [,43] [,44] [,45] [,46] [,47] [,48] [,49] [,50]
## [1,] 110 110 108 108 108 107 107 108 108 108 108 108
## [2,] 114 112 110 110 110 109 108 109 109 109 109 108
## [3,] 120 118 116 114 112 111 110 110 110 110 109 109
## [4,] 126 124 122 120 117 116 113 111 110 110 110 109
## [5,] 131 130 128 126 122 119 115 114 112 110 110 110
## [6,] 136 135 133 129 126 122 118 116 115 113 111 110
## [,51] [,52] [,53] [,54] [,55] [,56] [,57] [,58] [,59] [,60] [,61]
## [1,] 107 107 107 107 106 106 105 105 104 104 103
## [2,] 108 108 108 107 107 106 106 105 105 104 104
## [3,] 109 109 108 108 107 107 106 106 105 105 104
## [4,] 109 109 109 108 108 107 107 106 106 105 105
## [5,] 110 110 109 109 108 107 107 107 106 106 105
## [6,] 110 110 110 109 108 108 108 107 107 106 106
plot_ly(z = volcano, type = "contour", contours = list(showlabels = TRUE)) %>%
colorbar(title = "Elevation \n in meters")
# Gráficos en 3D
mtcars$am[which(mtcars$am == 0)] <- 'Automatic'
mtcars$am[which(mtcars$am == 1)] <- 'Manual'
mtcars$am <- as.factor(mtcars$am)
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')))
plot_ly(mtcars, x = ~wt, y = ~hp, z = ~qsec,
marker = list(color = ~mpg,
colorscale = c('#FFE1A1', '#683531'),
showscale = TRUE)) %>%
add_markers() %>%
layout(scene = list(xaxis = list(title = 'Weight'),
yaxis = list(title = 'Gross horsepower'),
zaxis = list(title = '1/4 mile time')),
annotations = list(x = 1.13,
y = 1.05,
text = 'Miles/(US) gallon',
xref = 'paper',
yref = 'paper',
showarrow = FALSE)
)
# Usando botones HTML
p <- plot_ly(z = ~volcano, type = "heatmap", colorscale='Rainbow')
# Botón para tipo de gráfico
chart_types <- list(
type = "buttons",
direction = "right",
xanchor = 'center',
yanchor = "top",
pad = list('r'= 0, 't'= 10, 'b' = 10),
x = 0.5,
y = 1.27,
buttons = list(
list(method = "restyle",
args = list("type", "heatmap"),
label = "Heatmap"),
list(method = "restyle",
args = list("type", "contour"),
label = "Contour"),
list(method = "restyle",
args = list("type", "surface"),
label = "Surface")
))
# Botón para tipo de color
color_types <- list(
type = "buttons",
direction = "right",
xanchor = 'center',
yanchor = "top",
pad = list('r'= 0, 't'= 10, 'b' = 10),
x = 0.5,
y = 1.17,
buttons = list(
list(method = "restyle",
args = list("colorscale", "Rainbow"),
label = "Rainbow"),
list(method = "restyle",
args = list("colorscale", "Jet"),
label = "Jet"),
list(method = "restyle",
args = list("colorscale", "Earth"),
label = "Earth"),
list(method = "restyle",
args = list("colorscale", "Electric"),
label = "Electric")
))
annot <- list(list(text = "Chart<br>Type", x=0.2, y=1.25, xref='paper', yref='paper', showarrow=FALSE),
list(text = "Color<br>Type", x=0.2, y=1.15, xref='paper', yref='paper', showarrow=FALSE))
# Resultado
p %>% layout(xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(chart_types,color_types),
annotations = annot)
# Animados
# install.packages("gapminder")
library(gapminder)
gapminder %>% 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"))
Para guardar los gráficos en HTML
se emplea el siguiente código.
Gifs en R
Para crea gifs animados es necesario instalar el paquete gganimate
desde el repositorio de GitHub.
# paquete para acceder a las librerÃas de GitHub
install.packages("devtools",dependencies = T)
# instalar paquetes de GitHub
devtools::install_github('thomasp85/gganimate',force = T)
# También está en el CRAN
install.packages("gganimate",dependencies = T)
La idea de los gift es visualizar paso por paso las capas de un gráfico, el paquete gganimate
es para construir este tipo de archivos para los gráficos construÃdos en ggplot2
.
library(gapminder)
library(ggplot2)
library(gganimate)
p <- ggplot(gapminder,
aes(x = gdpPercap, y = lifeExp,
size = pop, color = continent,
frame = year)) +
geom_point() +
scale_x_log10() +
theme_bw()+
transition_states(year)
# Realizar la animación
animate(p)
# Guardar el gif
anim_save("Mi_Animacion.gif")
Mapas interactivos
R
tiene la capacidad de hacer análisis geoestadÃsticos y de estadÃstica espacial de datos raster, areales o de patrones de puntos y existe una barterÃa amplia de paquetes para graficar mapas y resultados estáticos o interactivos.
Las librerÃas más utilizadas para graficar mapas estáticos son raster
, rasterVis
, cartogram
, tmap
y ggplot2
, por otra parte para los mapas interactivos basandos en HMTL
se cuenta con los paquetes leaflet
, rbokeh
, plotly
, ggiraph
, highcharter
, gganimate
, mapview
, mapdeck
, googleway
, entre otros.
install.packages("leaflet",dependencies = T)
install.packages("spData",dependencies = T)
install.packages("tmap",dependencies = T)
install.packages("ggiraph",dependencies = T)
install.packages("sf",dependencies = T)
install.packages("sp",dependencies = T)
install.packages("maps",dependencies = T)
install.packages("rbokeh",dependencies = T)
library(spData)
library(maps)
data(world.cities)
library(rbokeh)
caps <- dplyr::filter(world.cities, capital == 1)
caps$population <- prettyNum(caps$pop, big.mark = ",")
plot <- suppressWarnings(figure(width = 800, height = 450, padding_factor = 0) %>%
ly_map("world", col = "gray") %>%
ly_points(long, lat, data = caps, size = 5,
hover = c(name, country.etc, population)))
widgetframe::frameWidget(plot,width=600,height=400)
leaflet() %>%
setView(lat = 6.1999, lng = -75.5791, zoom=15) %>%
addTiles()%>%
addProviderTiles(providers$Stamen.Toner)
leaflet() %>%
setView(lat = 6.1999, lng = -75.5791, zoom=15) %>%
addTiles()%>%
addProviderTiles(providers$CartoDB.Positron)
leaflet() %>%
setView(lat = 6.1999, lng = -75.5791, zoom=15) %>%
addTiles()%>%
addProviderTiles(providers$MtbMap) %>%
addProviderTiles(providers$Stamen.TonerLines,
options = providerTileOptions(opacity = 0.35)) %>%
addProviderTiles(providers$Stamen.TonerLabels)
leaflet() %>% addTiles() %>% setView(-87.65, 38.0285, zoom = 6) %>%
addWMSTiles(
"http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
layers = "nexrad-n0r-900913",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "Weather data © 2012 IEM Nexrad"
)
df <- sp::SpatialPointsDataFrame(
cbind(
(runif(20) - .5) - 75.5, # lng
(runif(20) - .5) + 6.1 # lat
),
data.frame(type = factor(
ifelse(runif(20) > 0.75, "alto", "bajo"),
c("alto", "bajo")
))
)
leaflet(df) %>% addTiles() %>% addCircleMarkers()
pal <- colorFactor(c("navy", "red"), domain = c("bajo", "alto"))
leaflet(df) %>% addTiles() %>%
addCircleMarkers(
radius = ~ifelse(type == "alto", 6, 10),
color = ~pal(type),
stroke = FALSE, fillOpacity = 0.5
)
leaflet() %>%
addTiles() %>%
addTerminator(
resolution=10,
time = "2020-05-01T21:00:00Z",
group = "daylight") %>%
addLayersControl(
overlayGroups = "daylight",
options = layersControlOptions(collapsed = FALSE))
leaflet() %>% setView(-75,6,5) %>%
addProviderTiles(providers$Esri.WorldStreetMap) %>%
addMiniMap(
tiles = providers$Esri.WorldStreetMap,
toggleDisplay = TRUE)
pal = colorNumeric("RdYlBu", domain = cycle_hire$nbikes)
leaflet(data = cycle_hire) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircles(col = ~pal(nbikes), opacity = 0.9) %>%
addPolygons(data = lnd, fill = FALSE) %>%
addLegend(pal = pal, values = ~nbikes) %>%
setView(lng = -0.1, 51.5, zoom = 12) %>%
addMiniMap()