假设我在下面的 MWE 中有
final_df
数据框,我使用来自 scale_x_continuous
的自定义 element_markdown
和 ggtext
在其下方绘制了图。
myseq <- "AGAATATTATACATTCATCT"
set.seed(123)
mydata <- data.frame(time=1:100, value=rnorm(100, mean=10, sd=2))
indices <- seq(5, 100, length.out=20)
seqsplit <- unlist(strsplit(myseq, ""))
ind_df <- data.frame(call=seqsplit, time=indices)
final_df <- dplyr::left_join(mydata, ind_df, by="time")
xcolors <- ifelse(seqsplit=="A", "green", ifelse(seqsplit=="C", "blue", ifelse(seqsplit=="G", "black", "red")))
P <- ggplot2::ggplot(final_df, ggplot2::aes(x=time, y=value)) +
ggplot2::geom_line(linewidth=0.5) +
ggplot2::scale_x_continuous(breaks=indices, labels=seqsplit) +
ggplot2::theme_light() +
ggplot2::theme(axis.title.x=ggplot2::element_blank(),
axis.text.x=ggtext::element_markdown(face="bold", color=xcolors))
grDevices::pdf(file="test.pdf", height=3, width=10)
print(P)
grDevices::dev.off()
现在我有一些其他类似的序列及其数据存储在列表中,如下面 MWE 中的
mylist
。
我想制作一个分面图,其中每个分面对应一个序列,并且分面中的每个图与上面的单个示例图相同,保留每个 x 轴中的自定义中断和标签以及字母颜色。
我怎样才能做到这一点?这就是我所在的位置(有问题的行已被注释掉):
mylist <- list()
mylist[["ID1"]][["sequence"]] <- "AGAATATTATACATTCATCT"
mylist[["ID2"]][["sequence"]] <- "GCTAGCGTTTAGTTT"
mylist[["ID3"]][["sequence"]] <- "AACCCTTTAGTA"
set.seed(123)
mylist[["ID1"]][["data"]] <- data.frame(time=1:100, value=rnorm(100, mean=10, sd=2))
mylist[["ID2"]][["data"]] <- data.frame(time=1:60, value=rnorm(60, mean=10, sd=2))
mylist[["ID3"]][["data"]] <- data.frame(time=1:120, value=rnorm(120, mean=10, sd=2))
mylist[["ID1"]][["indices"]] <- seq(5, 100, length.out=20)
mylist[["ID2"]][["indices"]] <- seq(4, 60, length.out=15)
mylist[["ID3"]][["indices"]] <- seq(10, 120, length.out=12)
all_df <- NULL
for (id in names(mylist)){
seqsplit <- unlist(strsplit(mylist[[id]][["sequence"]], ""))
ind_df <- data.frame(call=seqsplit, time=mylist[[id]][["indices"]])
finaldf <- dplyr::left_join(mylist[[id]][["data"]], ind_df, by="time")
finaldf$id <- id
xcolors <- ifelse(seqsplit=="A", "green", ifelse(seqsplit=="C", "blue", ifelse(seqsplit=="G", "black", "red")))
all_df <- rbind(all_df, finaldf)
}
P <- ggplot2::ggplot(all_df, ggplot2::aes(x=time, y=value)) +
ggplot2::geom_line(linewidth=0.5) +
#ggplot2::scale_x_continuous(breaks=indices, labels=seqsplit) + #HOW?
ggplot2::theme_light() +
ggplot2::facet_wrap(~id, ncol=1, scales="free_x", strip.position="left")
#ggplot2::theme(axis.title.x=ggplot2::element_blank(),
# axis.text.x=ggtext::element_markdown(face="bold", color=xcolors)) #HOW?
grDevices::pdf(file="test_all.pdf", height=6, width=10)
print(P)
grDevices::dev.off()
这是一个可能的选项,它使用
ggh4x::facetted_pos_scales
单独设置每个方面的比例(又名 breaks
和 labels
),而不是通过 theme()
传递颜色向量,使用 ggtext
的功能来使用一些 HTML 和 CSS 设置文本样式,即我直接将颜色添加到标签中:
library(ggplot2)
library(ggtext)
library(ggh4x)
library(dplyr, warn = FALSE)
library(glue)
scale_x <- purrr::map(mylist, \(x) {
indices <- x$indices
seqsplit <- unlist(strsplit(x$sequence, ""))
colors <- dplyr::case_match(
seqsplit,
"A" ~ "green",
"C" ~ "blue",
"G" ~ "black",
.default = "red"
)
labels <- glue::glue(
"<span style='color: {colors}'>{seqsplit}</span>"
)
scale_x_continuous(
breaks = indices, labels = labels
)
})
ggplot2::ggplot(all_df, ggplot2::aes(x = time, y = value)) +
ggplot2::geom_line(linewidth = 0.5) +
ggplot2::theme_light() +
ggplot2::facet_wrap(~id,
ncol = 1,
scales = "free_x", strip.position = "left"
) +
ggh4x::facetted_pos_scales(
x = scale_x
) +
ggplot2::theme(
axis.title.x = ggplot2::element_blank(),
axis.text.x = ggtext::element_markdown(face = "bold")
)