重新排列“ggplot2”图例以混合和匹配不同级别

Dav*_*ore 7 r ggplot2

我有以下数据:

df1 <- structure(list(Wastewater_Treatment_Plant = c("D_S1_L001_R1_001", 
"D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", 
"D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", 
"D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", 
"D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", "D_S1_L001_R1_001", 
"D_S1_L001_R1_001"), Domain = c("Archaea", "Archaea", "Archaea", 
"Archaea", "Archaea", "Bacteria", "Bacteria", "Bacteria", "Bacteria", 
"Bacteria", "Bacteria", "Bacteria", "Eukaryota", "Eukaryota", 
"Eukaryota", "Eukaryota", "Other Sequences", "Viruses"), Phylum = c("Crenarchaeota", 
"Euryarchaeota", "Korarchaeota", "Nanoarchaeota", "Thaumarchaeota", 
"Acidobacteria", "Actinobacteria", "Aquificae", "Bacteroidetes", 
"Candidatus Poribacteria", "Chlamydiae", "Chlorobi", "Streptophyta", 
"Xanthophyceae", "unclassified (derived from Eukaryota)", "unclassified (derived from Fungi)", 
"unclassified (derived from other sequences)", "unclassified (derived from Viruses)"
), Alignment_Length = c(3573, 34060, 257, 22, 525, 85973, 670251, 
8825, 1040376, 1273, 5962, 41954, 13026, 5, 15129, 48, 528, 3451
), Relative_Alignment_Length = c(0.00185587444253646, 0.0176913192031323, 
0.000133489989289636, 1.14271586162334e-05, 0.000272693557887388, 
0.044655777623338, 0.348139294985867, 0.00458384885401182, 0.540388253296476, 
0.000661216950839325, 0.00309675998499926, 0.0217915914811571, 
0.00676591673341166, 2.59708150368941e-06, 0.00785824921386343, 
2.49319824354184e-05, 0.000274251806789602, 0.00179250565384643
), ymax = c(0.00185587444253646, 0.0195471936456687, 0.0196806836349584, 
0.0196921107935746, 0.019964804351462, 0.0646205819748, 0.412759876960667, 
0.417343725814679, 0.957731979111154, 0.958393196061993, 0.961489956046993, 
0.98328154752815, 0.990047464261561, 0.990050061343065, 0.997908310556929, 
0.997933242539364, 0.998207494346154, 1), ymin = c(0, 0.00185587444253646, 
0.0195471936456687, 0.0196806836349584, 0.0196921107935746, 0.019964804351462, 
0.0646205819748, 0.412759876960667, 0.417343725814679, 0.957731979111154, 
0.958393196061993, 0.961489956046993, 0.98328154752815, 0.990047464261561, 
0.990050061343065, 0.997908310556929, 0.997933242539364, 0.998207494346154
)), row.names = c(NA, -18L), class = c("tbl_df", "tbl", "data.frame"
))
Domain_Colors <- c("orange", "blue", "grey", "green", "purple")
Phyla_Colors <- c("#FEEDDE", "#FDBE85", "#FD8D3C", "#E6550D", "#A63603", "#440154FF", 
"#443A83FF", "#31688EFF", "#21908CFF", "#35B779FF", "#8FD744FF", 
"#FDE725FF", "#4D4D4D", "#969696", "#C3C3C3", "#E6E6E6", "green1", 
"purple1")
Run Code Online (Sandbox Code Playgroud)

我创建了以下图表:

if (!require (dplyr)) {
  install.packages("dplyr")
}
library (dplyr)
if (!require (ggnewscale)) {
  install.packages("ggnewscale")
}
library (ggnewscale)
if (!require (ggplot2)) {
  install.packages("ggplot2")
}
library (ggplot2)
if (!require (tidyr)) {
  install.packages("tidyr")
}
library (tidyr)
ggplot(df1) +
  geom_rect(aes(fill = Domain, ymax = ymax, ymin = ymin, xmax = 2, xmin = 0)) +
  scale_fill_manual(aesthetics = "fill", values = Domain_Colors, breaks = unique(df1$Domain), name = "Domain") +
  new_scale_fill() +
  geom_rect(aes(fill = Phylum, ymax = ymax, ymin = ymin, xmax = 4, xmin = 2)) +
  scale_fill_manual(aesthetics = "fill", values = Phyla_Colors, breaks = unique(df1$Phylum), name = "Phylum") +
  coord_polar(theta = "y") +
  theme_void()
Run Code Online (Sandbox Code Playgroud)

示例图表

有没有办法重新排列图例,使得属于特定域的门列在每个域下?换句话说,我想将域(及其相关颜色)放在属于它的每组门的头部。

此外,最好在图例中保留图例标题“域”和“门”,对应于不同的域和门。

当一切都完成后,图例应如下所示:

最终传奇

谢谢!

ste*_*fan 3

也许这就是您正在寻找的。phyla要按域对您进行分组,您可以

  1. 单独绘制每个域(通过拆分或过滤数据集)并为每个域添加新的填充比例。
  2. 由于这是大量的手动工作(复制并粘贴代码 5 次),我使用一个函数为每个域添加图层,并使用 imap 循环遍历域。
  3. 为了获得域和门的正确颜色,我将所有颜色放入一个命名向量中。
  4. 设置填充比例的中断,使域首先出现,从而确保域位于每个图例的开头
  5. 为了设置图例的顺序,我使用guide_legendinside的 order 参数scale_fill_manual

最后,我不确定你的意思是“......在图例中保留图例标题‘Domain’和‘Phylum’”。所以我只是将域名放在图例标题中。

Domain_Colors <- c("orange", "blue", "grey", "green", "purple")
Phyla_Colors <- c("#FEEDDE", "#FDBE85", "#FD8D3C", "#E6550D", "#A63603", "#440154FF", 
                  "#443A83FF", "#31688EFF", "#21908CFF", "#35B779FF", "#8FD744FF", 
                  "#FDE725FF", "#4D4D4D", "#969696", "#C3C3C3", "#E6E6E6", "green1", 
                  "purple1")

Domain_Colors <- setNames(Domain_Colors, unique(df1$Domain))
Phyla_Colors <- setNames(Phyla_Colors, unique(df1$Phylum))

colors <- c(Domain_Colors, Phyla_Colors)
breaks_colors <- names(colors)

library(ggplot2)
library(ggnewscale)
library(purrr)
library(dplyr)

layers_help <- function(d, .domain, .order) {
  d <- filter(d, Domain == .domain)
  list(
    geom_rect(data = d, aes(fill = Domain, ymax = ymax, ymin = ymin, xmax = 2, xmin = 0)),
    geom_rect(data = d, aes(fill = Phylum, ymax = ymax, ymin = ymin, xmax = 4, xmin = 2)),
    scale_fill_manual(aesthetics = "fill", breaks = breaks_colors, values = colors, 
                      guide = guide_legend(title = .domain, order = as.integer(.order))),
    new_scale_fill()
  )
}

ggplot(df1) +
  imap(setNames(unique(df1$Domain), seq_along(unique(df1$Domain))), ~ layers_help(df1, .x, .y)) +
  coord_polar(theta = "y") +
  theme_void() +
  theme(legend.text=element_text(size = 4), legend.title=element_text(size = 6))
Run Code Online (Sandbox Code Playgroud)