This visualization shows the distribution of responses and the prompt text for a collection of Likert (agree/disagree) items. I'd like to make it a little easier for readers to connect the prompt text to the corresponding bar, by putting a box around each prompt and extending the axis tick mark to the appropriate box.
One option to achieve your desired result would be to use ggtext::element_markdown
which allows to draw a box around the axis text. Note however, that this requires to use a <br>
tag to add line breaks instead of \n
.
Using some fake example data:
library(ggplot2)
library(ggtext)
set.seed(123)
dat <- data.frame(
x = 1:12,
y = sapply(1:12, \(x) lorem::ipsum_words(12))
)
p <- ggplot(dat) +
geom_col(
aes(x, y)
) +
scale_y_discrete(
labels = \(x) label_wrap_gen()(x) |> gsub("\\n", "<br>", x = _),
guide = guide_axis(n.dodge = 2)
) +
theme(
axis.text.y = ggtext::element_markdown(
box.color = "black",
linetype = 1,
padding = unit(2, "pt"),
linewidth = .25
)
)
For the axis ticks you can use a vector to get ticks of different lengths as suggested by @Axeman
p +
theme(
axis.ticks.length.y = rel(c(3, 50))
)
or as a second option use e.g. annotate
to fake the axis ticks using a geom_segment
which however requires some fiddling to get the lengths right:
p +
annotate(
"segment",
x = 0, xend = -5,
y = seq(2, 12, 2),
yend = seq(2, 12, 2),
linewidth = .5
) +
coord_cartesian(
clip = "off", xlim = c(0, NA), expand = FALSE
)