Jak zrobić wykresy waflowe w R?

11

Jak wykreślić wykres waflowy jako alternatywę dla używania piecharts w R?

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

Najbliższe, jakie znalazłem w Google, to mozaiki.

719016
źródło
Nie wiem, ale dlaczego nie zastosować lepszej metody? Wykresy punktowe są znacznie lepsze.
Peter Flom - Przywróć Monikę
2
Dla tych, którzy chcą wiedzieć, jakie są wykresy waflowe, Robert Kosara na blogu Eager Eyes ma o nich kawałek . Zwróć także uwagę na komentarze Jona Peltiera.
Andy W
Najbliższa rzecz, jaką mogłem znaleźć, to to . FWIW, zgadzam się z Peterem, unikam ciast i gofrów podczas wizualizacji danych.

Odpowiedzi:

13

Teraz jest paczka o nazwie gofr .

Przykład ze strony github:

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

Wynik:

wynik

pozdrowienia

jbkunst
źródło
Nie wiedziałem, że są to tak zwane „wykresy waflowe”. Lubię je - dobre zastąpienie wykresu kołowego
shadowtalker
7

Podejrzewam, że geom_tilez paczki ggplot2można zrobić to, czego szukasz. Odpowiedź Shane'a na to pytanie StackOverflow powinna zacząć.

Edycja: Oto przykład z kilkoma innymi wykresami do porównania.

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")

Przykładowy wykres waflowy

Najwyraźniej trzeba wykonać dodatkową pracę, aby uzyskać odpowiednią estetykę (np. Co do cholery oznaczają te osie?), Ale taka jest jej mechanika. „Ładne” zostawiam jako ćwiczenie dla czytelnika.

Matt Parker
źródło
3

Oto jeden w bazie r wykorzystujący dane @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')

wprowadź opis zdjęcia tutaj

rawr
źródło
2
Wszystkie przykłady wydają się mieć wysoki stosunek atramentu do informacji.
Frank Harrell,
1
Zgadzam się z @Frank Harrell. Przykład jest wyjątkowo nieprzekonujący. Uwielbiam wykresy ponad miarę, ale w tym przykładzie uzasadnione jest oczekiwanie, że czytelnicy zrozumieją tabelę z czterema częstotliwościami. Jeśli preferowany jest wykres, wówczas wykres punktowy lub słupkowy jest prostszy (częstotliwości można również dodać jako adnotację). Mogę sobie wyobrazić pewną wartość pedagogiczną dla bardzo małych dzieci.
Nick Cox,
1
Więc mówisz, że kiedy przedstawię ten spisek na dorocznej konwencji wykresów słupkowych, powinienem spodziewać się wielu nienawiści w tłumie? dzięki za heads-up
rawr
Odwróć: wykres wydaje się mówić czytelnikom: spójrz tutaj, możesz liczyć na zrozumienie wykresu! Jeśli liczby są duże, nie jest to możliwe. Jeśli liczby są małe, nadal nie jest to bardziej pomocne niż inne wykresy. Dla małych dzieci jest to wzmocnienie, aby rozumieli grafikę. Kto jeszcze potrzebuje wiadomości?
Nick Cox,