R 围绕一组点绘制曲线

R 围绕一组点绘制曲线,r,graphics2d,curve,R,Graphics2d,Curve,我在平面上有一组点。它们被划分为子集。 我想围绕属于同一子集的点绘制一条闭合曲线,这样属于子集的点将位于曲线内部,而不属于子集的点将位于曲线外部。因此,简单的圆或凸包可能不起作用 对于初学者,假设我只想要一条围绕一组点的平滑曲线(不需要排除其他点) 有没有办法在R里做到这一点 ---后来添加--- 我最终要看的是这里图形的精神:-虽然上下文不是一个超图,而是一组给定的点和这些点的一个分区。在谷歌搜索之后,我很少修改这个例子 编辑 它将chull功能与bezier library(ggplot2)

我在平面上有一组点。它们被划分为子集。 我想围绕属于同一子集的点绘制一条闭合曲线,这样属于子集的点将位于曲线内部,而不属于子集的点将位于曲线外部。因此,简单的圆或凸包可能不起作用

对于初学者,假设我只想要一条围绕一组点的平滑曲线(不需要排除其他点)

有没有办法在R里做到这一点

---后来添加---


我最终要看的是这里图形的精神:-虽然上下文不是一个超图,而是一组给定的点和这些点的一个分区。

在谷歌搜索之后,我很少修改这个例子

编辑

它将chull功能与bezier

library(ggplot2)
library(plyr)
library(Hmisc)



df <- data.frame(x = rnorm(20), y = rnorm(20),z = sample(letters[1:5], 20, rep = T))
ggplot(df, aes(x, y, colour = z)) + geom_point()

find_hull <- function(df) {
    res.ch <- df[chull(df$x, df$y), ]
    res <- bezier(res.ch)
    res <- data.frame(x=res$x,y=res$y)
    res$z <- res$z
    res
  }
hulls <- ddply(df, "z", find_hull)
ggplot(df, aes(x, y, colour = z,fill = z)) +
  geom_point() + geom_polygon(data = hulls,alpha = 0.4)
库(ggplot2)
图书馆(plyr)
图书馆(Hmisc)

df好的,这里有一个版本的答案,我认为它与你所追求的很接近: 它使用了在GIS论坛上的这个答案()上创建的
spline.poly
函数

以下是一些示例点:

testpts <- 
structure(list(x = c(4.9, 4.2, 4, 4.1, 4.4, 5.8, 5.8, 5.8, 5.8, 
5.5, 4.9, 3.2, 3.2, 3.3, 5.4, 5.4, 5.7, 6.4, 6.7, 6.7, 6, 4.8, 
3.6, 2.8, 3.5, 4.4, 5.1, 4, 3.7, 4.5, 4.9, 5.7), y = c(6.9, 6.2, 
5.3, 4.1, 3.1, 2.9, 2.9, 3.5, 4.2, 4.9, 5.1, 4.9, 4.9, 5.2, 6.9, 
6.9, 5.3, 3.8, 4.2, 5.6, 6.9, 5.8, 1.2, 2.5, 5.3, 6.4, 6.8, 7.6, 
6.9, 5.4, 4.8, 4.4)), .Names = c("x", "y"))
生成并绘制ahull对象-在确定多边形与数据的拟合度时,alpha值似乎非常重要

ahull.obj <- ahull(testptsnodup,alpha=2)
plot(ahull.obj,add=TRUE,col="red",wpoints=FALSE)
ahull.obj简单地说:

testpts <- structure(list(x = c(4.9, 4.2, 4, 4.1, 4.4, 5.8, 5.8, 5.8, 5.8, 
5.5, 4.9, 3.2, 3.2, 3.3, 5.4, 5.4, 5.7, 6.4, 6.7, 6.7, 6, 4.8, 
3.6, 2.8, 3.5, 4.4, 5.1, 4, 3.7, 4.5, 4.9, 5.7), y = c(6.9, 6.2, 
5.3, 4.1, 3.1, 2.9, 2.9, 3.5, 4.2, 4.9, 5.1, 4.9, 4.9, 5.2, 6.9, 
6.9, 5.3, 3.8, 4.2, 5.6, 6.9, 5.8, 1.2, 2.5, 5.3, 6.4, 6.8, 7.6, 
6.9, 5.4, 4.8, 4.4)), .Names = c("x", "y"))
x <- do.call('cbind',testpts)
ch<-chull(x)
x[c(ch,ch[1]),]
plot(x,pch=20)
points(x[ch,],pch=20,col='red')
lines(x[c(ch,ch[1]),],lwd=.5)

