ggplot legend customized from scrtch

I like this plot. But a proper legend is missing. The default legend is redundant to the x axis labels.
Reproducible code below.

I want a legend that has two rectangles in the same pink like the "Total" bar (same two alpha values) and labeled as the data says: legend title "data", legend text "chance" and "accuracy".

Can this be achieved with ggplot?

df <- structure(list(variable = c("Gender", "Gender", "Gender", "Gender", 
"Gender", "Gender", "Gender", "Gender", "Gender", "Gender", "Gender", 
"Gender", "Age", "Age", "Age", "Age", "Age", "Age", "Age", "Age", 
"Age", "Age", "Age", "Age", "Occupation", "Occupation", "Occupation", 
"Occupation", "Occupation", "Occupation", "Occupation", "Occupation", 
"Occupation", "Occupation", "Occupation", "Occupation", "Education", 
"Education", "Education", "Education", "Education", "Education", 
"Education", "Education", "Education", "Education", "Education", 
"Education"), source = c("A", "B", "C", "D", "E", "TOTAL", "A", 
"B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
"A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
"A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
"A", "B", "C", "D", "E", "TOTAL"), data = c("chance", "chance", 
"chance", "chance", "chance", "chance", "accuracy", "accuracy", 
"accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
"chance", "chance", "chance", "chance", "accuracy", "accuracy", 
"accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
"chance", "chance", "chance", "chance", "accuracy", "accuracy", 
"accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
"chance", "chance", "chance", "chance", "accuracy", "accuracy", 
"accuracy", "accuracy", "accuracy", "accuracy"), value = c(0.523895968227212, 
0.509236901291129, 0.519668988460942, 0.524802806125146, 0.632036357690869, 
0.525958818637582, 0.642384105960265, 0.664259927797834, 0.703984819734345, 
0.67065868263473, 0.758373205741627, 0.696371398078975, 0.186782358542585, 
0.186149584307939, 0.244016956158074, 0.258504849722108, 0.181859027439288, 
0.204253609334977, 0.291390728476821, 0.28, 0.388257575757576, 
0.383367139959432, 0.306954436450839, 0.344957081545064, 0.395881180643248, 
0.519061786755519, 0.394176295779594, 0, 0, 0.429357805784071, 
0.509933774834437, 0.595667870036101, 0.51498127340824, NaN, 
NaN, 0.537422037422037, 0, 0, 0.166467424550934, 0.180220751438608, 
0.216859450366366, 0.165678266356785, NaN, NaN, 0.318181818181818, 
0.316430020283976, 0.335731414868106, 0.322670375521558)), row.names = c(NA, 
-48L), class = "data.frame")

library(ggplot2)

p.acc <- ggplot(df, aes(x = source, y = value, fill = source)) + 
  geom_bar(stat="identity", position = 'dodge', alpha = .5, show.legend = FALSE) + 
  facet_wrap(~ variable) +
  labs(title = 'Prediction accuracy', x = '', y = 'Probability') +
  geom_text(aes(label=sprintf("%1.2f", value)), vjust = 2, color = 'white') + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

p.acc

Is this a rough approximation of what you are trying to do?

df <- structure(list(variable = c("Gender", "Gender", "Gender", "Gender", 
                                  "Gender", "Gender", "Gender", "Gender", "Gender", "Gender", "Gender", 
                                  "Gender", "Age", "Age", "Age", "Age", "Age", "Age", "Age", "Age", 
                                  "Age", "Age", "Age", "Age", "Occupation", "Occupation", "Occupation", 
                                  "Occupation", "Occupation", "Occupation", "Occupation", "Occupation", 
                                  "Occupation", "Occupation", "Occupation", "Occupation", "Education", 
                                  "Education", "Education", "Education", "Education", "Education", 
                                  "Education", "Education", "Education", "Education", "Education", 
                                  "Education"), source = c("A", "B", "C", "D", "E", "TOTAL", "A", 
                                                           "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL"), data = c("chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy"), value = c(0.523895968227212, 
                                                                                                                                                                  0.509236901291129, 0.519668988460942, 0.524802806125146, 0.632036357690869, 
                                                                                                                                                                  0.525958818637582, 0.642384105960265, 0.664259927797834, 0.703984819734345, 
                                                                                                                                                                  0.67065868263473, 0.758373205741627, 0.696371398078975, 0.186782358542585, 
                                                                                                                                                                  0.186149584307939, 0.244016956158074, 0.258504849722108, 0.181859027439288, 
                                                                                                                                                                  0.204253609334977, 0.291390728476821, 0.28, 0.388257575757576, 
                                                                                                                                                                  0.383367139959432, 0.306954436450839, 0.344957081545064, 0.395881180643248, 
                                                                                                                                                                  0.519061786755519, 0.394176295779594, 0, 0, 0.429357805784071, 
                                                                                                                                                                  0.509933774834437, 0.595667870036101, 0.51498127340824, NaN, 
                                                                                                                                                                  NaN, 0.537422037422037, 0, 0, 0.166467424550934, 0.180220751438608, 
                                                                                                                                                                  0.216859450366366, 0.165678266356785, NaN, NaN, 0.318181818181818, 
                                                                                                                                                                  0.316430020283976, 0.335731414868106, 0.322670375521558)), row.names = c(NA, 
                                                                                                                                                                                                                                           -48L), class = "data.frame")

