r - 计算距离并添加线条ggplot
问题描述
我试图找出一种更好的方法来制作下图,而无需在 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)
是的,我想标记的不仅仅是两个部分。大多数点将通过分组位于相同/相似的 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')
解决方案
我会使用一个函数来解决这个问题,该函数将索引值作为输入并相应地添加段和文本。要将多个图层添加到 中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)
或使用向量一次性指定一堆:
ggplot(df,aes(x,y,color=z)) +
geom_point(size = 5) +
add_annotation(2, c(1,3:9))
我们可以输入起始和结束索引的向量,以获取示例中的所有点对点线:
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))
添加垂直线需要更多的思考。好奇其他人是否对如何解决这个问题有好的想法。
推荐阅读
- python - Python 找不到嵌套包 - ModuleNotFoundError
- reactjs - 如何从 React-east-state 中的 autoEffect 中排除商店元素?
- python - 如何使用 tf.argmax 的结果来访问对应位置的值?
- python - 对于每 1000 行,插入新的递增日期 python pandas
- python - 在 git repo 中获取特定本地文件的所有提交
- javascript - 从 JSON 获取数据到 JS
- html - Navbar-固定响应式导航栏
- statistics - 如何在 SAS 中使用 proc 报表调整发布式报表?
- react-native - React Native:有没有办法通过 ref 向元素添加事件监听器?
- python - python web抓取soup.find给空