Построение кривой вокруг множества точек
У меня есть набор точек на плоскости. Они разбиваются на подмножества.
Я хочу построить замкнутую кривую вокруг точек, принадлежащих одному и тому же подмножеству, так что точки, принадлежащие подмножеству, будут внутри кривой, а те, которые не являются, будут снаружи. Поэтому простые круги или выпуклый корпус могут не работать.
Для стартера, скажем, я просто хочу иметь гладкую кривую вокруг множества точек (без требования, чтобы исключить другие точки)
Любые идеи, как это сделать в R?
--- добавлено позже ---
В конце концов, что я ищу, это что-то в духе графики здесь: https://tex.stackexchange.com/info/1175/drawing-a-hypergraph - хотя контекст не является гиперграфом, а скорее заданный набор точек и разбиение на них.
Ответы
Ответ 1
Хорошо, вот вариант ответа, который, я думаю, близок к тому, что вы преследуете:
Он использует функцию spline.poly
, созданную над этим ответом (https://gis.stackexchange.com/a/24929) на форуме ГИС.
Вот несколько примеров:
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"))
Настройте основной сюжет
plot(NA,xlim=c(0,10),ylim=c(0,10))
points(testpts,pch=19)
chuld <- lapply(testpts,"[",chull(testpts))
polygon(chuld,lty=2,border="gray")
polygon(spline.poly(as.matrix(as.data.frame(chuld)),100),border="red",lwd=2)
И результат:
![chullin' it up!]()
РЕДАКТИРОВАТЬ ДОБАВИТЬ ПРИМЕР КОНЦЕВАЦИИ
В этой части ответа используется библиотека alphahull
# load the required library
library(alphahull)
plot(NA,xlim=c(0,10),ylim=c(0,10))
points(testpts,pch=19)
# remove duplicate points so the ahull function doesn't error out
testptsnodup <- lapply(testpts,"[",which(!duplicated(as.matrix(as.data.frame(testpts)))))
Сгенерировать и построить объект ahull. Значение альфа-значения кажется очень важным при определении соответствия многоугольника данным.
ahull.obj <- ahull(testptsnodup,alpha=2)
plot(ahull.obj,add=TRUE,col="red",wpoints=FALSE)
И результат:
![enter image description here]()
Ответ 2
В пакете ggalt
содержится geom_encircle
, который должен предоставить что-то вроде этого - выпуклое, но плавное:
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)
![введите описание изображения здесь]()
Ответ 3
После некоторого поиска в Google я немного изменяю этот пример Morota ggplot2
ИЗМЕНИТЬ
Он использует функцию chull с Безье
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)
![enter image description here]()
Ответ 4
Просто:
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)
Plot:
сюжет