【问题标题】:how to prevent an overlapped segments in geom_segment如何防止 geom_segment 中的重叠段
【发布时间】:2020-11-15 19:28:33
【问题描述】:

我正在尝试使用geom_segment 将不同的范围(线)映射到图中的不同区域(见下文),但某些范围重叠并且根本无法显示。 这是数据框的一个最小示例:

start = c(1, 5,8, 14)
end =c(3, 6,12, 16)
regions = c(1,2,3, 4)

regions = data_frame(regions, start, end)

from = c(1,2, 5.5, 13.5)
to = c(3,2.5,6, 15)

lines = data_frame(from, to)

我用geom_rect 绘制区域,然后用geom_segment 绘制范围(线)。 剧情是这样的:

plot_splice <- ggplot() +
  scale_x_continuous(breaks = seq(1,16)) +
  scale_y_continuous() +
  geom_hline(yintercept = 1.6,
             size = 20,
             alpha = 0.1) +
  geom_rect(
    data = regions,
    mapping = aes(
      xmin = start,
      xmax = end,
      ymin = 1.5,
      ymax = 1.8,
    )) +
  geom_segment(
    data = lines,
    x = (lines$from),
    xend = (lines$to),
    y = 1.48,
    yend = 1.48,
    colour = "red",
    size = 3
    ) +
  ylim(1.0, 2.2) + 
  xlab("") +
  theme_minimal() 

第一个图是使用代码生成的图,而第二个图是所需的图。

如您所见,第二行与第一行重叠,因此您根本看不到第二行。

如何更改代码以生成第二个图?

我正在尝试使用 ifelse 语句,但不确定 test 参数应该是什么: 我希望它检查每个范围(线)是否与任何先前的范围(线)重叠以将y 位置更改为.05 左右,因此它不会重叠。

lines <- lines %>% 
  dplyr::arrange(desc(from))

new_y$lines = ifelse(from[1] < to[0], 1.48, 1.3)

geom_segment(
    data = lines,
    x = (lines$from),
    xend = (lines$to),
    y = new_y,
    yend = new_y,
    colour = "red",
    size = 3
    )

【问题讨论】:

    标签: r if-statement ggplot2 data-visualization geom-segment


    【解决方案1】:

    您的geom_segment 调用未使用任何美学映射,这是您通常如何让 ggplot 元素根据特定变量(或一组变量)更改位置的方式。

    最好在调用 ggplot 之前根据重叠区域的数量计算 geom_segment 的堆叠。这允许您将 x 和 y 值传递到美学映射中:

    # First ensure that the data feame is ordered by the start time
    lines <- lines[order(lines$from),]
    
    # Now iterate through each row, calculating how many previous rows have
    # earlier starts but haven't yet finished when the current row starts.
    # Multiply this number by a small negative offset and add the 1.48 baseline value
    lines$offset <- 1.48 - 0.03 * sapply(seq(nrow(lines)), function(i) {
       with(lines[seq(i),], length(which(from < from[i] & to > from[i])))
       })
    

    现在做同样的情节,但在geom_segment内部使用美学映射:

     ggplot() +
      scale_x_continuous(breaks = seq(1,16), name = "") +
      scale_y_continuous(limits = c(1, 2.2), name = "") +
      geom_hline(yintercept = 1.6,
                 size = 20,
                 alpha = 0.1) +
      geom_rect(
        data = regions,
        mapping = aes(
          xmin = start,
          xmax = end,
          ymin = 1.5,
          ymax = 1.8,
        )) +
      geom_segment(
        data = lines,
        mapping = aes(
          x = from, 
          xend = to, 
          y = offset, 
          yend = offset),
        colour = "red",
        size = 3
        ) +
      theme_minimal()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2020-05-09
      相关资源
      最近更新 更多