0
votes

I am trying to reproduce this image in ggplot:

enter image description here

Figure 2b, from Zak et al., 2016. see - https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5392204/

I initially tried to use a stacked bar plot, but I cannot get the bins to be all the same width. It seems the underlying nature of bar plots makes each category a set size which cannot be modified.

I set the x-axis as the timepoint, the y-axis as each sample and the colour with the value.

I have created a connected line plot with some success; however, I don’t think it has the same sharpness seen in the image there.

Does anyone have a suggestion of how I can recreate this in ggplot using a stacked barplot with custom heights? Or should I just keep trying to improve the line chart?

Code : ## Connecting Line chart  
 ggplot(groupC, aes(colour=value, y=sample, x=timepoint)) + 
  geom_line(size=12)  +
  theme(plot.title = element_text(hjust = 0.5,size=12)) +
  scale_colour_gradientn(colours = myPalette(100), limits=c(1, 80), na.value = NA, name="Value") +
  ylab("")  +
  theme_classic()

## Bar Chart    
ggplot(groupC_bar, aes(x=sample, y=timepoint, fill=value)) + 
geom_bar(stat="identity", colour="black")  +   coord_flip() 

Data
sample  timepoint   value
a1  m0  0
b2  m0  2
c3  m0  6
d4  m0  7
e5  m0  3
a1  m2  9
b2  m2  10
c3  m2  12
d4  m2  16
e5  m2  11
a1  m4  16
b2  m4  20
c3  m4  15
d4  m4  20
e5  m4  32
a1  m6  34
b2  m6  34
c3  m6  18
d4  m6  33
e5  m6  54
1

1 Answers

1
votes

If you want to give the appearance of a gradient fill like this, just flip the co-ordinates and stack the bars, using a custom color palette in the fill aesthetic:

my_palette <- colorRampPalette(c("red", "#DDDD00", "forestgreen"))

df <- data.frame(sample = rep(paste0(letters[1:5], 1:5), each = 100),
                 value  = rep(c(1, 0.8, 0.65, 1.3, 0.5), each = 100),
                 color =  factor(rep(my_palette(100), 5), my_palette(100)))

ggplot(df, aes(x = sample, y = value, fill = color)) +
  geom_col() +
  scale_fill_identity() +
  coord_flip() +
  theme_classic() +
  theme(axis.line.x  = element_blank(),
        axis.text.x  = element_blank(),
        axis.title.x = element_blank())

enter image description here

Your own data isn't sufficiently gradiated to allow this. You could either interpolate it or have larger blocks of color fill like this:

ggplot(groupC, aes(x = sample, y = value, fill = timepoint)) +
  geom_col() +
  scale_fill_manual(values = my_palette(4)) +
  coord_flip() +
  theme_classic() +
  theme(axis.line.x  = element_blank(),
        axis.text.x  = element_blank(),
        axis.title.x = element_blank())

enter image description here


EDIT

An option with even bin widths:

ggplot(groupC, aes(x = 1, y = sample, fill = value)) +
  geom_col() +
  scale_fill_gradientn(colours = c("forestgreen", "yellow", "red")) +
  scale_x_continuous(breaks = 1:4 - 0.5, labels = unique(groupC$timepoint)) +
  theme_classic() +
  labs(x = "timepoint")

enter image description here