Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiple columns of information ggplot y axis

Tags:

r

ggplot2

I want to write multiple pieces of information in each y-axis label of a ggplot bar chart (or any similar kind of plot). The problem is having everything aligned nicely.

It's probably best explained with an example for what I want to have: enter image description here

My primary issue is the formatting on the left side of the figure.

What I've tried so far includes using monospace fonts to write the labels. This basically works but I want to try and avoid the use of monospace fonts for aesthetic purposes.

I've also tried making several ggplots where the idea was to remove everything in two initial plots, except for the y-axis labels (so these "plots" would only be the y-axis labels). Then align the plots next to each other using grid.align. The problem I have here is that there doesn't seem to be a way to remove the plot part of a ggplot (or is there?). It also requires some tweaking since removing x-axis labels in one of the "empty" plots would result in the labels moving down (since no space is occupied by the x-axis labels/title anymore).

I've also tried an approach using geom_text and setting the appropriate distances using the hjust parameter. However, for some reason, the spacing does not seem to be equal for the different size labels (for example distances for the "Red" and "Turquoise" labels are different for the same hjust). As the real data has many more variations in label sizes this variation makes the table look very messy...

I'm not too concerned about the headers since they are easy to add to the figure manually. The values on the right are also not too much of a problem since they have a fixed width and I can use geom_text to set them. So my main problem is with the y-axis (left) labels.

Here's an example data set:

dt = data.frame(shirt = c('Red','Turquoise','Red','Turquoise','Red','Turquoise','Red','Turquoise'), 
            group = c('Group alpha','Group alpha','Group beta','Group beta','Group delta','Group delta','Group gamma','Group gamma'),
            n = c(22,21,15,18,33,34,20,19),
            mean = c(1,   4,  9,  2,  4,  5 , 1, 2),
            p = c(0.1, 0.09, 0.2, 0.03, 0.05, 0.99, 0.81, 0.75))
like image 452
Deruijter Avatar asked Sep 17 '25 17:09

Deruijter


1 Answers

The closest I could come to is to use guide_axis_nested() from ggh4x for formatting the left part. (Disclaimer: I'm the author of ggh4x). With this axis, you can't align spanning categories (e.g group) to the top, nor have titles for the different levels.

library(ggplot2)
library(ggh4x)

# Create some dummy data
df <- expand.grid(
  group = paste("Group", c("alpha", "beta", "delta", "gamma")),
  shirt = c("Red", "Turquoise")
)
df$N <- sample(1:100, nrow(df))
df$mean <- rlnorm(nrow(df), meanlog = 1)
df$pvalue <- runif(nrow(df))

ggplot(df, aes(x = mean, y = interaction(N, shirt, group, sep = "&"))) +
  geom_col() +
  guides(
    y = guide_axis_nested(delim = "&"),
    y.sec = guide_axis_manual(
      breaks = interaction(df$N, df$shirt, df$group, sep = "&"),
      labels = scales::number(df$pvalue, 0.001)
    )
  ) +
  theme(
    axis.text.y.left = element_text(margin = margin(r = 5, l = 5)),
    ggh4x.axis.nesttext.y = element_text(margin = margin(r = 5, l = 5)),
    ggh4x.axis.nestline = element_blank()
  )

Created on 2021-11-16 by the reprex package (v1.0.0)

like image 88
teunbrand Avatar answered Sep 20 '25 10:09

teunbrand