Gráfico de puntos en R

Crea gráficos de puntos en R

Un diagrama de puntos o gráfico de puntos es similar a un diagrama de dispersión. La principal diferencia es que el gráfico de puntos en R muestra el índice (cada categoría) en el eje vertical y el valor correspondiente en el eje horizontal, por lo que puedes ver el valor de cada observación siguiendo una línea horizontal desde la etiqueta correspondiente.

El gráfico de puntos en R se puede utilizar como alternativa a los gráficos de barras horizontales. Además, puedes etiquetar los puntos correspondientes en el eje vertical en diferentes grupos e incluso ordenarlos en función de alguna variable.

Ten en cuenta que hay varios tipos de gráficos de puntos. En este tutorial mostraremos cómo crear dot plots de Cleveland y de Dumbbell.

La función dotchart

La función dotchart permite crear un diagrama de puntos de Cleveland en R. Considera el siguiente conjunto de datos, que representa las ventas esperadas y reales de una empresa para cada mes.

set.seed(1)

mes <- month.name
esperado <- c(15, 16, 20, 31, 11, 6,
              17, 22, 32, 12, 19, 20)
vendido <- c(8, 18, 12, 10, 41, 2,
          19, 26, 14, 16, 9, 13)
trimestre <- c(rep(1, 3), rep(2, 3), rep(3, 3), rep(4, 3))

datos <- data.frame(mes, esperado, vendido, trimestre)
datos
         mes esperado vendido trimestre
1    January       15      8       1
2   February       16     18       1
3      March       20     12       1
4      April       31     10       2
5        May       11     41       2
6       June        6      2       2
7       July       17     19       3
8     August       22     26       3
9  September       32     14       3
10   October       12     16       4
11  November       19      9       4
12  December       20     13       4

Puedes crear un gráfico de puntos en R de la variable vendido pasándola a la función dotchart. También puedes etiquetar cada observación con el argumento labels y especificar argumentos adicionales, como el símbolo, el tamaño del símbolo o el color del símbolo con los argumentos, pch, bg y pt.cex, respectivamente.

dotchart(datos$vendido, labels = datos$mes, pch = 21, bg = "green", pt.cex = 1.5)

Gráfico de puntos simple

Gráfico de puntos por grupo en R

Si tienes una variable que clasifique los datos en grupos, puedes separar el gráfico de puntos en esos grupos, pasándolos al argumento labels. También puedes especificar colores para cada grupo si así lo deseas, especificándolos en el argumento color.

# Grupos
colores <- numeric(4)
colores[trimestre == "1"] <- "red"
colores[trimestre == "2"] <- "blue"
colores[trimestre == "3"] <- "green"
colores[trimestre == "4"] <- "orange"

dotchart(datos$esperado, labels = datos$mes, pch = 19,
         pt.cex = 1.5, groups = rev(datos$trimestre), color = colores)

Gráfico de puntos con la función dotplot basado en grupos

Ordenar el gráfico de puntos por una variable

Además, puedes ordenar un dotchart en R por una variable si previamente ordenas los datos. Para ello puedes escribir:

x <- datos[order(datos$esperado), ] 

dotchart(x$esperado, labels = x$mes, pch = 19,
         xlim = range(x$esperado, x$vendido) + c(-2, 2),
         pt.cex = 1.5, color = colors, groups = rev(datos$trimestre))

Dotplot con la variable ordenada

Gráfico de dumbbell en R

A veces resulta interesante crear un gráfico de puntos con dos variables, que representen los valores mínimos y máximos de algunos eventos o el cambio de algunas observaciones en el tiempo.

En nuestro ejemplo, podría ser interesante representar las variables vendido y esperado juntas, para analizar la diferencia entre las ventas esperadas y las reales. Este tipo de gráficos de puntos se conocen como gráficos de Dumbbell.

dotchart(datos$sold, pch = 21, labels = datos$mes, bg = "green",
         pt.cex = 1.5, xlim = range(datos$esperado, datos$vendido) + c(-2, 2))
points(datos$esperado, 1:nrow(datos), col = "red", pch = 19, cex = 1.5)

Gráfico de puntos con mínimo y máximo

También puedes agregar segmentos y textos para etiquetar los puntos de la siguiente manera:

dotchart(datos$vendido, labels = datos$mes, pch = 21, bg = "green",
         xlim = range(datos$esperado, datos$vendido) + c(-2, 2),
         pt.cex = 1.5)

points(datos$esperado, 1:nrow(datos), col = "red", pch = 19, cex = 1.5)

invisible(sapply(1:nrow(datos), function(i) {
  segments(min(datos$vendido[i], datos$esperado[i]), i,
           max(datos$vendido[i], datos$esperado[i]), i, lwd = 2)
  text(min(datos$sold[i], datos$esperado[i]) - 1.5, i,
       labels = min(datos$vendido[i], datos$esperado[i]))
  text(max(datos$vendido[i], datos$esperado[i]) + 1.5, i,
       labels = max(datos$vendido[i], datos$esperado[i]))
}))

