Consider this plot:
seg <- data.frame(x = 1, xend = 1, y = 2, yend = 3)
ggplot(seg)
aes(x = x, xend = xend, y = y, yend = yend)
geom_segment()
geom_text(aes(y = (y yend) / 2), label = "Hello", size = 10)
Is there an easy way to remove the part of the segment that overlaps with the text?
I tried using geom_label
but I still want the background to be the same, just the other objects to be removed around the text. I also tried with geomtextpath
but I can't get the text to be horizontal. Any ideas?
Looking for something like this:
CodePudding user response:
I wouldn't say the following is 'easy', but you can use the {ggfx} package to put an inverted mask on the segment that corresponds with a textbox.
library(ggplot2)
library(ggfx)
seg <- data.frame(x = 1, xend = 1, y = 2, yend = 3)
ggplot(seg)
aes(x = x, xend = xend, y = y, yend = yend)
# Adding a label-textbox as mask ensures appropriate window-agnostic size
# Just make sure the aesthetics are the same as the geom_text later
as_reference(
geom_label(aes(y = (y yend) / 2), label = "Hello", size = 10),
id = "textbox"
)
# Plot the masked bit
with_mask(
geom_segment(),
mask = ch_alpha("textbox"), invert = TRUE
)
# On top of the mask
geom_text(aes(y = (y yend) / 2), label = "Hello", size = 10)
Created on 2022-10-14 by the reprex package (v2.0.1)
CodePudding user response:
An option could be using ggplot_build
to modify the distance of your geom_segment
by creating two separate segments like this:
seg <- data.frame(x = 1, xend = 1, y = 2, yend = 3)
library(ggplot2)
library(dplyr)
p <- ggplot(seg)
aes(x = x, xend = xend, y = y, yend = yend)
geom_segment()
geom_text(aes(y = (y yend) / 2), label = "Hello", size = 10)
q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
bind_rows(q$data[[1]]) %>%
mutate(y = c(2, 2.55),
yend = c(2.45, 3))
q <- ggplot_gtable(q)
plot(q)
Created on 2022-10-15 with reprex v2.0.2