Как изменить цвета в этой тепловой карте?

#r #ggplot2 #pheatmap

#r #ggplot2 #тепловая карта

Вопрос:

Я был бы очень благодарен за любую помощь. Я создал тепловую карту с помощью Pheatmap. Мои меры являются двоичными, и я бы хотел, чтобы цвета строк аннотаций (5 категорий) совпадали с точками данных. В настоящее время у меня есть один цвет для 5 категорий. Я приложил диаграмму, созданную моим кодом. Я не уверен, как это сделать. Заранее спасибо! введите описание изображения здесь

Вот мой код и примеры данных:

 library(pheatmap)
library(dplyr)

*Arrange cluster
spells2=spells%>%arrange(PAM_complete) 

*Df for wheeze columns
whz=spells2%>%dplyr::select(2:6)

*Create separate df for cluster  
c5=spells2$PAM_complete
c5=as.data.frame(c5)

*Wheeze and cluster need the same row names (id)
rownames(whz)=spells2$id
rownames(c5)=spells2$id
c5$c5=as.factor(c5$c5)


col=c("white", "darkblue")
pheatmap(whz,legend_breaks = 0:1, legend_labels = c("No wheeze", "Wheeze"), fontsize = 10,
         show_rownames=FALSE, cluster_rows = FALSE,  color=col,
         cluster_cols=FALSE , annotation_row=c5,  )
 
 > dput(head(spells2, 50))
structure(list(id = c("10003A", "1001", "10012A", "10013A", "10016A", 
"10019A", "1001A", "10023A", "1002A", "10037A", "1004", "10042A", 
"10045A", "1005", "10051A", "10054A", "1006", "10064A", "10065A", 
"10075A", "10076A", "10082A", "10087A", "10094A", "10095A", "10097A", 
"10098A", "100A", "10103A", "10104A", "10106A", "10121A", "10124A", 
"10126A", "10132A", "1013A", "10144A", "10146A", "1014A", "1015", 
"10153A", "10156A", "10159A", "10161A", "1017", "10171A", "10175A", 
"10178A", "1018", "10186A"), whz1 = c(0, 1, 0, 0, 0, 0, 0, 1, 
0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0
), whz2 = c(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 
0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0), whz3 = c(0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 
0, 0, 0), whz4 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), whz5 = c(0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 
0, 0, 0, 0, 0, 0), PAM_complete = c("ETW", "ETW", "NWZ", "NWZ", 
"LOW", "NWZ", "NWZ", "INT", "NWZ", "ETW", "NWZ", "PEW", "ETW", 
"INT", "NWZ", "INT", "ETW", "NWZ", "ETW", "ETW", "NWZ", "ETW", 
"ETW", "NWZ", "NWZ", "NWZ", "NWZ", "NWZ", "NWZ", "PEW", "NWZ", 
"ETW", "NWZ", "INT", "NWZ", "INT", "NWZ", "INT", "NWZ", "LOW", 
"PEW", "NWZ", "NWZ", "INT", "ETW", "NWZ", "ETW", "NWZ", "ETW", 
"NWZ")), row.names = c(NA, -50L), class = c("tbl_df", "tbl", 
"data.frame"))
> 
 

Комментарии:

1. Я не понимаю, что означает «я бы хотел, чтобы цвета строк аннотаций (5 категорий) совпадали с точками данных». Можете ли вы сделать приблизительный набросок окончательной версии, которую вы пытаетесь получить?

2. Спасибо за ваш ответ! В самом левом углу вы можете увидеть полосу, разделенную на пять различных цветов. Это мои категории кластеров. Там, где находится розовая полоса (т.Е. Категория кластера = ETW), я хочу, чтобы все точки данных справа от этой полосы (whz1-whz5) также были розовыми, когда переменная whz = 1. Где whz = 0, это белый. Все точки данных в категории NWZ равны 0, и поэтому мы не увидим никаких соответствующих данных того же оттенка синего. Надеюсь, это понятнее!

Ответ №1:

Если я вас правильно понял, у вас есть график «B» ниже, но вам нужен график «A» (без небольших промежутков между графиками). Это непростая задача с использованием пакета pheatmap. Подход, который я использовал для создания графика «A» ниже, может быть подходящим с некоторой настройкой (в основном, нанесите каждую группу отдельно, а затем вставьте их все вместе в столбец). В противном случае ниже приведен более простой метод ggplot.

 library(tidyverse)
library(pheatmap)
library(cowplot)

spells2 <- as.data.frame(spells) %>%
  arrange(PAM_complete)

#Df for wheeze columns
whz <- spells2 %>%
  dplyr::select(2:6)

#Create separate df for cluster  
c5 <- spells2$PAM_complete %>% 
  as.data.frame()
colnames(c5) <- "names"

#Wheeze and cluster need the same row names (id)
rownames(whz) <- spells2$id
rownames(c5) <- spells2$id

c5$names <- as.factor(c5$names)

combined <- cbind(c5, whz)

# To get the 'default' pheatmap colour scheme
gg_color_hue <- function(n) {
  hues = seq(15, 375, length = n   1)
  hcl(h = hues, l = 75, c = 100)[1:n]
}
scales::show_col(gg_color_hue(5))

# Specify colours for each group
ann_colors = list(
  names = c(ETW = "#FF9289", INT = "#FF8AFF",
            LOW = "#00DB98", NWZ = "#00CBFF",
            PEW = "#BEC100"))


# Generate the plots
col = c("grey95", "darkblue")
p <- pheatmap(whz, legend_breaks = 0:1,
         legend_labels = c("No wheeze", "Wheeze"),
         fontsize = 10, show_rownames = FALSE,
         cluster_rows = FALSE, color = col,
         cluster_cols = FALSE, annotation_row = c5)