library(ggplot2)

p.acc <- ggplot(df, aes(x = source, y = value, fill = source)) + 
  geom_bar(stat="identity", position = 'dodge', alpha = .5, show.legend = FALSE) + 
  facet_wrap(~ variable) +
  labs(title = 'Prediction accuracy', x = '', y = 'Probability') +
  geom_text(aes(label=sprintf("%1.2f", value)), vjust = 2, color = 'white') + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.55, ymax = 0.63, 
        alpha = .2, fill = "#FF00CC") +
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.63, ymax = 0.69, 
           alpha = .6, fill = "#FF00CC") +
  annotate("text", x = 5.5, y = 0.60, label = "accuracy") +
  annotate("text", x = 5.5, y = 0.66, label = "chance") +
  annotate("text", x = 5.5, y = 0.72, label = "Data") +
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.55, ymax = 0.75, 
           color = "black", fill = NA) 

p.acc
#> Warning: Removed 4 rows containing missing values (geom_bar).
#> Warning: Removed 4 rows containing missing values (geom_text).

Created on 2020-05-14 by the reprex package (v0.3.0)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

Hi phiggins. Not quite :). I want a legend that fits the ggplot design. Setting show.legend = TRUE in my plot creates a ggplot default legend. This legend design is required but customized as described.

Is this closer to the intent?

df <- structure(list(variable = c("Gender", "Gender", "Gender", "Gender", 
                                  "Gender", "Gender", "Gender", "Gender", "Gender", "Gender", "Gender", 
                                  "Gender", "Age", "Age", "Age", "Age", "Age", "Age", "Age", "Age", 
                                  "Age", "Age", "Age", "Age", "Occupation", "Occupation", "Occupation", 
                                  "Occupation", "Occupation", "Occupation", "Occupation", "Occupation", 
                                  "Occupation", "Occupation", "Occupation", "Occupation", "Education", 
                                  "Education", "Education", "Education", "Education", "Education", 
                                  "Education", "Education", "Education", "Education", "Education", 
                                  "Education"), source = c("A", "B", "C", "D", "E", "TOTAL", "A", 
                                                           "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL", "A", "B", "C", "D", "E", "TOTAL", 
                                                           "A", "B", "C", "D", "E", "TOTAL"), data = c("chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy", "chance", "chance", 
                                                                                                       "chance", "chance", "chance", "chance", "accuracy", "accuracy", 
                                                                                                       "accuracy", "accuracy", "accuracy", "accuracy"), value = c(0.523895968227212, 
                                                                                                                                                                  0.509236901291129, 0.519668988460942, 0.524802806125146, 0.632036357690869, 
                                                                                                                                                                  0.525958818637582, 0.642384105960265, 0.664259927797834, 0.703984819734345, 
                                                                                                                                                                  0.67065868263473, 0.758373205741627, 0.696371398078975, 0.186782358542585, 
                                                                                                                                                                  0.186149584307939, 0.244016956158074, 0.258504849722108, 0.181859027439288, 
                                                                                                                                                                  0.204253609334977, 0.291390728476821, 0.28, 0.388257575757576, 
                                                                                                                                                                  0.383367139959432, 0.306954436450839, 0.344957081545064, 0.395881180643248, 
                                                                                                                                                                  0.519061786755519, 0.394176295779594, 0, 0, 0.429357805784071, 
                                                                                                                                                                  0.509933774834437, 0.595667870036101, 0.51498127340824, NaN, 
                                                                                                                                                                  NaN, 0.537422037422037, 0, 0, 0.166467424550934, 0.180220751438608, 
                                                                                                                                                                  0.216859450366366, 0.165678266356785, NaN, NaN, 0.318181818181818, 
                                                                                                                                                                  0.316430020283976, 0.335731414868106, 0.322670375521558)), row.names = c(NA, 
                                                                                                                                                                                                                                           -48L), class = "data.frame")

library(ggplot2)
library(patchwork)
library(ggplotify)

p.acc <- ggplot(df, aes(x = source, y = value, fill = source)) + 
  geom_bar(stat="identity", position = 'dodge', alpha = .5, show.legend = FALSE) + 
  facet_wrap(~ variable) +
  labs(title = 'Prediction accuracy', x = '', y = 'Probability') +
  geom_text(aes(label=sprintf("%1.2f", value)), vjust = 2, color = 'white') + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) 


grob<- ggplot()+
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.55, ymax = 0.63, 
           alpha = .6, fill = "#FF00CC") +
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.63, ymax = 0.69, 
           alpha = .2, fill = "#FF00CC") +
  annotate("text", x = 5.5, y = 0.60, label = "accuracy") +
  annotate("text", x = 5.5, y = 0.66, label = "chance") +
  annotate("text", x = 5.5, y = 0.72, label = "Data") +
  annotate("rect", xmin=4.7, xmax = 6.3, ymin = 0.55, ymax = 0.69, 
           color = "black", fill = NA) +
  theme_void(0)

legend<- as.grob(grob)

lay_out <- "AAAAAAAAAB"

p.acc + legend + 
  plot_layout(design = lay_out)
#> Warning: Removed 4 rows containing missing values (geom_bar).

#> Warning: Removed 4 rows containing missing values (geom_text).

Created on 2020-05-15 by the reprex package (v0.3.0)