I have a two facet plots created in ggplot2. I would like to add an arrow outside of the plot area. Multiple questions tried to address this: How to draw lines outside of plot area in ggplot2? Displaying text below the plot generated by ggplot2
but I can't make my example work. Also, I hope there is an easier way to accomplish this?
I tried to increase plot.margins
and to use coord_cartesian()
, but neither helped.
Instead, I want:
My dummy example:
# read library to assess free data
library(reshape2)
library(ggplot2)
ggplot(tips,
aes(x=total_bill,
y=tip/total_bill)) +
geom_point(shape=1) +
facet_grid(. ~ sex) +
# define the segment outside the plot
geom_segment(aes(x = 10,
y = -0.25,
xend = 10,
yend = 0),
col = "red",
arrow = arrow(length = unit(0.3, "cm"))) +
theme_bw() +
# limit the displayed plot extent
coord_cartesian(ylim = c(0, 0.75)) +
# increase plot margins - does not help
theme(plot.margin = unit(c(1,1,1,0), "lines"))
You can draw outside the panel using the argument clip="off"
in coord_cartesian
. I also use the expand
argument of scale_y
to start the y-axis at zero. There is a bit a manual selection over the y
start position.
So your example
library(reshape2)
library(ggplot2)
ggplot(tips,
aes(x=total_bill,
y=tip/total_bill)) +
geom_point(shape=1) +
facet_grid(. ~ sex) +
annotate("segment", x=12, y=-0.05, xend=12, yend=0,
col="red", arrow=arrow(length=unit(0.3, "cm"))) +
scale_y_continuous(expand=c(0,0))+
theme_bw() +
coord_cartesian(ylim = c(0, 0.75), clip="off") +
theme(plot.margin = unit(c(1,1,1,0), "lines"))
(I changed geom_segment
to annotate
as you were not mapping aesthetics)
Which produces
This is a workaround which is not exactly super satisfying, because you will need to play around with the position of your plots. Principally it uses custom annotation, possible with cowplot
library(ggplot2)
library(cowplot)
library(reshape2)
First define your plots, with the same coordinate limits.
p <-
ggplot(tips, aes(x = total_bill, y = tip/total_bill)) +
geom_point(shape = 1) +
facet_grid(. ~ sex) +
theme_bw() +
coord_cartesian(ylim = c(0, 0.75), xlim = c(0, 50))
arrow_p <-
ggplot(tips) +
geom_segment(aes(x = 1, y = -1, xend = 1, yend = 0),
col = "red",
arrow = arrow(length = unit(0.3, "cm"))) +
coord_cartesian(ylim = c(0, 0.75), xlim = c(0,50)) +
theme_void()
arrow_p
is created on a void background for use as overlay. You can now position it where you want with:
ggdraw() +
draw_plot(p) +
draw_plot(arrow_p, x = 0.10, y = 0.05) +
draw_plot(arrow_p, x = 0.57, y = 0.05)
Unfortunately, you have to trial-and-error here. You can also change specify the width/height/scale parameters of draw_plot()
.
There might be a better way, but this is a fairly straight forward workaround...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With