Reputation: 3
I am beginner at R and trying to make a boxplot showing tumor accumulation of a certain product at different points over time, for two different conditions. I came up with the following image:
Boxplot with multiple groups + condition
I used this code:
ggplot(tumor, aes(x=time_point, y=IA, fill=condition)) + ggtitle ("Tumor accumulation") + xlab("Time post-injection (h)") + ylab("%IA/kg") + geom_boxplot()+ geom_point(position=position_jitterdodge(0))+ scale_x_discrete(limits=c("2", "24", "96", "144")) + scale_fill_brewer(palette="Paired") + theme_minimal() + expand_limits(y=0)
Because there is no data for condition C1 and 144 h time point, the appearance of the box on the far right is much bigger. I cannot seem to figure out how to change the width of this single box without altering the rest.
Upvotes: 0
Views: 182
Reputation: 13823
This should help you out. First, let me use an example dataset and an an example boxplot:
df <- data.frame(
samplename=c(rep("A", 10), rep("B1", 10), rep("B2", 10)),
grp=c(rep("Group A", 10), rep("Group B", 20)),
y=c(rnorm(10), rnorm(10, 0.2), rnorm(10, 0.35, 0.1))
)
ggplot(df, aes(grp, y)) +
geom_boxplot(aes(fill=grp, group=samplename))
This gives you a plot similar to your example. The box on the left is expanded to fill the entire x aesthetic, whereas the boxes on the right are split (official term is "dodged") so that the total of B1 + B2 = the width of B.
To fix this, you can use the preserve='single'
argument included in the position_dodge()
function, which must be applied to the position=
argument of geom_boxpot
. Here's what I mean:
ggplot(df, aes(grp, y)) +
geom_boxplot(aes(fill=grp, group=samplename),
position=position_dodge(preserve='single'))
That fixes your width issue by making all the individual boxes (dodged or otherwise) the same width, but it also means that the box belonging to "Group A" is still dodged to the left. This was an issue before it was fixed by adding position_dodge2()
(Movie Subtitle: "The return of position_dodge!"). Simply substituting that for position_dodge()
fixes this issue and you have all boxes aligned with their x axis values:
ggplot(df, aes(grp, y)) +
geom_boxplot(aes(fill=grp, group=samplename),
position=position_dodge2(preserve='single'))
Upvotes: 1