The x and y axis are labeled based on certain interval set by ggplot.
In the event that a horizontal or vertical line is added to the plot, the goal is to label x or y axis at the exact value of the line.
How can this be done?
This isn't totally straightforward, but it is possible. I would probably use these two little functions to automate the tricky parts:
add_x_break <- function(plot, xval) {
p2 <- ggplot_build(plot)
breaks <- p2$layout$panel_params[[1]]$x$breaks
breaks <- breaks[!is.na(breaks)]
plot +
geom_vline(xintercept = xval) +
scale_x_continuous(breaks = sort(c(xval, breaks)))
}
add_y_break <- function(plot, yval) {
p2 <- ggplot_build(plot)
breaks <- p2$layout$panel_params[[1]]$y$breaks
breaks <- breaks[!is.na(breaks)]
plot +
geom_hline(yintercept = yval) +
scale_y_continuous(breaks = sort(c(yval, breaks)))
}
These would work like this. Start with a basic plot:
library(ggplot2)
set.seed(1)
df <- data.frame(x = 1:10, y = runif(10))
p <- ggplot(df, aes(x, y)) +
geom_point() +
ylim(0, 1)
p
Add a vertical line with add_x_break
p <- add_x_break(p, 6.34)
p
Add a horizontal line with add_y_break
:
p <- add_y_break(p, 0.333)
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
p
ADDENDUM
If for some reason you do not have the code that generated the plot, or the vline is already present, you could use the following function to extract the xintercept and add it to the axis breaks:
add_x_intercepts <- function(p) {
p2 <- ggplot_build(p)
breaks <- p2$layout$panel_params[[1]]$x$breaks
breaks <- breaks[!is.na(breaks)]
vals <- unlist(lapply(seq_along(p$layers), function(x) {
d <- layer_data(p, x)
if('xintercept' %in% names(d)) d$xintercept else numeric()
}))
p + scale_x_continuous(breaks = sort(c(vals, breaks)))
}
So, for example:
set.seed(1)
df <- data.frame(x = 1:10, y = runif(10))
p <- ggplot(df, aes(x, y)) +
geom_point() +
geom_vline(xintercept = 6.34) +
ylim(0, 1)
p
Then we can do:
add_x_intercepts(p)
The y intercepts of geom_hline
can be obtained in a similar way, which should hopefully be evident from the code of add_x_intercepts