Home > Enterprise >  R ggplot legend with Waffle chart
R ggplot legend with Waffle chart

Time:10-21

library(tidyverse)
library(waffle)
df_2 <- structure(list(group = c(2, 2, 2, 1, 1, 1), 
  parts = c("A", "B", "C", "A", "B", "C"), 
  values = c(1, 39, 60, 14, 15, 71)), row.names = c(NA,
  -6L), class = c("tbl_df", "tbl", "data.frame"))

df_2 %>% ggplot(aes(label = parts))  
  geom_pictogram(
    n_rows = 10, aes(color = parts, values = values),
    family = "fontawesome-webfont",
    flip = TRUE
  )  
  scale_label_pictogram(
    name = "Case",
    values = c("male"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C")
  )  
  scale_color_manual(
    name = "Case",
    values = c("A" = "red", "B" = "green", "C" = "grey85"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C")
  )  
  facet_grid(~group)

With the above code, I got the legend what I expected: enter image description here

However, when I replaced df_2 with the following df_1 dataframe, I was unable to combine two legends.

df_1 <- structure(list(group = c(2, 2, 2, 1, 1, 1), 
  parts = c("A", "B", "C", "A", "B", "C"), 
  values = c(0, 0, 100, 0, 0, 100)), 
  row.names = c(NA,-6L), class = c("tbl_df", "tbl", "data.frame"))

I kind of know the cause of the problem (0 values) but I would like to keep the legend the same as the graph above. Any suggestions would be appreciated.

enter image description here

CodePudding user response:

To make it clear, the package "waffle" referred to here is not the CRAN package "waffle", but the GitHub-only package:

remotes::install_github("hrbrmstr/waffle")
library(waffle)

You will also need a way of displaying the pictograms, such as:

library(emojifont)
load.fontawesome()

Now, as with any other discrete scale, if you want to add values that are not present in the (post-stat) data, you need to use the limits argument:

df_1 %>% ggplot(aes(label = parts))  
  geom_pictogram(
    n_rows = 10, aes(color = parts, values = values),
    family = "fontawesome-webfont",
    flip = TRUE
  )  
  scale_label_pictogram(
    name = "Case",
    values = c("male"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C"),
    limits = c("A", "B", "C")
  )  
  scale_color_manual(
    name = "Case",
    values = c("A" = "red", "B" = "green", "C" = "grey85"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C")
  )  
  facet_grid(~group)

enter image description here

CodePudding user response:

It is a bit tricky, but what you could do is say let's add 1 to all values so it will plot it like before. But using ggplot_build to remove from each case one row to get it in the right amount like this:

library(tidyverse)
library(waffle)
library(ggplot2)
library(dplyr)
library(emojifont)
library(waffle)
library(extrafont)

p <- df_1 %>% ggplot(aes(label = parts))  
  geom_pictogram(
    n_rows = 10, aes(color = parts, values = values 1),
    family = "fontawesome-webfont",
    flip = TRUE
  )  
  scale_label_pictogram(
    name = "Case",
    values = c("male"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C")
  )  
  scale_color_manual(
    name = "Case",
    values = c("A" = "red", "B" = "green", "C" = "grey85"),
    breaks = c("A", "B", "C"),
    labels = c("A", "B", "C")
  )  
  facet_grid(~group)

q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
  group_by(PANEL) %>%
  slice(4:n())

q <- ggplot_gtable(q)

plot(q)

Created on 2022-10-20 with reprex v2.0.2

  • Related