Home > Software engineering >  Adding background transparency and custom ordering in legend in ggplot
Adding background transparency and custom ordering in legend in ggplot

Time:10-27

Let say I have below ggplot

library(ggplot2)
library(ggnewscale)

data = 
structure(list(grp1 = c("X", "X", "X", "X", "Y", "Y", "Y", "Y"
), grp2 = c("A", "B", "C", "D", "A", "B", "C", "D"), val = c(1, 
2, 3, 4, 3, 4, 5, 6)), row.names = c(NA, -8L), class = "data.frame")

col_define = c('red', 'orange', 'blue', 'lightblue')
names(col_define) = c('A', 'B', 'C', 'D')

ggplot(data, aes(x = grp1, group = grp2, y = val))  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("A", "B"), name = "1")  
  new_scale_fill()  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("C", "D"), name = "2")  
  theme(legend.position="top", legend.direction = 'vertical', 
        legend.box.margin = margin(), 
        legend.box.background = element_rect(fill = alpha('#e5e5e5', 0.60), size = 0.1, linetype = 'solid', color = '#333333'))

As we can seen I tried to add background transparency in my plot using element_rect(fill = alpha('#e5e5e5', 0.60), however is not working. Is there any alternate way to add transparency in the background for this plot?

I also want to change the order in label of legend like 2, 1, instead 1, 2. Basically I want to apply some custom ordering in case there are many levels.

Any pointer will be very helpful.

CodePudding user response:

Legend backgrounds are always a bit tricky. As we have to deal with multiple elements. Also I'm not 100% sure what you mean by add background transparency. But the first thing I did was to remove the color and the fill for the legend.background, i.e. the box drawn around each legend (whereas legend.box.background is the background of the box drawn around all legends (; BTW: There is also the background of the single legend keys which is set via legend.key. :D ).

The easy part is the ordering of the legends which could be set via the order argument of guide_legend.

library(ggplot2)
library(ggnewscale)

data <-
  structure(list(grp1 = c("X", "X", "X", "X", "Y", "Y", "Y", "Y"), grp2 = c("A", "B", "C", "D", "A", "B", "C", "D"), val = c(
    1,
    2, 3, 4, 3, 4, 5, 6
  )), row.names = c(NA, -8L), class = "data.frame")

col_define <- c("red", "orange", "blue", "lightblue")
names(col_define) <- c("A", "B", "C", "D")

ggplot(data, aes(x = grp1, group = grp2, y = val))  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("A", "B"), name = "1", guide = guide_legend(order = 2))  
  new_scale_fill()  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("C", "D"), name = "2", guide = guide_legend(order = 1))  
  theme(
    legend.position = "top",
    legend.direction = "vertical",
    legend.box.margin = margin(),
    legend.background = element_rect(color = NA, fill = NA),
    legend.box.background = element_rect(
      fill = alpha('#e5e5e5', .6), size = 0.1, linetype = "solid", color = "#333333"
    )
  )

CodePudding user response:

Here is an alternative:

ggplot(data, aes(x = grp1, group = grp2, y = val))  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("B", "A"), name = "1")  
  new_scale_fill()  
  geom_col(aes(fill = grp2))  
  scale_fill_manual(values = col_define, breaks = c("C", "D"), name = "2")  
  theme(legend.position="top", legend.direction = 'vertical',
        legend.background = element_rect(fill="gray",
                                         size=1, linetype="solid", 
                                         color ="gray"))

enter image description here

  • Related