使用facet_wrap和free_x在ggplot2中的每个方面保留x轴中断和element_markdown规范

问题描述 投票:0回答:1

假设我在下面的 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()

fig1

现在我有一些其他类似的序列及其数据存储在列表中,如下面 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()

fig2

r ggplot2 axis facet facet-wrap
1个回答
0
投票

这是一个可能的选项,它使用

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")
  )

© www.soinside.com 2019 - 2024. All rights reserved.