¿Cómo hacer gráficos de gofres en R?

11

¿Cómo puedo trazar un gráfico de gofres como alternativa al uso de gráficos circulares en R?

help.search("waffle")
No help files found with alias or concept or title matching waffle
using fuzzy matching.

Lo más cercano que encontré buscando en Google son los mosaicos.

719016
fuente
No lo sé, pero ¿por qué no usar un método mejor? Los gráficos de puntos son mucho mejores.
Peter Flom - Restablece a Monica
2
Para aquellos que quieran saber qué son los gofres, Robert Kosara en el blog Eager Eyes tiene un artículo sobre ellos. Tome nota de los comentarios de Jon Peltier también.
Andy W
Lo más cercano que pude encontrar es esto . FWIW, estoy de acuerdo con Peter, evito pasteles y gofres cuando visualizo datos.

Respuestas:

13

Ahora hay un paquete llamado waffle .

Ejemplo de la página de github:

parts <- c(80, 30, 20, 10)
waffle(parts, rows=8)

Resultado:

resultado

Saludos

jbkunst
fuente
No sabía que se llamaban "gráficos de gofres". Me gustan - buen reemplazo del gráfico circular
shadowtalker
7

Sospecho que geom_tiledesde el paquete ggplot2puedes hacer lo que estás buscando. La respuesta de Shane sobre esta pregunta de StackOverflow debería ayudarlo a comenzar.

Editar: Aquí hay un ejemplo, con algunas otras parcelas para comparar.

library(ggplot2)

# Here's some data I had lying around
tb <- structure(list(region = c("Africa", "Asia", "Latin America", 
"Other", "US-born"), ncases = c(36L, 34L, 56L, 2L, 44L)), .Names = c("region", 
"ncases"), row.names = c(NA, -5L), class = "data.frame")


# A bar chart of counts
ggplot(tb, aes(x = region, weight = ncases, fill = region)) +
    geom_bar()

# Pie chart.  Forgive me, Hadley, for I must sin.
ggplot(tb, aes(x = factor(1), weight = ncases, fill = region)) +
    geom_bar(width = 1) +
    coord_polar(theta = "y") +
    labs(x = "", y = "")

# Percentage pie.
ggplot(tb, aes(x = factor(1), weight = ncases/sum(ncases), fill = region)) +
    geom_bar() +
    scale_y_continuous(formatter = 'percent') +
    coord_polar(theta = "y") +
    labs(x = "", y = "")


# Waffles
# How many rows do you want the y axis to have?
ndeep <- 5

# I need to convert my data into a data.frame with uniquely-specified x
# and y coordinates for each case
# Note - it's actually important to specify y first for a
# horizontally-accumulating waffle
# One y for each row; then divide the total number of cases by the number of
# rows and round up to get the appropriate number of x increments
tb4waffles <- expand.grid(y = 1:ndeep,
                          x = seq_len(ceiling(sum(tb$ncases) / ndeep)))

# Expand the counts into a full vector of region labels - i.e., de-aggregate
regionvec <- rep(tb$region, tb$ncases)

# Depending on the value of ndeep, there might be more spots on the x-y grid
# than there are cases - so fill those with NA
tb4waffles$region <- c(regionvec, rep(NA, nrow(tb4waffles) - length(regionvec)))

# Plot it
ggplot(tb4waffles, aes(x = x, y = y, fill = region)) + 
    geom_tile(color = "white") + # The color of the lines between tiles
    scale_fill_manual("Region of Birth",
                      values = RColorBrewer::brewer.pal(5, "Dark2")) +
    opts(title = "TB Cases by Region of Birth")

Ejemplo de parcela de gofres

Claramente, hay trabajo adicional por hacer para lograr la estética correcta (por ejemplo, ¿qué demonios significan esos ejes?), Pero esa es la mecánica. Lo dejo "bonito" como ejercicio para el lector.

Matt Parker
fuente
3

Aquí hay uno en la base r usando los datos de @jbkunst:

waffle <- function(x, rows, cols = seq_along(x), ...) {
  xx <- rep(cols, times = x)
  lx <- length(xx)
  m <- matrix(nrow = rows, ncol = (lx %/% rows) + (lx %% rows != 0))
  m[1:length(xx)] <- xx

  op <- par(no.readonly = TRUE)
  on.exit(par(op))

  par(list(...))
  plot.new()
  o <- cbind(c(row(m)), c(col(m))) + 1
  plot.window(xlim = c(0, max(o[, 2]) + 1), ylim = c(0, max(o[, 1]) + 1),
              asp = 1, xaxs = 'i', yaxs = 'i')
  rect(o[, 2], o[, 1], o[, 2] + .85, o[, 1] + .85, col = c(m), border = NA)

  invisible(list(m = m, o = o))
}


cols <- c("#F8766D", "#7CAE00", "#00BFC4", "#C77CFF")
m <- waffle(c(80, 30, 20, 10), rows = 8, cols = cols, mar = c(0,0,0,7),
            bg = 'cornsilk')
legend('right', legend = LETTERS[1:4], pch = 15, col = cols, pt.cex = 2,
       bty = 'n')

ingrese la descripción de la imagen aquí

rawr
fuente
2
Todos los ejemplos parecen tener una alta relación tinta: información.
Frank Harrell
1
Estoy de acuerdo con @Frank Harrell. El ejemplo es singularmente poco convincente. Me encantan los gráficos sin medida, pero para este ejemplo es razonable esperar que los lectores comprendan una tabla con las cuatro frecuencias. Si se prefiere un gráfico, entonces un gráfico de puntos o barras es más simple (las frecuencias también se pueden agregar como anotación). Puedo imaginar algún valor pedagógico para niños muy pequeños.
Nick Cox
1
¿Estás diciendo que cuando presente esta trama en la convención anual de gráficos de barras, debería esperar muchos enemigos en la multitud? gracias por el
aviso
Déle la vuelta: el gráfico parece estar diciendo a los lectores: ¡miren aquí, pueden contar por sí mismos para entender el gráfico! Si los números son grandes, eso no es posible. Si los números son pequeños, todavía no es más útil que otros gráficos. Para los niños pequeños, eso es refuerzo para que entiendan los gráficos. ¿Quién más necesita el mensaje?
Nick Cox