Reputation: 93
What I try to achieve is having the bars ordered by a given variable per panel.
A simple example:
library(ggplot2)
library(plyr)
df <- data.frame(fac = c("a", "b", "c", "e", "b", "c", "d"),
val = c(1, 2, 7, 4, 5, 3, 1),
group = c(1, 1, 1, 1, 2, 2, 2))
p1 <- ggplot(df, aes(x = fac, y = val)) + geom_bar() + facet_wrap(~ group, scales = "free") + coord_flip()
p1
p2 <- ggplot(df, aes(x = reorder(fac, val), y = val)) + geom_bar() + facet_wrap(~ group, scales = "free") + coord_flip()
p2
p2 does not produce what I want because not every "factor level" appears in all panels. Is there a simple solution already for this problem?
One solution I found is the following (calculates the rank for each factor level per group).
df2 <- ddply(df, .(group), transform, fac2 = rank(val))
df2$fac2 <- factor(df2$fac2)
p3 <- ggplot(df2, aes(x = fac2, y = val)) + facet_wrap(~ group, scales = "free") + geom_bar(stat = "identity") + coord_flip() +
opts(panel.margin = unit(2, "lines"))
p3
I have to set the labels by my self here. One possible solution is the following (hard coded for this example):
grid.newpage()
grob <- ggplotGrob(p3)
object.path <- grid.ls(getGrob(grob, "axis.text.y", grep = TRUE, global = TRUE), print = FALSE)$name
grob <- grid::editGrob(grob, object.path[1], label = c("ABDQ", "M", "A", "B"))
grob <- grid::editGrob(grob, object.path[2], label = c("A", "B", "EEEEX"))
grid.draw(grob)
But there is another problem. I have to set the panel.margin by my self now and it seems to be not possible to do this as I'm only able to set a "global" panel.margin and what I need is one for all 4 sides (or at least 2).
Question 1: Is there a simple solution using reorder?
Question 2: Is there a solution using scale_x_discrete to get the needed axis?
Question 3: I wasn't able to find the needed grid object to manipulate the viewports for the panel.margins. Is there an easy way to manipulate the appropriate grid object?
Any ideas?
Upvotes: 9
Views: 2056
Reputation: 173577
I think that grid.arrange
is a much better tool for this than trying to shoehorn free scales into a faceting framework:
library(gridExtra)
q1 <- ggplot(subset(df,group == 1),aes(x = reorder(fac,val),y = val)) +
geom_bar() +
facet_wrap(~group) +
coord_flip()
q2 <- q1 %+% subset(df,group == 2)
grid.arrange(q1,q2,nrow = 1)
Upvotes: 4