testpts
ggalt
软件包提供了
geom_-enclosure
,它应该提供类似这样的东西-凸面但平滑:

library(ggplot2)
library(ggalt)  ## v 0.4.0

df <- data.frame(x = rnorm(20), y = rnorm(20),
      z = sample(letters[1:5], 20, replace = TRUE))
ggplot(df, aes(x, y, colour = z)) + geom_point() +
     geom_encircle(aes(fill=z),alpha=0.3)
库(ggplot2)
图书馆(ggalt)##V0.4.0

df当你说平滑曲线-你的意思是凸包不起作用(对于你所说的起始问题)?出于美学原因,我更喜欢平滑曲线而不是凸包多边形。当然,对于初学者的问题,一个简单的解决办法是找到一个足够大的包含所有点的圆。但这个解决方案不能应用/推广到一般问题。我试图找到一些能将点更紧密地包围在给定点集中的东西。@amit-你能使用
Hmisc
库中的
bezier
来平滑
chull
多边形吗?@latemail:我不确定这能保证多边形中的所有点都在曲线内,虽然我可能是错的,但我不确定,但这个问题可以用countour plot表示为KNN问题。这不会像OP要求的那样顺利,though@David现在比较顺利了。我觉得你原来的答案更好。虽然更平滑,但这个结果似乎漏掉了很多点。我想这也是因为我随机生成了数据。我在代码中用bezier替换了spline.poly,我几乎得到了你们的结果。我对我的两个解决方案并不满意…我稍后尝试将其表述为一个近邻问题。这是一个很好的解决方案!我认为曲线仍然相当“大”,因为它基于凸包,因此很难“排除”不属于集合的点。但是spline.poly也可以用于凹多边形。我只需要计算那个多边形。谢谢。@amit-您可能对该软件包感兴趣:我在GIS stackexchange上再次找到了该软件包的链接:@amit-我加入了一个显示凹形解决方案的新示例。如果它看起来像你想要的,请告诉我。有一个函数
rgeos::gBuffer
可以将多边形“增长”一定量。这可能有助于OP接近所提供链接中的问题。OP不希望发出刺耳的声音:“因此[…]凸壳可能不起作用。”
testpts <- structure(list(x = c(4.9, 4.2, 4, 4.1, 4.4, 5.8, 5.8, 5.8, 5.8, 
5.5, 4.9, 3.2, 3.2, 3.3, 5.4, 5.4, 5.7, 6.4, 6.7, 6.7, 6, 4.8, 
3.6, 2.8, 3.5, 4.4, 5.1, 4, 3.7, 4.5, 4.9, 5.7), y = c(6.9, 6.2, 
5.3, 4.1, 3.1, 2.9, 2.9, 3.5, 4.2, 4.9, 5.1, 4.9, 4.9, 5.2, 6.9, 
6.9, 5.3, 3.8, 4.2, 5.6, 6.9, 5.8, 1.2, 2.5, 5.3, 6.4, 6.8, 7.6, 
6.9, 5.4, 4.8, 4.4)), .Names = c("x", "y"))
x <- do.call('cbind',testpts)
ch<-chull(x)
x[c(ch,ch[1]),]
plot(x,pch=20)
points(x[ch,],pch=20,col='red')
lines(x[c(ch,ch[1]),],lwd=.5)
library(ggplot2)
library(ggalt)  ## v 0.4.0

df <- data.frame(x = rnorm(20), y = rnorm(20),
      z = sample(letters[1:5], 20, replace = TRUE))
ggplot(df, aes(x, y, colour = z)) + geom_point() +
     geom_encircle(aes(fill=z),alpha=0.3)