12

I would like to justify (not just align!) multiline text in my ggplots, i.e. mostly title, subtitle, caption and annotations via geom_text() etc.

Justified Text

To be clear, by "justified text" I mean adding space between words so that both edges of each line are aligned with both margins. The last line in the paragraph is aligned left. In the following image it would be the format on the right, highlighted in yellow:

enter image description here

reprex

Below is a reproducible example trying it with both {ggplot2} and {ggtext}. As you can see, I can only think of using hjust= (and halign= with {ggtext}) but they only align and do not justify multiline text.

library(ggtext)
library(tidyverse)

my_text <- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
my_subtitle <- paste(rep(my_text, 5), collapse = " ")

df <- tibble(
  my_text = rep(my_text, 3),
  x = c(1, 2, 3),
  y = c(2, 1, 0),
  hjust = c(0, 0.5, 1),
  vjust = c(0, 0.5, 1)
)

ggplot() +
  ggtitle("ggplot2::geom_text() with line breaks inserted via str_wrap()") +
  ggplot2::geom_text(data = df,
                     aes(
                       label = str_wrap(my_text, 45),
                       x = vjust,
                       y = hjust,
                       hjust = hjust,
                       vjust = vjust
                     )) +
  labs(subtitle = str_wrap(my_subtitle, 100)) +
  theme(plot.subtitle = element_text(hjust = 0))

ggplot() +
  ggtitle("ggtext::geom_richtext() with automatic word-wrapping") +
  ggtext::geom_textbox(
    data = df,
    width = unit(2, "inch"),
    box.color = NA,
    fill = NA,
    aes(
      label = my_text,
      x = vjust,
      y = hjust,
      hjust = hjust,
      vjust = vjust,
      halign = hjust,
      valign = vjust
    )
  ) +
  labs(subtitle = my_subtitle) +
  theme(plot.subtitle = ggtext::element_textbox_simple(hjust = 0, halign = 0))

Created on 2022-08-23 with reprex v2.0.2

Paul Schmidt
  • 1,072
  • 10
  • 23
  • 1
    While I think this is useful, I don't think a package implements something like this. My best guess would be to implement your own geoms and elements using something like `systemfonts::shape_string()` or `textshaping::shape_text()` to get initial measurements, and then do the justification yourself. But that is all not trivial as this comment makes it seem. – teunbrand Aug 17 '22 at 11:51

0 Answers0