Как сделать вафельные графики в R?


11

Как я могу построить вафельную диаграмму как альтернативу использованию круговых диаграмм в R?

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

Ближе всего я обнаружил, что в поиске есть мозаичные участки.


Я не знаю, но почему бы не использовать лучший метод? Точечные диаграммы намного лучше.
Питер Флом - Восстановить Монику

2
Для тех, кто хочет знать, что такое вафельные графики, у Роберта Косара в блоге Eager Eyes есть статья о них. Обратите внимание на комментарии Джона Пельтье.
Энди W

Самое близкое, что я мог найти, это . FWIW, я согласен с Питером, я избегаю пирогов и вафель, когда я визуализирую данные.

Ответы:


13

Теперь есть пакет под названием вафельный .

Пример со страницы github:

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

Результат:

результат

С уважением


Я не знал, что они назывались «вафельные графики». Они мне нравятся - хорошая замена круговой диаграммы
shadowtalker

7

Я подозреваю, что geom_tileиз пакета ggplot2можно сделать то, что вы ищете. Ответ Шейна на этот вопрос StackOverflow должен помочь вам начать.

Изменить: вот пример, с несколькими другими графиками для сравнения.

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

Пример вафельного сюжета

Понятно, что для правильной эстетики нужно проделать дополнительную работу (например, что, черт возьми, означают эти оси?), Но в этом вся механика. Я оставляю «красивое» как упражнение для читателя.


3

Вот один из них в базе r, использующий данные @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')

введите описание изображения здесь


2
Все примеры, кажется, имеют высокое соотношение чернил: информация.
Фрэнк Харрелл

1
Я согласен с @Frank Harrell. Пример необычайно неубедителен. Я безмерно люблю графики, но для этого примера разумно ожидать, что читатели поймут таблицу с четырьмя частотами. Если график предпочтительнее, то точечная или гистограмма проще (частоты также могут быть добавлены как аннотации). Я могу представить некоторую педагогическую ценность для очень маленьких детей.
Ник Кокс

1
То есть, вы говорите, что когда я представляю этот сюжет на ежегодном собрании гистограмм, я должен ожидать много ненавистников в толпе? спасибо за хэдз-ап
Rawr

Переверните его: график, кажется, говорит читателям: посмотрите сюда, вы можете рассчитывать на себя, чтобы понять график! Если числа большие, это невозможно. Если числа маленькие, это все же не более полезно, чем другие графики. Для маленьких детей это подкрепление, чтобы они понимали графику. Кому еще нужно сообщение?
Ник Кокс

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.