I am trying to expand the geom_vline lines in my ggplot plot to go outside of the plot space and into the axis area. The goal of this is to have these lines separating the axis labels so it can line up with another plot that goes next to it (see below).
Some short example code (I have many more rows, and therefore need the horizontal lines to keep things straight):
library(ggplot2)
library(cowplot)
library(dplyr)
#play data set
cars.data <- mtcars %>%
mutate(car_name = rownames(mtcars)) %>%
slice(1:6)
#I would like vlines to be extend in this plot
p1 <- ggplot(cars.data, aes(x = car_name, y = hp)) +
geom_point() +
scale_x_discrete(position = "top") +
coord_flip() +
geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
xlab("")
p2 <- ggplot(cars.data, aes(y = car_name, x = 1)) +
geom_text(aes(label = disp)) +
xlab("disp") +
geom_hline(aes(yintercept = seq(1.5, 6.5, 1)), color = "gray60")+
theme(axis.title.y = element_blank(),
axis.title.x = element_text(vjust = 0.5, angle = 30),
axis.text = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank(),
panel.background = element_rect(fill = "gray90"))
plot_grid(p1, p2, rel_widths = c(1,0.2))
This results in the following figure:
What I am looking for is to extend the lines from p1
so that they continue between the plots, almost like a plot-table hybrid. I've tried clip = "off"
but it doesn't seem to do the trick.
You'll have to draw the lines yourself to make sure they can extend past the plot boundary when you set clip = "off"
. I'm using geom_segment()
here and manually set the limits in the coord.
You also need to align the two plots in plot_grid()
to make sure everything works properly.
library(ggplot2)
library(cowplot)
library(dplyr)
#play data set
cars.data <- mtcars %>%
mutate(car_name = rownames(mtcars)) %>%
slice(1:6)
p1 <- ggplot(cars.data, aes(x = car_name, y = hp)) +
geom_point() +
scale_x_discrete(
name = NULL,
position = "top"
) +
scale_y_continuous(expand = c(0, 0)) +
coord_flip(clip = "off", ylim = c(80, 180)) +
geom_segment(
data = data.frame(x = seq(1.5, 6.5, 1), ymin = 80, ymax = 240),
aes(x = x, xend = x, y = ymin, yend = ymax),
inherit.aes = FALSE,
color = "gray60"
) +
xlab(NULL) +
theme_cowplot()
p2 <- ggplot(cars.data, aes(y = car_name, x = 1)) +
geom_text(aes(label = disp)) +
xlab("disp") +
geom_hline(aes(yintercept = seq(1.5, 6.5, 1)), color = "gray60") +
theme_cowplot() +
theme(
axis.title.y = element_blank(),
axis.title.x = element_text(vjust = 0.5, angle = 30),
axis.text = element_blank(),
axis.line = element_blank(),
axis.ticks = element_blank(),
panel.background = element_rect(fill = "gray90"),
plot.margin = margin(7, 7, 7, 0)
)
plot_grid(p1, p2, rel_widths = c(1,0.2), align = "h", axis = "bt")
Created on 2019-12-02 by the reprex package (v0.3.0)
Here's a way to get started that instead of relying on ggplot's axis labelling to get what you want, treats labels as data and builds your own. There was a question where we used similar approaches here: Bar charts connected by lines / How to connect two graphs arranged with grid.arrange in R / ggplot2
A few hacks make this work:
geom_text
and scale expansion to place it properlylibrary(ggplot2)
library(cowplot)
library(dplyr)
theme_set(theme_cowplot()) # I'm using cowplot v1.0.0 which no longer does this by default
p_left <- ggplot(cars.data, aes(x = car_name, y = hp)) +
geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
geom_point() +
scale_x_discrete(breaks = NULL) +
coord_flip() +
xlab(NULL) +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
axis.line = element_blank(),
plot.margin = margin(5, -5, 5, 5, "pt"),
panel.border = element_blank())
p_middle <- ggplot(cars.data, aes(x = car_name, y = 1)) +
geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
geom_text(aes(label = car_name), hjust = 0) +
scale_x_discrete() +
scale_y_continuous(expand = expansion(add = c(0.05, 0.5))) +
coord_flip() +
labs(x = NULL, y = "") +
theme(axis.text = element_blank(),
axis.ticks = element_blank(),
axis.line = element_blank(),
panel.grid = element_blank(),
plot.margin = margin(5, -5, 5, -5, "pt"),
panel.border = element_blank())
p_right <- ggplot(cars.data, aes(x = car_name, y = 1)) +
geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
geom_text(aes(label = disp)) +
scale_x_discrete() +
coord_flip() +
labs(x = NULL, y = "disp") +
theme(axis.text = element_blank(),
axis.ticks = element_blank(),
axis.line = element_blank(),
panel.grid = element_blank(),
plot.margin = margin(5, 5, 5, -5, "pt"),
panel.border = element_blank())
plot_grid(p_left, p_middle, p_right,
nrow = 1, rel_widths = c(1, 0.4, 0.2),
align = "h"
)
I only copied over the essential theme changes—you'll probably want to adjust things to fit your purposes. I'd recommend also digging into each of the individual plots to adjust them one by one.
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