【问题标题】:One line plot per row for multiple rows (ggplot or base R?)多行每行一个线图(ggplot 或 base R?)
【发布时间】:2017-10-27 22:21:50
【问题描述】:

我有以下数据框:

test_new <- structure(list(PS_position = c(12871487, 12997222, 12861487, 
 12871491, 12934355), Region_ID = structure(c(1L, 1L, 2L, 2L, 
 1L), .Label = c("D", "D_left", "D_right"), class = "factor"), 
 chr_key = c(1, 1, 1, 1, 1), start = c(12871487, 12871487, 
 12871487, 12871487, 12871487), stop = c(12997222, 12997222, 
 12997222, 12997222, 12997222), exact_center = c(12934355, 
 12934355, 12934355, 12934355, 12934355)), .Names = c("PS_position", 
 "Region_ID", "chr_key", "start", "stop", "exact_center"), row.names = c(1L, 
 2L, 3L, 4L, 7L), class = "data.frame")

我想每行绘制一个图,其中每个区域的 start、stop 和 center 保持不变,并且 PS_position 被逐个添加为一个点,如下所示(单词不需要在图上出现,并且PS_position 标记可以是其他任何东西):

这在 ggplot 中作为 geom_vline() 和 geom_hline() 很难做到:

ggplot(test_new) + geom_vline(xintercept = 12871487) + geom_vline(xintercept = 12997222) + geom_vline(xintercept = 12934355)

所以我用一个例子尝试了base R:

plot(1,1)
lines(c(0.8, 1.2), c(0.6, 0.6))
abline(v = 1, col = "gray60")
abline(v=1.2, col = "gray60")
abline(v=0.8, col = "gray60")

显然,这些策略距离理想的情节还有很长的路要走。所以我的问题是如何最好地为单行制作所需的图,以及如何对其进行迭代以保持前一行的点?

非常感谢!

【问题讨论】:

  • 你想迭代地分别构建每一步的情节吗?
  • 嗨!是的,我想要每行数据帧一个图,保持前一行/上一个图的开始、停止、精确中心和 PS_position。谢谢!

标签: r plot ggplot2


【解决方案1】:
Reduce(
  function(plot, position) {
    plot + annotate(
      geom = "point", 
      x = position, y = 1, 
      shape = 18, size = 5)
  }, 
  test_new$PS_position, 
  init = ggplot() + 
    theme_minimal() +
    theme(
      panel.grid =element_blank(),
      axis.text = element_blank(),
      axis.line = element_blank()) +
    labs(x = NULL, y = NULL) +
    geom_vline(xintercept = c(12871487, 12934355, 12997222), color = "red"),
  accumulate = TRUE)

将构建一个带有迭代添加点的绘图列表,看起来非常接近您的想法,最后一个绘图看起来像这样

编辑

使用 dplyr、tidyr 和 purrr 按数据框分组。这只是按 Region_ID 分组,为列中的每个数据框嵌套和运行相同的归约

library(dplyr)
library(purrr)
library(tidyr)

test_new %>%
  group_by(Region_ID) %>%
  nest() %>%
  mutate(plots = map(data, ~Reduce(
    function(plot, position) {
      plot + annotate(
        geom = "point", 
        x = position, y = 1, 
        shape = 18, size = 5)
    }, 
    .$PS_position, 
    init = ggplot() + 
      theme_minimal() +
      theme(
        panel.grid =element_blank(),
        axis.text = element_blank(),
        axis.line = element_blank()) +
      labs(x = NULL, y = NULL) +
      geom_vline(xintercept = c(12871487, 12934355, 12997222), color = "red"),
    accumulate = TRUE)))

【讨论】:

  • 太酷了!谢谢!但是,有两个问题:i。每行可以有 1 个独立的情节。所以上面的例子总共有 5 个图。 ii.不同区域的 xintercept 变化是什么。它能否打破并为下一个区域绘制一系列新的情节。我将更新我的示例以反映这一点。
  • 我在上面编辑了我的输入示例。那么它可以为区域 D 绘制不同系列的图,为区域 D_left 绘制另一系列的图吗?谢谢!
  • 关于第二条评论,请参阅我更新的答案,不确定我是否理解第一个问题,您是否希望它不累积?
  • 嗨罗宾,请忽略第一个问题,您的解决方案工作得很好。我已接受您的解决方案。我确实有最后一个问题。如何将此对象列表保存为 pdf?在将您的代码输出命名为list:library(gridExtra) pdf("plots.pdf", onefile = TRUE) for (i in seq(length(list))) { do.call("grid.arrange", list[[i]]) } dev.off() 后,我尝试了以下操作,但它会引发错误:only 'grobs' allowed in "gList" 即使列表中的每个项目都是ggplot 对象?谢谢*n
  • 如果您遍历列表,您将遍历列。对于您的 do.callgrid.arrange,您将提供 list$plots[[i]] 而不是 list[[i]]
猜你喜欢
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多