points(datos$esperado, 1:nrow(datos), col = "red",
       pch = 19, cex = 1.5)
points(datos$vendido, 1:nrow(datos), col = "red",
       pch = 21, bg = "green", cex = 1.5)

Gráfico de puntos en R con la función dumbbell

Sin embargo, lo anterior no es fácil de manejar y no se puede usar cuando especificas grupos. Como no existe ninguna alternativa gráfica en R que permita esta funcionalidad, hemos desarrollado la función dumbbell, que funciona con datos agrupados y no agrupados. Los argumentos permiten especificar si quieres agregar los segmentos, el texto, ambos o solo los puntos y además personalizar el diagrama a tu gusto con argumentos adicionales.

# v1: variable numérica
# v2: variable numérica
# group: vector (numérico o caracter) o factor que contenga grupos
# labels: etiquetas para el eje Y
# segments: añadir segmentos (TRUE) o no (FALSE)
# text: añadir textos (TRUE) o no (FALSE)
# pch: símbolo
# col1: color de la variable v1. Si quieres
# añadir colores para grupos añádelos aquí
# col1: color de la variable v2
# pt.cex: tamaño de los puntos
# segcol: color de los segmentos
# lwd: ancho de los segmentos
# ... : argumentos adicionales para pasar a la función dotchart

dumbbell <- function(v1, v2, group = rep(1, length(v1)), labels = NULL,
                     segments = FALSE, text = FALSE, pch = 19,
                     colv1 = 1, colv2 = 1, pt.cex = 1, segcol = 1,
                     lwd = 1, ...) {

  o <- sort.list(as.numeric(group), decreasing = TRUE)
  group <- group[o]
  offset <- cumsum(c(0, diff(as.numeric(group)) != 0))
  y <- 1L:length(v1) + 2 * offset
  
  dotchart(v1, labels = labels, color = colv1, xlim = range(v1, v2) + c(-2, 2),
           groups = group, pch = pch, pt.cex = pt.cex)
  
  if(segments == TRUE) {
    for(i in 1:length(v1)) {
      segments(min(v2[i], v1[i]), y[i],
               max(v2[i], v1[i]), y[i],
               lwd = lwd, col = segcol) 
    }
  }
  
  for(i in 1:length(v1)){
    points(v2[i], y[i], pch = pch, cex = pt.cex, col = colv2)
    points(v1[i], y[i], pch = pch, cex = pt.cex, col = colv1)
  }
  
  if(text == TRUE) {
    for(i in 1:length(v1)) {
      text(min(v2[i ], v1[i]) - 1.5, y[i],
           labels = min(v2[i], v1[i]))
      text(max(v2[i], v1[i]) + 1.5, y[i],
           labels = max(v2[i], v1[i])) 
    }
  }
}

Con esta función puedes crear varias combinaciones. Considera el ejemplo donde quieres mostrar la comparación entre ventas reales (azul) y ventas esperadas (negro) para cada mes. Para ello podrías escribir lo siguiente:

dumbbell(v1 = datos$esperado, v2 = datos$vendido, text = FALSE,
         labels = datos$mes, segments = TRUE, pch = 19,
         pt.cex = 1.5, colv1 = 1, colv2 = "blue")

Salida de la función dumbbell en R

Ahora, si prefieres dividir los datos en grupos y también agregar textos con cada valor, puedes escribir:

dumbbell(v1 = datos$esperado, v2 = datos$vendido, group = datos$trimestre,
         text = TRUE, labels = data$month, segments = TRUE, pch = 19,
         pt.cex = 1.5, colv1 = 1, colv2 = "blue")

Gráfico de Dumbbell por grupos

Además, si quieres agregar colores para cada grupo, puedes usar el argumento colv1.

dumbbell(v1 = datos$esperado, v2 = datos$vendido, group = datos$trimestre,
         text = TRUE, labels = datos$mes, segments = TRUE,
         pch = 19, pt.cex = 1.5, colv1 = colores)

Gráfico de puntos de Dumbbell coloreado por grupos

Finalmente, como hicimos en la sección anterior, también puedes ordenar los datos para alguna variable:

x <- datos[order(datos$esperado), ] 

dumbbell(v1 = x$esperado, v2 = x$vendido, group = datos$trimestre,
         text = TRUE, segcol = "gray", lwd = 3, labels = x$mes,
         segments = TRUE, pch = 19, pt.cex = 1.5, colv1 = 1, colv2 = "blue")

Gráfico de Dumbbell ordenado por una variable

Observa que los puntos negros están ordenados en orden creciente.