Reputation: 13
My dataframe has the following columns:
I wish to color the bars by Group2 (so fill = Group2), but I couldn't figure out how to make bars outlined or not based on Group1 as well. My current code is
ggplot(data=df, aes(x=Category,y=Proportion, fill = Group1, group = Group2)) +
geom_bar(stat = "identity", position = position_dodge()) +
xlab("") +
ylab("Proportion") +
theme_classic() +
theme(legend.position="top") +
theme(legend.title = element_blank())
I am new to R visualization, so it would be really nice if someone could tell me how to outline the bars based on the grouping.
Here's how the dataframe should look like:
> df
Category Proportion Group1 Group2
1 1 45 a A
2 2 40 a A
3 3 49 a A
4 4 47 a A
5 5 43 a A
6 1 32 a B
7 2 37 a B
8 3 45 a B
9 4 47 a B
10 5 50 a B
11 6 49 b A
12 7 34 b A
13 8 31 b A
14 6 36 b B
15 7 46 b B
16 8 39 b B
17 9 42 c A
18 9 31 c B
19 10 31 d A
20 10 44 d B
Here's the current output:
I want the bars on left of each group to be outlined (white filling and the edge be the same color as the group)
Upvotes: 1
Views: 1441
Reputation: 24810
Is this what you're looking for?
Set fill to Group2
then color to Group1
. You can override the legend if you want a particular color or fill. I added factor
around Category
to get the x axis to make more sense, although I suspect your actual Category
is already a factor.
Note your data column is Proportions
, although your code is Proportion
.
ggplot(data=df, aes(x=factor(Category),y=Proportions, fill = Group2, color = Group1)) +
geom_bar(stat = "identity", position = position_dodge()) +
scale_fill_manual(values =c(A = "white", B = "gray")) +
xlab("") + ylab("Proportion") +
theme_classic() +
theme(legend.position="top") +
theme(legend.title = element_blank()) +
guides(fill = guide_legend(override.aes =
list(color = "gray")),
color = guide_legend(override.aes =
list(fill = "gray")))
If you're dead set on the fill matching the color, it gets more complicated, but you can use interaction(Group2,Group1)
as the fill. Then you have to manually determine the colors for the interactions.
ggplot(df, aes(x=factor(Category),y=Proportions, fill = interaction(Group2,Group1), color = Group1)) +
geom_bar(stat = "identity", position = position_dodge()) +
scale_fill_manual(values = setNames(c(rep("white",4),"cornflowerblue","forestgreen","firebrick3","goldenrod"),
sort(unique(as.character(interaction(df$Group2,df$Group1))))),
breaks = c("A.a","B.a"),
labels = c("A","B")) +
scale_color_manual(values = setNames(c("cornflowerblue","forestgreen","firebrick3","goldenrod"),
sort(unique(as.character(df$Group1))))) +
labs(x = "", y = "Proportion") +
theme_classic() +
theme(legend.position="top") +
theme(legend.title = element_blank()) +
guides(fill = guide_legend(override.aes =
list(color = "gray",
fill = c("white","darkgray"))),
color = guide_legend(override.aes =
list(fill = c("white"))))
To understand what's going on here, consider this:
interaction(df$Group2,df$Group1)
[1] A.a A.a A.a A.a A.a B.a B.a B.a B.a B.a A.b A.b A.b B.b B.b B.b A.c B.c A.d B.d
Levels: A.a B.a A.b B.b A.c B.c A.d B.d
If we sort and unique this, we get the following:
sort(unique(as.character(interaction(df$Group2,df$Group1))))
[1] "A.a" "A.b" "A.c" "A.d" "B.a" "B.b" "B.c" "B.d"
We want the first 4 to be white, so we can use rep
, and then manually define the others.
c(rep("white",4),"cornflowerblue","forestgreen","firebrick3","goldenrod")
[1] "white" "white" "white" "white" "cornflowerblue" "forestgreen" "firebrick3" "goldenrod"
From here we can use setNames
to apply the fills to the values:
setNames(c(rep("white",4),"cornflowerblue","forestgreen","firebrick3","goldenrod"),
sort(unique(as.character(interaction(df$Group2,df$Group1)))))
A.a A.b A.c A.d B.a B.b B.c B.d
"white" "white" "white" "white" "cornflowerblue" "forestgreen" "firebrick3" "goldenrod"
Repeat the process for the colors.
We don't necessarily want to see all of the interaction()
's in the legend. So we can limit them with the breaks =
argument. We can rename A.a
and B.a
to just A
and B
with labels =
.
Upvotes: 1