Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create minimum bounding rectangle over complete dataset in R

Say I have a set of coordinates like this, for example:

m <- data.frame(replicate(2,sample(0:9,20,rep=TRUE)))

And I want to draw a box around all of the points so that it creates a minimum bounding rectangle.

a <- bounding.box.xy(m)
plot(m)
par(new=T)
plot(a, main="Minimum bounding rectangle")

But the box doesn't go around all of the points.

I am also interested in drawing a standard deviation circle/ellipse around these points but I don't know the function for this.

enter image description here

like image 503
JAG2024 Avatar asked Mar 10 '23 01:03

JAG2024


1 Answers

RECTANGLE

You can obtain the value of minimum and maximum x and y and then draw polygon using those values. Try this:

set.seed(42)
m <- data.frame(replicate(2,sample(0:9,20,rep=TRUE)))
lx = min(m$X1)
ux = max(m$X1)
ly = min(m$X2)
uy = max(m$X2)
plot(m)
title(main = "Minimum bounding rectangle")
polygon(x = c(lx, ux, ux, lx), y = c(ly, ly, uy, uy), lty = 2)

enter image description here

POLYGON

More discussion about drawing a curve around a set of points can be found here. One way is to exploit the chull command for creating convex hull.

First import the following function

plot_boundary <- function(x,y,offset = 0,lty = 1,lwd = 1,border = "black",col = NA){
# 'offset' defines how much the convex hull should be bumped out (or in if negative value)
# relative to centroid of the points. Typically value of 0.1 works well 
BX = x + offset*(x-mean(x))
BY = y + offset*(y-mean(y))
k2 = chull(BX,BY)
polygon(BX[k2],BY[k2],lty = lty,lwd = lwd,border = border,col = col)
}

Then you can generate data and plot boundary around it.

set.seed(242)
m <- data.frame(replicate(2,sample(0:9,20,rep=TRUE)))
plot(m, xlim = c(0,10), ylim = c(0,10))
title(main = "Minimum bounding rectangle")
plot_boundary(x = m$X1, y = m$X2, lty = 2)

enter image description here

ELLIPSE

set.seed(42)
A = data.frame(x = rnorm(20, 25, 4), y = rnorm(20, 11, 3))
B = data.frame(x = rnorm(20, 12, 5), y = rnorm(20, 5, 7))
plot(rbind(A,B), type = "n", ylim = c(-10,20), xlim = c(0,40), asp = 1)
require(ellipse)
red_eli = ellipse(cor(A$x,A$y), scale = c(sd(A$x), sd(A$y)),
                                centre = c(mean(A$x), mean(A$y)))
blue_eli = ellipse(cor(B$x,B$y), scale = c(sd(B$x), sd(B$y)),
                                centre = c(mean(B$x), mean(B$y)))
points(A, pch = 19, col = "red")
points(B, pch = 18, col = "blue")
lines(red_eli, col = "red")
lines(blue_eli, col = "blue", lty = 2)

enter image description here

like image 71
d.b Avatar answered May 01 '23 01:05

d.b