I would like to create a plot with subgroups in legend using interaction. I create some fake data with zero values to create subheading.
My sample data:
library(ggplot2)
df <- data.frame(value = runif(27, 0, 1),
x = rep(1:3, each = 3),
group1 = rep(c(letters[1:3])),
group2 = rep(c("fake", "X", "Y"), each = 9))
# introducing fake data
df[df$group2 == "fake", "value"] <- 0
df$group2 <- relevel(df$group2, ref = "fake")
I was almost able to create desired plot:
# labels
lbl1 <- c(expression(bold("HEADING 1")), paste("LABEL 1", 1:2),
expression(bold("HEADING 2")), paste("LABEL 2", 1:2),
expression(bold("HEADING 3")), paste("LABEL 3", 1:2))
fills <- c("white", "red1", "red3",
"white", "blue1", "blue3",
"white", "green1", "green3")
colo <- c("white", "black", "black",
"white", "black", "black",
"white", "black", "black")
ggplot(df, aes(x = x, y = value,
fill = interaction(group2, group1),
colour = interaction(group2, group1))) +
geom_col(position = "dodge") +
scale_fill_manual("", values = fills, label = lbl1) +
scale_colour_manual("", values = colo, label = lbl1)
However, I don't want to have LABEL 1 1
and LABEL 1 2
etc in subgroups, I would like to have only LABEL 1
and LABEL 2
.
I was not able to create such a plot when specifying such labels:
lbl2 <- c(expression(bold("HEADING 1")), paste("LABEL", 1:2),
expression(bold("HEADING 2")), paste("LABEL", 1:2),
expression(bold("HEADING 3")), paste("LABEL", 1:2))
ggplot(df, aes(x = x, y = value,
fill = interaction(group2, group1),
colour = interaction(group2, group1))) +
geom_col(position = "dodge") +
scale_fill_manual("", values = fills, label = lbl2) +
scale_colour_manual("", values = colo, label = lbl2)
To be explicit, this is desired output:
In the original barplot we had used scale_fill_manual() function to specify colors for barplot. Now we can add name=”” as argument to remove legend title. If our plot does use using fill option, but uses color option, then we can use scale_color_manual() function to remove legend title in R.
Example 1: Remove All Legends in ggplot2 We simply had to specify legend. position = “none” within the theme options to get rid of both legends.
You can use the following syntax to change the legend labels in ggplot2: p + scale_fill_discrete(labels=c('label1', 'label2', 'label3', ...))
You have non unique labels because you are introducing a fake group to separate the columns on your plot.
According to the discrete_scale
help:
A character vector giving labels (must be same length as breaks)
The scale code probably calls unique
to the character vector and you end up with a vector with fewer labels than breaks resulting on the weird legends.
It seems you should be using facets to obtain similar results instead of the hack(fake group):
# Remove the "fake" group 2
df1 <- df[df$group2 != "fake",]
ggplot(df1, aes(x = group1, y = value, fill=group2)) +
geom_col(position = "dodge", color ="black")+
scale_fill_manual( values =c("red","green"),labels = c("Lable 1", "Lable 2")) +
scale_x_discrete(labels =c("H1", "H2", "H3")) +
facet_wrap(x~., strip.position = "bottom")
If you really want the exact plot, you will have to change the labels modifying the gtable
using more hacks:
library(grid)
fills <- c("white", "red1", "red3",
"white", "blue1", "blue3",
"white", "green1", "green3")
# You need the lbl1 in order to get the legend correct placed since it needs
# size of labels.
lbl1 <- c(expression(bold("HEADING 1")), paste("LABEL 1", 1:2),
expression(bold("HEADING 2")), paste("LABEL 2", 1:2),
expression(bold("HEADING 3")), paste("LABEL 3", 1:2))
lbl2 <- c(expression(bold("HEADING 1")), paste("LABEL", 1:2),
expression(bold("HEADING 2")), paste("LABEL", 1:2),
expression(bold("HEADING 3")), paste("LABEL", 1:2))
colo <- c("white", "black", "black",
"white", "black", "black",
"white", "black", "black")
p <- ggplot(df, aes(x = x, y = value,
fill = interaction(group2, group1),
color = interaction(group2, group1))) +
geom_col(position = "dodge") +
scale_fill_manual("",values = fills, labels=lbl1) +
scale_color_manual("",values = colo, labels=lbl1)
gt <- ggplotGrob(p)
gt
#TableGrob (12 x 11) "layout": 19 grobs
#z cells name grob
#1 0 ( 1-12, 1-11) background rect[plot.background..rect.16164]
# ...
#14 13 ( 7- 7, 7- 7) ylab-r zeroGrob[NULL]
#15 14 ( 7- 7, 9- 9) guide-box gtable[guide-box]
#16 15 ( 4- 4, 5- 5) subtitle zeroGrob[plot.subtitle..zeroGrob.16160]
# ...
# We want the item 15 guide-box
gt$grobs[[15]]$grobs
#21 21 ( 4- 4, 4- 4) label-3-3 gTree[GRID.gTree.11993]
#22 22 ( 5- 5, 4- 4) label-4-3 gTree[GRID.gTree.11994]
#23 23 ( 6- 6, 4- 4) label-5-3 gTree[GRID.gTree.11995]
#24 24 ( 7- 7, 4- 4) label-6-3 gTree[GRID.gTree.11996]
#25 25 ( 8- 8, 4- 4) label-7-3 gTree[GRID.gTree.11997]
#26 26 ( 9- 9, 4- 4) label-8-3 gTree[GRID.gTree.11998]
#27 27 (10-10, 4- 4) label-9-3 gTree[GRID.gTree.11999]
#28 28 (11-11, 4- 4) label-10-3 gTree[GRID.gTree.12000]
#29 29 (12-12, 4- 4) label-11-3 gTree[GRID.gTree.12001]
# Items 21 to 29 are labels, replace the labels with the ones we want.
for(i in 1:9)
{
gt$grobs[[15]]$grobs[[1]]$grobs[[20 +i]]$children[[1]]$children[[1]]$label <- lbl2[i]
}
# New plot
grid.draw(gt)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With