0

I'm building a barplot with RNA reads % in ggplot, I did this:

ggplot(tipos_exo,aes(x = reorder(sample, -value),y = value,fill = variable)) +
     geom_bar( stat = "identity")

barplot

I need to replace the x axis labels with colored bars, each sample belongs to a specific batch and I looking for this effect:

Colored bars

Any thoughts?

stefan
  • 90,330
  • 6
  • 25
  • 51
  • 1
    Hard to say without a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), but perhaps `+ geom_rug(aes(color = sample))`? – jared_mamrot Jul 26 '22 at 10:42

1 Answers1

1

One option to achieve your desired result would be to create your axis colorbar as a second plot and glue it to the main plot via the patchwork package.

For the colorbar I use geom_tile and remove all non-data ink using theme_void. As a first step I reorder your sample column by value and get rid of the duplicated sample categories using dplyr::distinct.

Using some fake random example data:

set.seed(123)

tipos_exo <- data.frame(
  sample = rep(letters, each = 2),
  variable = c("tablaq_readsPerc", "tablaq_shortReadsPerc"),
  value = runif(52, 0, 100),
  batch = rep(LETTERS, each = 2)
)

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

p1 <- ggplot(tipos_exo,aes(x = reorder(sample, -value),y = value,fill = variable)) +
  geom_bar( stat = "identity") +
  scale_y_continuous(expand = c(0, 0)) +
  labs(x = NULL) +
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.length.x = unit(0, "pt"))

tipos_exo1 <- tipos_exo |> 
  mutate(sample = reorder(sample, -value)) |> 
  distinct(sample, batch)

p_axis <- ggplot(tipos_exo1, aes(x = sample, y = factor(1), fill = batch)) +
  geom_tile(width = .9) +
  geom_text(aes(label = sample)) +
  theme_void() +
  theme(axis.title.x = element_text()) +
  labs(x = "Batch Annotation") +
  guides(fill = "none")

p1 / p_axis + plot_layout(heights = c(8, 1)) 

UPDATE Adapting my answer on this post Reorder Bars of a Stacked Barchart in R you could reorder your sample column by a helper value "column", e.g. if you want to reorder by "tablaq_readsPerc" you set the values for the other categories to zero and use FUN=sum. Note that I also reversed the order of the stack so that the "tablaq_readsPerc" bars are placed at the bottom.

tipos_exo <- tipos_exo |> 
  mutate(sample1 = reorder(sample, -ifelse(!variable %in% "tablaq_readsPerc", 0, value), FUN = sum))

p1 <- ggplot(tipos_exo,aes(x = sample1, y = value, fill = variable)) +
  geom_bar( stat = "identity", position = position_stack(reverse = TRUE)) +
  scale_y_continuous(expand = c(0, 0)) +
  labs(x = NULL) +
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.length.x = unit(0, "pt"))

tipos_exo1 <- tipos_exo |> 
  distinct(sample, sample1, batch)

p_axis <- ggplot(tipos_exo1, aes(x = sample1, y = factor(1), fill = batch)) +
  geom_tile(width = .9) +
  geom_text(aes(label = sample)) +
  theme_void() +
  theme(axis.title.x = element_text()) +
  labs(x = "Batch Annotation") +
  guides(fill = "none")

p1 / p_axis + plot_layout(heights = c(8, 1)) 

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thank you very much Stefan, you put me in the way. It looks much better now. Your code is very smart. – David Caceres Jul 27 '22 at 12:43
  • Hi again. And what about if I want to order these bars according for example to the decreasing value of readsPerc??. Because they are ordered by the total value or the sum of them. Thanks – David Caceres Aug 01 '22 at 20:25
  • Hi @DavidCaceres, actually reorder uses the mean by default. And ordering by one category is always a bit tricky but see my update for one option to achieve that. – stefan Aug 01 '22 at 20:50
  • Much appreciated Stefan, tricky way to find it by myself. – David Caceres Aug 04 '22 at 22:04