我有以下数据:
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")我已经创建了以下图表:
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()

有没有办法重新排列图例,以便在每个域下面列出属于特定域的门?换句话说,我想把属性域(及其相关颜色)放在属于它的每一组门的头部。
此外,最好在图例中保留图例标题“域”和“门”,与不同的域和门相对应。
说到底,图例应该是这样的:

谢谢!
发布于 2020-09-27 16:36:51
也许这就是你要找的。要按域对phyla进行分组,您可以
中使用code>的
最后,我不确定你所说的“……在图例中保留图例标题‘域’和‘门’是什么意思”。因此,我只需将域名放在图例标题中。
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))

发布于 2020-09-27 22:10:06
再试一次。由于答案采用了与第一个不同的方法,因此我将其作为第二个答案发布。此外,即使是第二种解决方案也不是完美的。的主要缺点是它只适用于等宽字体。
一般的想法是坚持使用您的绘图代码,但填充数据,以便每个域包含相同数量的门或类别。这样做可以按域按列排列门类。对于空的或辅助的类别,我将填充颜色设置为透明,并使用labeller函数将标签设置为空字符串,以便它们不会出现在图例中。
然而,棘手的部分是将域图例的图例键与门图例的键对齐。问题是图例的宽度由标签的长度和所选的字体决定。要使所有标签的长度相同,我们可以添加额外的空格。但是,标签的宽度仍将根据所选字体的不同而不同(默认情况下:"sans")。不幸的是,除了等宽字体的情况外,我不知道有什么简单的方法来解决这个问题。在这种情况下,长度等同于宽度,只需向标签添加额外的空格就足以确保域图例的项与门图例中的项对齐。
library(ggplot2)
library(ggnewscale)
library(tidyr)
library(dplyr)
library(stringr)
d <- df1 %>%
group_by(Domain) %>%
mutate(rank = row_number(Phylum),
max_len = max(nchar(Phylum))
) %>%
ungroup() %>%
complete(Domain, rank, fill = list(ymin = 0, ymax = 0, xmin = 0, xmax = 0, Phylum = "empty")) %>%
fill(max_len) %>%
mutate(Phylum = if_else(Phylum == "empty", paste0(Domain, rank), Phylum),
Phylum = if_else(str_detect(Phylum, "\\d$"), str_pad(Phylum, max_len, "left"), str_pad(Phylum, max_len, "right")),
Domain = str_pad(Domain, max_len, "right"))
is_empty <- str_detect(d$Phylum, "\\d$")
empty_cat <- d$Phylum[is_empty]
non_empty_cat <- d$Phylum[!is_empty]
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(d$Domain))
Phyla_Colors <- setNames(Phyla_Colors, non_empty_cat)
colors <- c(Domain_Colors, Phyla_Colors)
colors <- setNames(colors, names(colors))
colors <- c(colors, setNames(rep("transparent", length(empty_cat)), empty_cat))
breaks_phylum <- d %>%
arrange(Domain, rank) %>%
pull(Phylum)
breaks <- c(unique(d$Domain), breaks_phylum)
mylabels <- function(breaks) {
if_else(str_detect(breaks, "\\d$"), "", breaks)
}
ggplot(d) +
geom_rect(aes(fill = Domain, ymax = ymax, ymin = ymin, xmax = 2, xmin = 0)) +
scale_fill_manual(aesthetics = "fill", breaks = breaks, values = colors, labels = mylabels,
guide = guide_legend(title = "Domain", order = 1, nrow = 1)) +
new_scale_fill() +
geom_rect(aes(fill = Phylum, ymax = ymax, ymin = ymin, xmax = 2, xmin = 0)) +
scale_fill_manual(aesthetics = "fill", breaks = breaks, values = colors, labels = mylabels,
guide = guide_legend(title = "Phylum", order = 0, nrow = 7)) +
coord_polar(theta = "y") +
theme_void(base_family = "mono") +
theme(legend.text=element_text(size = 4),
legend.title=element_text(size = 6, vjust = 1),
legend.position = "bottom",
legend.box = "vertical",
legend.box.just = "left")

https://stackoverflow.com/questions/64082907
复制相似问题