Search code examples
rggplot2ggtext

reduce the gap between left-aligned (hjust=0) and right-aligned (hjust=1) in axis label in ggplot2


I have the following codes

var <- c("var1-very long text", "b", "very long text", "var2", "bb", "bla", "blah", "var3", "bbb", "bbbb")
y <- c(NA, 1, 2, NA, 1, 3, 2, NA, 3, 2)
lcl <- y - 0.5
ucl <- y + 0.5

df <- data.frame(var[10:1], y[10:1], lcl[10:1], ucl[10:1])
df$var <- factor(df$var, levels = unique(df$var))

library(ggplot2)
library(ggtext)

bold_vars <- c("var1-very long text", "var2", "var3")

p <- ggplot(data=df, aes(x=var, y=y, ymin=lcl, ymax=ucl)) +
  geom_pointrange() + 
  geom_hline(yintercept=1, lty=2) + 
  coord_flip() +  
  ylab("Blah") +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.title.y=element_blank(),
        axis.text.y = element_text(hjust=c(1, 1, 0, 1, 1, 1, 0, 1, 1, 0))) + 
  scale_x_discrete(labels = c("var1-very long text" = expression(bold("var1-very long text")), "var2" = expression(bold("var2")), "var3" = expression(bold("var3"))))
print(p)

I want to keep the left-aligned and the right-aligned labels for the Y axis, but there is a big gap between them. How can I reduce this gap?


Solution

  • One option to get rid of the gap would be to switch to ggtext::element_markdown where we have to set the alignment using halign= and importantly set align_widths = TRUE:

    var <- c("var1-very long text", "b", "very long text", "var2", "bb", "bla", "blah", "var3", "bbb", "bbbb")
    y <- c(NA, 1, 2, NA, 1, 3, 2, NA, 3, 2)
    lcl <- y - 0.5
    ucl <- y + 0.5
    
    df <- data.frame(var[10:1], y[10:1], lcl[10:1], ucl[10:1])
    df$var <- factor(df$var, levels = unique(df$var))
    
    library(ggplot2)
    library(ggtext)
    
    bold_vars <- c("var1-very long text", "var2", "var3")
    
    ggplot(data = df, aes(y = var, x = y, xmin = lcl, xmax = ucl)) +
      geom_pointrange() +
      geom_vline(xintercept = 1, lty = 2) +
      xlab("Blah") +
      theme(
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.line = element_line(colour = "black"),
        axis.title.y = element_blank(),
        axis.text.y = element_markdown(
          halign = c(1, 1, 0, 1, 1, 1, 0, 1, 1, 0),
          align_widths = TRUE
        )
      ) +
      scale_y_discrete(
        labels = \(x) ifelse(
          x %in% bold_vars,
          paste0("**", x, "**"),
          x
        )
      )
    #> Warning: Removed 3 rows containing missing values or values outside the scale range
    #> (`geom_pointrange()`).