计算距离并添加线ggplot [英] compute distance and add lines ggplot

查看:50
本文介绍了计算距离并添加线ggplot的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to figure out a better way to make the graph below without manually typing the distances and line segments in ggplot. The code below will create the graph, but the lines and text call outs are manual tasks and won't work for large datasets which i'm working with.

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)


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

Yes, i would want to label more than just the two segements. Most of the Dots will be on the same/similar y axis positioning by grouping, for example all red dots will lie on 2 and green dots on 3.5 and blue dots on 6. Sorry for not clarifying, I wanted to provide a simpler problem. The pattern could be different, for instance there might be a middle row between the two.

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

I've added another chart to better explain my problem.

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

推荐答案

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

I would approach this using a function that takes index values as an input and adds the segments and text accordingly. To add put multiple layers to ggplot, you put the layers into a list.

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

I have not yet figured out a good way to approach the part of your question about creating secondary lines between lines (like the vertical lines in your example), but it should help start you on your way.

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

Here's a function that takes index values and uses those to specify the locations for a segment and text that reflects the distance.

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

我们可以使用它来指定一个细分&一次贴上标签...

We could use this to specify one segment & label at a time...

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

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

or use vectors to specify a bunch at one go:

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

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

And we can feed in vectors of starting and ending indices to get all the dot-to-dot lines in your example:

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

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

Adding the vertical lines will take more thought. Curious if others have good ideas for how to approach that.

这篇关于计算距离并添加线ggplot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