How to modify text to ggplot below the plot?

48 Views Asked by At

Much like a previous user , I would like a panel of text underneath my plot.

With the previous post, I have gotten pretty far, but I would still like to modify my plot. With dummy data (borrowed from the previous post), my plot looks like this: Current plot

library(patchwork)
line_size <- 1.2 
base_size <- 20 
axis_text_rel_size = -1
title_text_rel_size = 5

d <- tibble(
  Rodent= c(rep("Mouse",11),
            rep("Hamster",7),
            rep("Guinea pig",4),
            rep("Gerbil",12)),
  `Weight (gm)` = rnorm(34,25,10),
  `Heat:` = c(rep("+",11),rep("-",7),rep("+",4),rep("+",12))
  ,  `Needle:` = c(rep("+",11),rep("+",7),rep("+",4),rep("+",12)),
  `Comb.:` = c(rep("Phen",11),rep("-",7),rep("-",4),rep("Met",12)),
)

p1 <- d %>% 
  ggplot(aes(Rodent,`Weight (gm)`)) +
  geom_boxplot(lwd=1.3,colour="black")+
  scale_y_continuous(expand = expansion(mult = c(0, 0.05)))+
  labs(y = "Percentage") +
  theme_foundation(base_size = base_size, base_family = "sans")+ 
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    panel.background = element_blank(),
    text = element_text(colour = "black"),
    plot.title = element_text(face = "bold", 
                              size = rel(1), hjust = 0.5),
    axis.line = element_line(colour="black", size = line_size),
    axis.ticks = element_line(colour="black", size = line_size),
    axis.title = element_text(face = "bold", size = rel(1)),
    axis.title.y = element_text(angle = 90, vjust = 2),
    axis.title.x = element_blank(),
    axis.text = element_text(face = "bold", size = rel(1)),
    axis.text.x = element_blank(),
    plot.background = element_blank(),
    legend.title=element_blank(),
    legend.position = "none"
  )

d1 <- d %>% 
  select(-`Weight (gm)`) %>%
  pivot_longer(-Rodent)

p2 <- d1 %>% 
  ggplot(aes(Rodent, fct(name), label = value)) +
  geom_text(size = 7.2) +
  labs(x = NULL, y = NULL)+
  theme_foundation(base_size = base_size, base_family = "sans")+
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    panel.background = element_blank(),
    text = element_text(colour = "black"),
    axis.title = element_text(face = "bold", size = rel(0.9)),
    axis.title.y = element_text(angle = 90, vjust = 2),
    axis.text = element_text(face = "bold", size = rel(1)),
    axis.text.x = element_blank(),
    axis.ticks=element_blank(),
    plot.background = element_blank()
  )


p1 / p2

If it is possible, I would like the panel to go Heat > Needle > Comb, but I don't know where to refactor. I would also like to reduce the spacing between the three "treatment options" (Heat, needle, comb) as well as the spacing between the y-axis and its title. Also, the fonts in the panel seem to differ depending whether its a header or not.

I am not married to this code, so if there is an easier way to get a panel below the plot, I would really appreciate it! Thank you :)

1

There are 1 best solutions below

2
On BEST ANSWER

To achieve your desired order for the table convert name in d1 to a factor with the levels set in your desired order. For the labels use the same font size as for theme, i.e. 20 / .pt or 20pt instead of 7.2 which is approx. 20.5 pt. To remove the space between the axis title and the axis text you could set `vjust´ to a negative value. Additionally I use a negative plot margin on the left. For the spacing between the table categories a simple option would be to increase the size of the main plot. This way the table gets squished. Finally, I collected the duplicated theme options and apply them in one go where creating the patch.

library(patchwork)
library(ggplot2)
library(ggthemes)
library(tidyr)
library(forcats)
library(dplyr, warn = FALSE)

set.seed(123)

p1 <- d %>%
  ggplot(aes(Rodent, `Weight (gm)`)) +
  geom_boxplot(lwd = 1.3, colour = "black") +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  labs(y = "Percentage") +
  theme_foundation(base_size = base_size, base_family = "sans") +
  theme(
    plot.title = element_text(
      face = "bold",
      size = rel(1), hjust = 0.5
    ),
    axis.line = element_line(colour = "black", size = line_size),
    axis.ticks = element_line(colour = "black", size = line_size),
    axis.title.x = element_blank(),
    legend.title = element_blank(),
    legend.position = "none"
  )

d1 <- d %>%
  select(-`Weight (gm)`) %>%
  pivot_longer(-Rodent) |>
  mutate(
    name = factor(name, rev(unique(name)))
  )

p2 <- d1 %>%
  ggplot(aes(Rodent, name, label = value)) +
  geom_text(size = 20 / .pt) +
  labs(x = NULL, y = NULL) +
  theme_foundation(base_size = base_size, base_family = "sans") +
  theme(
    axis.ticks = element_blank()
  )


(p1 / p2) +
  plot_layout(heights = c(2, 1)) &
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    panel.background = element_blank(),
    text = element_text(size = 20, colour = "black"),
    axis.title = element_text(face = "bold", size = rel(1)),
    axis.title.y = element_text(angle = 90, vjust = -8),
    axis.text = element_text(face = "bold", size = rel(1)),
    axis.text.x = element_blank(),
    plot.background = element_blank(),
    plot.margin = margin(5.5, 5.5, 5.5, -5.5)
  )