library(plotly)
## Loading required package: ggplot2
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Los Boxplots o Diagramas de caja son gráficos que resumen datos numéricos. Son útiles para comparar varias distribuciones numéricas de manera visual. Aunque son fáciles de comparar, a veces no pueden mostrar distribuciones complejas, como las multimodales.
La función add_boxplot() se usa para crear estos
gráficos y asegura que estén correctamente orientados,
independientemente de si los datos están en el eje x o y. En el eje
perpendicular al eje de los datos, puedes usar una variable discreta
para condicionar o simplemente proporcionar un nombre a la categoría del
eje.
p <- plot_ly(diamonds, y = ~price, color = I("black"),
alpha = 0.1, boxpoints = "suspectedoutliers")
p1 <- p %>% add_boxplot(x = "Overall")
p2 <- p %>% add_boxplot(x = ~cut)
subplot(
p1, p2, shareY = TRUE,
widths = c(0.2, 0.8), margin = 0
) %>% hide_legend()
FIGURA 6.1: Precio global del diamante y precio por talla.
Se puede particionar por más de una variable discreta, podría utilizar la interacción de esas variables con el eje discreto, y colorear por la variable anidada. De igual manera, es posible utilizar una visualización enrejada.
plot_ly(diamonds, x = ~price, y = ~interaction(clarity, cut)) %>%
add_boxplot(color = ~clarity) %>%
layout(yaxis = list(title = ""))
FIGURA 6.2: Precios de los diamantes por talla y claridad.
Ordenar los boxplots según un criterio significativo, como el precio mediano, también resulta beneficioso. La Figura 6.3 ilustra la misma información que la Figura 6.2, pero dispone los boxplots en función de su mediana, lo que de manera inmediata resalta que los diamantes con un corte clasificado como “SI2” presentan el precio promedio más alto.
d <- diamonds %>%
mutate(cc = interaction(clarity, cut))
# interaction levels sorted by median price
lvls <- d %>%
group_by(cc) %>%
summarise(m = median(price)) %>%
arrange(m) %>%
pull(cc)
plot_ly(d, x = ~price, y = ~factor(cc, lvls)) %>%
add_boxplot(color = ~clarity) %>%
layout(yaxis = list(title = ""))
FIGURA 6.3: Precios de los diamantes por talla y claridad, ordenados por mediana de precios.
Al igual que ocurre con add_histogram(), la función
add_boxplot() transmite los datos en su forma original al
navegador y delega en plotly.js el cálculo de estadísticas resumidas.
Desafortunadamente, en el caso de los boxplots, plotly.js
aún no permite utilizar estadísticas previamente calculadas.
El paquete Plotly proporciona dos funciones para
representar áreas rectangulares llamadas bins:
add_heatmap() y add_histogram2d(). Cuando se
trata de datos numéricos, add_heatmap() es como una versión
en 2D de add_bars() (requiere que los bins estén
previamente calculados), mientras que add_histogram2d()
funciona como una versión en 2D de add_histogram() (calcula
los bins directamente en el navegador). Por lo tanto, para tareas de
exploración, se sugiere utilizar add_histogram2d ya que no
es necesario preocuparse por cómo se hacen los bins. Esta función
también cuenta con una característica útil llamada
zsmooth que permite aumentar efectivamente
la cantidad de bins y brinda la posibilidad de configurar el número de
bins en las direcciones x e y. Además, es importante señalar que en
cualquiera de estos casos, en lugar de usar bins, se pueden emplear
contornos rellenos utilizando add_histogram2dcontour() en
lugar de add_histogram2d().
p <- plot_ly(diamonds, x = ~log(carat), y = ~log(price))
subplot(
add_histogram2d(p) %>%
colorbar(title = "default") %>%
layout(xaxis = list(title = "default")),
add_histogram2d(p, zsmooth = "best") %>%
colorbar(title = "zsmooth") %>%
layout(xaxis = list(title = "zsmooth")),
add_histogram2d(p, nbinsx = 60, nbinsy = 60) %>%
colorbar(title = "nbins") %>%
layout(xaxis = list(title = "nbins")),
shareY = TRUE, titleX = TRUE
)
FIGURA 7.1: Tres usos diferentes de histogram2d().
En la sección 5 acerca de barras e
histogramas, se destacó que calcular el número ideal de
“bins” en un contexto bidimensional es más complicado que en una
dimensión. Existe una carencia sorprendente de investigaciones y
herramientas computacionales para abordar esta cuestión, y en muchos
casos se recurre a asumir una forma de distribución gaussiana, lo cual
no siempre es práctico. En lugar de esta aproximación, se recomienda
utilizar la estimación de densidad kernel en 2D, que tiende a ser más
resistente a variaciones en la forma de la distribución. Un enfoque
confiable para estimar el ancho de banda de una densidad kernel
gaussiana en 2D es emplear la función kde2d() del paquete
MASS. Esta función permite estimar la densidad en 2D y
representarla visualmente como un mapa de calor utilizando la función
add_heatmap().
kde_count <- function(x, y, ...) {
kde <- MASS::kde2d(x, y, ...)
df <- with(kde, setNames(expand.grid(x, y), c("x", "y")))
# The 'z' returned by kde2d() is a proportion,
# but we can scale it to a count
df$count <- with(kde, c(z) * length(x) * diff(x)[1] * diff(y)[1])
data.frame(df)
}
kd <- with(diamonds, kde_count(log(carat), log(price), n = 30))
plot_ly(kd, x = ~x, y = ~y, z = ~count) %>%
add_heatmap() %>%
colorbar(title = "Número de diamantes")
FIGURA 7.2: Estimación de la densidad 2D mediante la función kde2d().
Las funciones add_histogram2d(),
add_histogram2dcontour() y add_heatmap() son
compatibles con ejes categóricos. Aunque add_histogram2d()
puede utilizarse para mostrar tablas de contingencia bidireccionales, se
recomienda crear gráficos de barras agrupadas para facilitar la
comparación de valores en lugar de basarse en la diferenciación de
colores, como sugiere Cleveland y McGill en 1984. No obstante,
add_heatmap() sigue siendo útil para ejes categóricos, ya
que permite mostrar cualquier cantidad deseada en el eje z mediante la
variación de colores.
En la Figura 7.3, se utiliza
add_heatmap() para presentar una matriz de correlación, y
se destaca cómo los parámetros “limits” en la función
“colorbar()” pueden ser utilizados para ampliar los límites
de la escala de colores y reflejar el rango de correlaciones posibles,
algo que no es fácil de lograr en plotly.js.
corr <- cor(dplyr::select_if(diamonds, is.numeric))
plot_ly(colors = "RdBu") %>%
add_heatmap(x = rownames(corr), y = colnames(corr), z = corr) %>%
colorbar(limits = c(-1, 1))
FIGURA 7.3: Visualización de una matriz de correlación con add_heatmap() y control de los límites de escala con colorbar().