Question Details

No question body available.

Tags

r ggplot2

Answers (2)

February 2, 2026 Score: 5 Rep: 131,157 Quality: Medium Completeness: 80%

An easy option to achieve your desired result is the "secondary axis trick", i.e. add the labels via a secondary x axis. This can be achieved by "adding"

scalexcontinuous(
  sec.axis = dupaxis(
    name = NULL,
    breaks = vlines$xintercept,
    labels = c("Intervention\nbegins", "Intervention\nends")
  )
)

And in case the left alignment of the labels is required I would suggest to switch to ggtext::elementmarkdown for the top axis text which provides an additional halign= parameter to achieve that (but requires to switch to "
"
to add a line break):

scalexcontinuous(
  sec.axis = dupaxis(
    name = NULL,
    breaks = vlines$xintercept,
    labels = c("Intervention
begins", "Intervention
ends") ) ) + theme( axis.text.x.top = ggtext::element
markdown( halign = 0 ) )

Full reproducible code for the second case:

library(ggplot2)

ggplot(df, aes(x = time, y = value)) + geomrect( data = shadedregion, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = Period), inherit.aes = FALSE, alpha = 0.3 ) + geomline(aes(color = "Observed Data"), linewidth = 0.8) + geomvline( data = vlines, aes(xintercept = xintercept, linetype = Line), linewidth = 1 ) + scalefillmanual(name = NULL, values = c("Intervention Period" = "lightgreen")) + scalecolormanual(name = NULL, values = c("Observed Data" = "steelblue")) + scalelinetypemanual(name = NULL, values = c("Intervention Start/End" = "dotted")) + labs(x = "Time", y = "Value", title = "Time Series with Intervention Period") + thememinimal() + theme( legend.position = "bottom" ) + scalexcontinuous( sec.axis = dupaxis( name = NULL, breaks = vlines$xintercept, labels = c("Intervention
begins", "Intervention
ends") ) ) + theme(

axis.text.x.top = ggtext::elementmarkdown( halign = 0 ) ) + guides( fill = guidelegend(order = 1), color = guidelegend(order = 2), linetype = guidelegend(order = 3) )

enter image description here

February 2, 2026 Score: 4 Rep: 22,394 Quality: Medium Completeness: 80%

One way is to make another plot containing just the title and the labels, and then combine the two using, say, the plotgrid function from cowplot

The first plot uses information from your vlines data frame:

data
labs