计算距离并添加线ggplot

时间:2019-01-31 04:22:47

标签: r ggplot2

我正在尝试找到一种更好的方法来制作下面的图,而无需在ggplot中手动键入距离和线段。下面的代码将创建图形,但是线条和文本标注是手动任务,不适用于我正在使用的大型数据集。

df<- data.frame(x=c(1,2,3,4,5,6,7,8,9),y=c(2,5,2,5,2,5,2,5,2),z=c('a','b','a','b','a','b','a','b','a'))

ggplot(df,aes(x,y,color=z))+geom_segment(aes(x = 2, y = 2, xend = 2, yend = 5),color='blue',size=1)+
  geom_segment(aes(x = 1, y = 2, xend = 3, yend = 2),color='blue',size=1)+
  geom_point(size=5)+scale_x_continuous(breaks = c(1,2,3,4,5,6,7,8,9,10,11))+
  annotate("text", x = 2, y = 2, label = "2 feet",size=6)+
  annotate("text", x = 2, y = 3.5, label = "3 feet",size=6)


graph

是的,我不仅要标记两个部分。通过分组,大多数点将在相同/相似的y轴上定位,例如,所有红点将位于2上,绿点位于3.5上,蓝点位于6上。抱歉,我想提供一个简单的问题。模式可能有所不同,例如,两者之间可能存在中间行。

我添加了另一个图表以更好地解释我的问题。

df<- data.frame(x=c(1,2,1,3,3,3.5,5,6,5),y=c(2,3.5,6,2,3.5,6,2,3.7,6),z=c('a','b','c','a','b','c','a','b','c'))

ggplot(df,aes(x,y,color=z))+geom_segment(aes(x = 2, y = 2, xend = 2, yend = 3.5),color='blue',size=1)+
  geom_segment(aes(x = 1, y = 2, xend = 3, yend = 2),color='blue',size=1)+
  geom_segment(aes(x = 2, y = 3.5, xend = 2, yend = 6),color='blue',size=1)+
  geom_segment(aes(x = 1, y = 6, xend = 3.5, yend = 6),color='blue',size=1)+
  geom_segment(aes(x = 2, y = 3.5, xend = 6, yend = 3.5),color='blue',size=1)+
  geom_point(size=5)+scale_x_continuous(breaks = c(1,2,3,4,5,6,7,8,9,10,11))+
  annotate("text", x = 2, y = 2, label = "2 feet",size=5)+
  annotate("text", x = 2, y = 2.75, label = "1.5 feet",size=5)+
  annotate("text", x = 2, y = 4.75, label = "2.5 feet",size=5)+
  annotate("text", x = 2.2, y = 6.2, label = "2.5 feet",size=5)+
  annotate("text", x = 2.5, y = 3.6, label = "1 foot",size=5)+
  annotate("text", x = 4.5, y = 3.6, label = "3 feet",size=5)+
  expand_limits(y = c(1, 7))+scale_y_continuous(breaks = c(1,2,3,4,5,6,7))+
  theme_bw()+  theme(legend.position = 'bottom')

extended

1 个答案:

答案 0 :(得分:1)

我将使用一个函数来实现这一点,该函数将索引值作为输入并相应地添加段和文本。要将放置多个图层添加到ggplot,请将图层放入列表。

对于在线之间创建辅助线(例如示例中的垂直线)的问题,我还没有找到一种好的方法,但这应该可以帮助您入门。

这是一个获取索引值并使用这些值指定段和文本的位置以反映距离的函数。

add_annotation <- function(index1, index2) {
  x1 = df[index1, 1]   # x1/x2/y1/y2 defined here for shorthand later
  x2 = df[index2, 1]
  y1 = df[index1, 2]
  y2 = df[index2, 2]

  # the function will return the last object it creates, ie this list with two objects
  list(            
    annotate("segment", color = "blue",
      x = x1, xend = x2,
      y = y1, yend = y2),

    annotate("text", color = "black", size = 5,
      x = (x1 + x2) / 2, y = (y1 + y2) / 2,
      label = paste(
        round(sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2), digits = 1),
        "feet")
    )
  )
}

我们可以使用它一次指定一个细分和标签...

ggplot(df,aes(x,y,color=z)) + 
  geom_point(size = 5) +
  add_annotation(2, 1)

enter image description here

或使用向量一次指定一束:

ggplot(df,aes(x,y,color=z)) + 
  geom_point(size = 5) +
  add_annotation(2, c(1,3:9))

enter image description here

我们可以输入起点和终点索引的向量,以获取示例中的所有点对点线:

ggplot(df,aes(x,y,color=z)) + 
  geom_point(size = 5) +
  add_annotation(index1 = c(1, 2, 3, 5), 
                 index2 = c(4, 5, 6, 8))

enter image description here

添加垂直线将需要更多的思考。好奇别人是否对如何解决这个问题有好主意。