Search code examples
rggplot2geom-text

R, ggplot2: Centering and aligning wrapped text in geom_rect


I have the following data:

Channel <- c("Episode", "Episode", "Episode", "Episode", "Episode", "Episode", "Episode", "Episode")
start.time <- c(0.000, 25.458, 48.712, 152.419, 179.055, 196.274, 212.693, 232.861)
stop.time <- c(25.458, 48.712, 152.419, 179.055, 196.274, 212.693, 232.861, 266.370)
Episode <- c("Prologue", "An episode title", "A longer episode title", "An really, incredibly long episode title", "I wish I knew how to make hjust work with wrapped text", "A sample title", "No one likes making reproducible examples", "Epilogue")

ep_df <- data.frame(Channel, start.time, stop.time, Episode)
#wrap text for episode titles
ep_df$Episode <- stringr::str_wrap(ep_df$Episode, 15)

I use this code to plot it:

library(ggplot2)
ggplot(ep_df, aes(fill = Episode, color = Episode)) + 
  geom_rect(color = "black", aes(xmin = start.time, xmax = stop.time, ymin = -0.5, ymax = 0.5), show.legend = FALSE) +
  scale_x_continuous(breaks = scales::pretty_breaks(n = 15)) +
  facet_grid(Channel ~ .) +
  theme(axis.text.y=element_blank(), 
        axis.ticks.y=element_blank()) + 
  coord_fixed(40)+ scale_fill_manual(values=c("#F8F8F8", "#F5F5F5", "#F0F0F0", "#E8E8E8", "#E0E0E0", "#DCDCDC", "#D8D8D8", "#D3D3D3", "#D0D0D0", "#C8C8C8")) +
  theme(legend.position="bottom") + 
  geom_text(hjust = -0.5, vjust = 0.5, size = 2, aes(x = pmin(start.time, (start.time+stop.time)/2), y = 0, label = Episode), inherit.aes = FALSE) + 
  theme(plot.margin = margin(t = 0)) +
  labs(x = "Time (sec)") +
  ylab(NULL)

This is the resulting plot:

plot_output

I have two problems:

  1. When using hjust to align the text in each rectangle, it appears to apply only to the first line of the wrapped text, the following lines seem randomly adjusted. I would like each line of an instance of wrapped text to be aligned.

  2. I also cannot figure out how to center the text in each block, hjust won't seem to do it. It is possible to center each text value regardless of the size of the rectangle?

If 2) is not possible, that's OK, I can live with that, but 1) is a deal-breaker, I gotta have that wrapped text aligned to the same left edge (that's not flush against the left border of the box).


Solution

  • Thank you for this question, I've found the solution by using the following geom_text

    geom_text(
        hjust = 0.5, 
        vjust = 0.5, 
        size = 2, 
        aes(
          x = (start.time + stop.time) / 2, 
          y = 0, 
          label = Episode
        ), 
        inherit.aes = FALSE
        )
    

    It produced the following plot

    plot with a centered text in each block