1
votes

I made a pie chart using R and ggplot2, more or less according to example #128 of the R Graph Gallery.

piePlot <- function(count, categories) {
  dat <- data.frame(count = count, category = categories)
  dat$fraction <- dat$count / sum(dat$count)
  dat$ymax <- cumsum(dat$fraction)
  dat$ymin <- c(0, head(dat$ymax, n = -1))
  dat$label <- paste(dat$category, dat$count)
  plot <-
    ggplot(dat, aes(
      fill = category,
      ymax = ymax,
      ymin = ymin,
      xmin = 0,
      xmax = 1
    )) +
    geom_rect() +
    coord_polar(theta = "y") +
    scale_fill_brewer(labels = dat$label, guide = "legend")
  plot
}

piePlot(count = c(20, 10, 30),
        categories = c("one", "two", "three"))

Here's the output:

Output

The colors of the legend mismatch. The biggest are is supposed to be the darkest (three 30) according to the legend, which is obviously not the case. Here's a printout of my data frame right before the plot:

  count category  fraction      ymax      ymin    label
1    20      one 0.3333333 0.3333333 0.0000000   one 20
2    10      two 0.1666667 0.5000000 0.3333333   two 10
3    30    three 0.5000000 1.0000000 0.5000000 three 30

This is exactly the legend's order, but ggplot seems to reorder the fields somehow when doing the plot. I just cannot understand why.

I'm using R version 3.4.2 and ggplot2 version 2.2.1.

Does anybody know how and why this reordering is taking place, and how I could suppress it?

1

1 Answers

1
votes

The mismatch occurs because ggplot() orders the legend alphabetically in the first place, i.e. the legend entries would read "one 20, three 30, two 10" from top to bottom if you would not have called scale_fill_brewer But you overwrite the legend's entries to be "one 20, two 30, three 10". One way around this is to define the dat$label as a factor with levels c("one 20", "two 10", "three 30") so the legend is ordered by the factor levels.

To cut a long story short, the code below should solve your problem:

piePlot <- function(count, categories) {
dat <- data.frame(count = count, category = categories)
dat$fraction <- dat$count / sum(dat$count)
dat$ymax <- cumsum(dat$fraction)
dat$ymin <- c(0, head(dat$ymax, n = -1))
dat$label <- factor(paste(dat$category, dat$count), levels = paste(dat$category, dat$count))
plot <-
ggplot(dat, aes(
  fill = label, # fill by label not category
  ymax = ymax,
  ymin = ymin,
  xmin = 0,
  xmax = 1
)) +
geom_rect() +
coord_polar(theta = "y") +
scale_fill_brewer(guide = "legend") # no need for labels anymore
plot
}

library(ggplot2)
piePlot(count = c(20, 10, 30),
    categories = c("one", "two", "three"))

enter image description here