col_1 <- c("grey95", "#FF9289")
p1 <- pheatmap(combined %>% filter(names == "ETW") %>% select(-c(names)),
         show_rownames = FALSE, show_colnames = FALSE,
         cluster_rows = FALSE, cluster_cols = FALSE,
         legend = FALSE, annotation_legend = FALSE,
         color = col_1, annotation_names_row = FALSE,
         annotation_colors = ann_colors, 
         annotation_row = combined %>% filter(names == "ETW") %>% select(names))

col_2 <- c("grey95", "#FF8AFF")
p2 <- pheatmap(combined %>% filter(names == "INT") %>% select(-c(names)),
         show_rownames = FALSE, show_colnames = FALSE,
         cluster_rows = FALSE, cluster_cols = FALSE,
         legend = FALSE, annotation_legend = FALSE,
         color = col_2, annotation_names_row = FALSE,
         annotation_colors = ann_colors, cellheight = 7,
         annotation_row = combined %>% filter(names == "INT") %>% select(names))

col_3 <- c("grey95", "#00DB98")
p3 <- pheatmap(combined %>% filter(names == "LOW") %>% select(-c(names)),
               show_rownames = FALSE, show_colnames = FALSE,
               cluster_rows = FALSE, cluster_cols = FALSE,
               legend = FALSE, annotation_legend = FALSE,
               color = col_3, annotation_names_row = FALSE,
               annotation_colors = ann_colors,
               annotation_row = combined %>% filter(names == "LOW") %>% select(names))

# Because all whz values = 0 for NWZ,
# you need to change one value to '1'
# in order for pheatmap to generate a plot
combined[23,2] <- 1

col_4 <- c("grey95", "grey95")
p4 <- pheatmap(combined %>% filter(names == "NWZ") %>% select(-c(names)),
               show_rownames = FALSE, show_colnames = FALSE,
               cluster_rows = FALSE, cluster_cols = FALSE,
               legend = FALSE, annotation_legend = FALSE,
               color = col_4, annotation_names_row = FALSE,
               annotation_colors = ann_colors,
               annotation_row = combined %>% filter(names == "NWZ") %>% select(names))

col_5 <- c("grey95", "#BEC100")
p5 <- pheatmap(combined %>% filter(names == "PEW") %>% select(-c(names)),
               show_rownames = FALSE,
               cluster_rows = FALSE, cluster_cols = FALSE,
               legend = FALSE, annotation_legend = FALSE,
               color = col_5,
               annotation_colors = ann_colors,
               annotation_row = combined %>% filter(names == "PEW") %>% select(names))

heatmaps <- cowplot::plot_grid(p1[[4]], p2[[4]], p3[[4]],
                   p4[[4]], p5[[4]], ncol = 1,
                   rel_heights = c(1.3, 0.7, 0.3, 2.4, 0.8))
cowplot::plot_grid(heatmaps, p$gtable, ncol = 2, rel_widths = c(0.7, 1), labels = "AUTO")
 

пример_1.png

Редактировать

Если вы не обязательно хотите использовать тепловую карту, ggplot2 geom_tile() было бы намного проще, например

 library(tidyverse)

my_levels <- rownames(combined)
my_colours <- c("#FF9289", "#FF8AFF", "#00DB98", "#00CBFF", "#BEC100")

combined %>%
  rownames_to_column(var = "IDs") %>% 
  pivot_longer(cols = -c(IDs, names),
               names_to = "Trial",
               values_to = "Wheeze") %>%
  rename(Group = names) %>% 
  mutate(IDs = factor(IDs, levels = my_levels)) %>% 
  ggplot()  
  geom_tile(aes(y = rev(IDs),
                x = Trial,
                fill = Group,
                alpha = Wheeze),
            color = "black")  
  scale_alpha_continuous(breaks = c(0, 1),
                         labels = c("No", "Yes"))  
  scale_fill_manual(values = my_colours)  
  theme_minimal()  
  theme(panel.grid = element_blank())
 

пример_3.png

РЕДАКТИРОВАТЬ 2

Чтобы включить панель «аннотации» перед графиком, вы можете использовать это:

 combined %>%
  rownames_to_column(var = "IDs") %>% 
  pivot_longer(cols = -c(IDs, names),
               names_to = "Trial",
               values_to = "Wheeze") %>%
  rename(Group = names) %>% 
  mutate(IDs = factor(IDs, levels = my_levels)) %>% 
  ggplot()  
  geom_tile(aes(y = rev(IDs),
                x = Trial,
                fill = Group,
                alpha = Wheeze),
            color = "black")  
  geom_tile(aes(x = -0.1, y = rev(IDs), fill = Group),
            show.legend = FALSE)  
  coord_cartesian(c(0.8, 5))  
  scale_fill_manual(values = my_colours)  
  scale_alpha_continuous(breaks = c(0, 1),
                         labels = c("No", "Yes"))  
  theme(plot.margin=unit(c(1,0,0,0), units="lines"))
 

пример_4.png

Я не смог обозначить это как «Группы», но я полагаю, что это возможно, если вы повозитесь с этим.

Комментарии:

1. Это выглядит великолепно и то, чего я пытаюсь достичь! Пробелы работают хорошо. Я выполню это сейчас и вернусь к этому сообщению.

2. для p4 я получил следующую ошибку: Error in cut.default(x, breaks = breaks, include.lowest = T) : 'breaks' are not unique

3. Извините — я понял, почему у меня возникла ошибка. Большое вам спасибо за время и мысли, которые вы посвятили этому.

4. Спасибо за редактирование с помощью geom_tile, это здорово! Я принял ваш ответ.

5. Вы можете включить столбец с цветами, но я не могу пометить его как «Группу», не отключив обрезку — см. Редактирование выше