0

I am generating a bar graph to show mutation frequency by dose for a specific dataset. Underneath the bar chart I would like to include a colour block type legend that corresponds to the dose of each bar. I have included a figure (made using excel with different data) that shows exactly what I would like to achieve (see below). enter image description here

I have come across a similar question which generates colour blocks based on a specific size (see below) however, I am looking to have one that will adjust based on the number of samples (columns) in the dataset and is associated with the dose column.

ggplot: Is there a way to add a color coded bar annotation to the right of the y-axis?

I have included my current code for this here, along with the associated data and current plot.

enter image description here

 MF_sample <- read.table(file = "SamplesData.txt", header = TRUE)
 MF_by_sample<-ggplot(MF_sample, aes(x=sample, y=MFmin, fill=factor(dose))) + 
 geom_col() +
 scale_fill_manual("Dose (mg/kg-bw/day)", values = c("0" = "#33ffff", "1" = "#00ccff", "2"="#3399ff",
 "5" = "#000066")) +
 theme_classic() +
 theme(text = element_text(size = 11, family="calibri")) +
 scale_x_discrete (limits=MF_sample$sample) +
 scale_y_continuous(expand = c(0,1e-9))


#Data:

sample dose    MFmin       MFmax
1 Sample1    0 1.89e-07 2.38750e-07
2 Sample2    0 2.89e-07 2.46467e-07
3 Sample3    1 3.89e-07 3.04626e-07
4 Sample4    1 5.89e-07 1.01960e-07
5 Sample5    1 7.89e-07 1.04370e-07
6 Sample6    2 8.89e-07 1.98602e-07
7 Sample7    2 9.89e-07 1.77643e-07
8 Sample8    2 1.89e-07 1.94386e-07
stefan
  • 90,330
  • 6
  • 25
  • 51

2 Answers2

1

One option to add your desired legend would be to create a second plot using e.g. a geom_rect which you could glue to your main plot using e.g. patchwork. To this end I first converted sample to a numeric and added it as a new column to your data.

library(ggplot2)
library(dplyr, warn=FALSE)
library(patchwork)

pal_fill <- c(
  "0" = "#33ffff", "1" = "#00ccff", "2" = "#3399ff",
  "5" = "#000066"
)

MF_sample$sample_num <- as.numeric(factor(MF_sample$sample))

p1 <- ggplot(MF_sample, aes(x = sample, y = MFmin, fill = factor(dose))) +
  geom_col() +
  scale_fill_manual("Dose (mg/kg-bw/day)", values = pal_fill) +
  scale_x_discrete(limits = MF_sample$sample) +
  scale_y_continuous(expand = c(0, 1e-9)) +
  theme_classic() +
  theme(
    text = element_text(size = 11, family = "calibri"),
  ) +
  guides(fill = "none")

MF_rect <- MF_sample |>
  group_by(dose) |>
  summarise(xmin = min(sample_num) - .5, xmax = max(sample_num) + .5, .groups = "drop")

p2 <- ggplot(MF_rect, aes(fill = factor(dose))) +
  scale_x_discrete(limits = MF_sample$sample) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = 0, ymax = 1), linewidth = 0) +
  geom_text(aes(x = .5 * (xmin + xmax), y = .5, label = dose), family = "calibri") +
  scale_fill_manual(values = pal_fill) +
  theme_void() +
  guides(fill = "none")

p1 / p2 +
  plot_layout(heights = c(20, 1))

enter image description here

DATA

MF_sample <- structure(list(sample = c(
  "Sample1", "Sample2", "Sample3", "Sample4",
  "Sample5", "Sample6", "Sample7", "Sample8"
), dose = c(
  0L, 0L,
  1L, 1L, 1L, 2L, 2L, 2L
), MFmin = c(
  1.89e-07, 2.89e-07, 3.89e-07,
  5.89e-07, 7.89e-07, 8.89e-07, 9.89e-07, 1.89e-07
), MFmax = c(
  2.3875e-07,
  2.46467e-07, 3.04626e-07, 1.0196e-07, 1.0437e-07, 1.98602e-07,
  1.77643e-07, 1.94386e-07
)), class = "data.frame", row.names = c(
  "1",
  "2", "3", "4", "5", "6", "7", "8"
))
stefan
  • 90,330
  • 6
  • 25
  • 51
1

You could use coloured facet strips via ggh4x library:

enter image description here

Code:

library(ggh4x)
strip <- strip_themed(background_x = elem_list_rect(fill = c("0" = "#33ffff", "1" = "#00ccff", "2"="#3399ff","5" = "#000066")))

MF_by_sample<-ggplot(MF_sample, aes(x=sample, y=MFmin, fill=factor(dose))) + 
  geom_col() +
  scale_fill_manual("Dose (mg/kg-bw/day)", values = c("0" = "#33ffff", "1" = "#00ccff", "2"="#3399ff",
                                                      "5" = "#000066")) +
  theme_classic() +
  theme(text = element_text(size = 11, family="calibri"), legend.position = "none") +
  #scale_x_discrete (limits=MF_sample$sample) +
  scale_y_continuous(expand = c(0,1e-9)) + 
  facet_grid2(cols=vars(dose), space="free", scale="free",strip=strip,switch = "x")

MF_by_sample
George Savva
  • 4,152
  • 1
  • 7
  • 21