Reputation: 53
I'm trying to connect ggplot2 boxplots with geom_lines for multiple factors. I'd been able to accomplish so far to connect all the boxplot with lines, see attach picture. But I wish to connect the only boxplots by their corresponding factor.
For example for my variable FL, I want to connect only those two boxplot, without connecting them with the remaining variables. Similarly for the variable RW, connecting those two sex boxplot without the remaining others.
library("MASS")
data(crabs)
melt_crabs <- melt(crabs,id.var=c("sp","sex","index"))
ggplot(melt_crabs, aes(x = variable, y = value)) + geom_line(aes(group = index), size = 0.05, alpha = 0.7) + geom_boxplot(aes(fill = sp), alpha = 0.5) + facet_grid(sex~.)
Does anyone know how to achieve this? I hope I'd explain myself the most clear way.
Many thanks and best wishes,
Upvotes: 3
Views: 12609
Reputation: 14360
@Stibu's answer is definitely the quickest and cleanest way to get your desired output. Building off his answer, since for a given variable, the plots are no longer next to each other, you might want to put each in their own separate plot. This can be easily by only a minor tweak to the facet_grid
call in @Stibu's code:
ggplot(melt_crabs, aes(x = interaction(sex, variable), y = value)) +
geom_boxplot(aes(fill = sex), alpha = 0.5) +
geom_line(aes(group = interaction(index, variable)),
alpha = 0.5, colour = "darkgrey") +
facet_grid(sp~variable,scales="free_x") +
scale_x_discrete(labels = "")
Also I did some digging if you want to move the top strip to the bottom, it isn't that difficult. Adapting the code from: How to display strip labels below the plot when faceting?
We get:
p<-ggplot(melt_crabs, aes(x = interaction(sex, variable), y = value)) +
geom_boxplot(aes(fill = sex), alpha = 0.5) +
geom_line(aes(group = interaction(index, variable)),
alpha = 0.5, colour = "darkgrey") +
facet_grid(sp~variable,scales="free_x") +
scale_x_discrete(labels = "")
# Convert the plot to a grob
gt <- ggplotGrob(p)
# Get the positions of the panels in the layout: t = top, l = left, ...
panels <-c(subset(gt$layout, name == "panel", select = t:r))
# Get the strip grob & x-axis label grob
stripGrob = gtable_filter(gt, "strip-top")
#Replace x-axis ticks with strip
gt = gtable_add_grob(gt, stripGrob, t = max(panels$b)+1, l = min(panels$l), r = max(panels$r))
# remove the old strip
gt = gt[-(min(panels$t)-1), ]
grid.newpage()
grid.draw(gt)
Upvotes: 5
Reputation: 15907
I don't know of way to connect the points in exactly the plot that you produced. But I can show you how to do something similar.
The difficulty is that all the points that belong to a pair of boxplots share the same x-coordinate (that is, the same value for variable
). Therefore I have used interaction(sex, variable)
as the x-coordinate, such that each boxplot has its own x-value. This means, however, that the paired boxplots are less visible. On the other hand, the connecting lines work in the other direction.
In order to plot the lines, they are grouped by interaction(index, variable)
, which means that data points are connected, when they share the same values for index
and variable
.
Enough talk, here's the code:
ggplot(melt_crabs, aes(x = interaction(sex, variable), y = value)) +
geom_boxplot(aes(fill = sex), alpha = 0.5) +
geom_line(aes(group = interaction(index, variable)),
alpha = 0.5, colour = "darkgrey") +
facet_grid(sp~.) +
scale_x_discrete(labels = rep(levels(melt_crabs$variable), each = 2))
Upvotes: 6