Reputation: 1170
The main goal of this plot is to make a comparison between A
and B
in three groups, but I want to have one
, two
, and three
besides them, as well. Using below code, I can make a grouped barplot which is almost what I want. But I need to have the names of each bar below it since the legend is so ugly.
How can I do it?
m.names <- c("A1","B1","one","A2","B2","two","A3","B3","three")
m.group <- c(1,1,1,2,2,2,3,3,3)
m.value <- c(5,10,1,20,15,2,10,20,3)
df <- data.frame(m.names, m.group, m.value)
df
ggplot(df, aes(x = m.group, y = m.value)) +
geom_bar(aes(fill = m.names), position = "dodge", stat = "identity") +
scale_fill_manual(values=c("gray75", "gray75","gray75", "gray40","gray40","gray40", "blue", "red", "green" ))
Upvotes: 1
Views: 88
Reputation: 4224
Seems like you might want this:
require(ggplot2)
ggplot(df, aes(x = m.names, y = m.value)) +
geom_bar(aes(fill = m.names), stat = "identity") +
scale_fill_manual(values=c("gray75", "gray75","gray75", "gray40",
"gray40","gray40", "blue", "red", "green" )) +
facet_grid(~m.group, scales = "free_x", space = "free_x") +
theme(strip.text.x = element_blank(),
panel.spacing = unit(0, "lines"))
Output:
The trick is to plot x by m.names here instead of m.groups. Then later we can facet the bars by m.group to keep them presented the way you want.
Upvotes: 1
Reputation: 887168
We could use geom_label
dodger = position_dodge(width = 0.9)
ggplot(df, aes(x = m.group, y = m.value)) +
geom_bar(aes(fill = m.names), position = dodger, stat = "identity") +
scale_fill_manual(values=c("gray75", "gray75","gray75",
"gray40","gray40","gray40", "blue", "red", "green" ),
guide = "none") +
theme(axis.text.x=element_blank(),
axis.ticks.x=element_blank()) +
geom_label(aes(x = m.group, group = m.names, label = m.names, y = 0),
position = dodger,
vjust = 1, colour = "black")
Upvotes: 1
Reputation: 29085
Faceting by group may work for this case as well:
fill.values = c("gray75", "gray75","gray75",
"gray40","gray40","gray40",
"blue", "red", "green")
names(fill.values) = levels(df$m.names)
> fill.values
A1 A2 A3 B1 B2 B3 one three two
"gray75" "gray75" "gray75" "gray40" "gray40" "gray40" "blue" "red" "green"
ggplot(df,
aes(x = m.names, y = m.value, fill = m.names)) +
geom_col() +
scale_fill_manual(values = fill.values, guide = F) +
facet_wrap(~m.group, scales = "free_x") +
theme_bw()
Upvotes: 3
Reputation: 60070
Adding geom_text
and making sure it's dodged in the same way as the bars:
# width = 0.9 should be the default for dodged bars but set
# it explicitly to be sure
dodger = position_dodge(width = 0.9)
ggplot(df, aes(x = m.group, y = m.value)) +
geom_bar(aes(fill = m.names), position = dodger, stat = "identity") +
scale_fill_manual(values=c("gray75", "gray75","gray75", "gray40","gray40","gray40", "blue", "red", "green" ),
guide = "none") +
geom_text(aes(x = m.group, group = m.names, label = m.names, y = 0),
position = dodger,
vjust = 1, colour = "black")
Upvotes: 3