Thuy Nguyen Hong
Thuy Nguyen Hong

Reputation: 253

Plot polygons with different colors and not overwrite the previous polygons if overlapped

I am graphing several n-edge polygons on the same plot. Let say:

1/ n=3: draw polygon with 3 edges, color it with "pink"

2/ n=6: draw polygon with 6 edges, will color with "grey". At this point, I see that the first polygon in step 1 is overlapped by this one. In this case, I just want to keep the "pink" color of the first polygon and color the rest "un-overlapped" area of 2nd polygon with "grey" color.

I have tried some code as follow, but it always display "grey" polygon, instead of "pink" and "grey" areas.

BTW, I also walked around this problem by "draw the 6-edge polygon (n=6) first, and then draw 3-edges polygon (n=3)". By changing the drawing order from the biggest polygon to the smallest one, I can keep the color of the biggest and smallest polygons at the end. However, I would like to do the steps as I mentioned at the beginning of this questions so that i can see the plotting areas are increasing when n (number of edges) keeps increasing.

If you have any suggestions, please advice me. Thank you very much!

cat("\014")
rm(list=ls())

#############################
# first polygon
#n=3
xx3=c(0,-3,3);xx3
yy3=c(1,1,-2);yy3

#plot each intersection /vertex of polygon n=3
plot   (xx3, yy3,type = "p", xlim=c(-8,8), ylim=c(-8,8),col="blue",xlab = "x", ylab = "y")
# display value of each point above 
text(xx3, yy3, paste("(",round(xx3, 2),"," ,round(yy3, 2), ")"), 
     cex=0.8,family="mono", font=1, adj=1.5, pos=3) 

#fill the shade area
polygon(xx3, yy3, col = "pink", border = "pink")
title("Plot n-edge polygon")

#############################
# RUN untill this point and stop. 
#And then run following part, you will see the 1st polygon is overlapping region 
#and is fully overwrited by the second polygon.

#############################
# Second polygon
#n=6 
par(new=TRUE)

xx=c(0,-15/11,-15/4,-45/11,-3, 3);xx
yy=c(1,20/11,5/2,20/11,1,-2);yy

#plot each intersection /vertex of polygon n=6
points(xx, yy,type = "p", col="blue",xlab = "x", ylab = "y")
# display value of each point above 
text(xx, yy, paste("(",round(xx, 2),"," ,round(yy, 2), ")"), 
     cex=0.8,family="mono", font=1, adj=1.5, pos=3) 

#fill the shade area
polygon(xx, yy, col = "grey", border = "grey")

#draw x=0,y=0
abline(a=0,b=0,v=0)

Upvotes: 0

Views: 1120

Answers (1)

eblondel
eblondel

Reputation: 603

One possibility is to compute the difference between the current polygon (bigger), and the previous one (smaller). I don't know if there is some easy way to compute geometries other than using sp (spatial objects) and rgeos.

Here some code that uses the packages sp and rgeos packages. The approach consists to compute the polygonal difference, by means of spatial objects, and plot it. This might not be the most elegant way, but at least it will do what you want.

require(sp)
require(rgeos)

#test data
xx3=c(0,-3,3);xx3
yy3=c(1,1,-2);yy3
xx=c(-5,-5,5,5);xx
yy=c(-5,5,5,-5);yy

#create a SpatialPolygons object for n = 3
sp3 <- as.data.frame(cbind(xx3,yy3))
sp3 <- rbind(sp3, sp3[1,])
coordinates(sp3) <- c("xx3","yy3")
p3 <- Polygon(sp3)
ps3 <- Polygons(list(p3),1)
sps3 <- SpatialPolygons(list(ps3))

#create a SpatialPolygons object for n = 6
sp <- as.data.frame(cbind(xx,yy))
sp <- rbind(sp, sp[1,])
coordinates(sp) <- c("xx","yy")
p <- Polygon(sp)
ps <- Polygons(list(p),1)
sps <- SpatialPolygons(list(ps))

#compute the difference (with rgeos)
#between the current polygon (bigger) and the previous one (smaller)
spsdiff <- gDifference(sps, sps3)

For plotting the difference, 2 ways:

#Plotting 1: based on sp-plot
#===========
plot(sps, border="transparent") #to set some bigger extent
plot(sps3, add=T, col = "pink")
plot(spsdiff, add=T, col = "grey") 

#Plotting 2: use polygon and polypath base functions
#===========
#preparing data for using polypath (polygons with hole)
polys <- spsdiff@polygons[[1]]@Polygons
coords <- do.call("rbind", lapply(polys, function(x){ if(x@hole) x@coords }))
holes <- do.call("rbind", lapply(polys,function(x){ if(!x@hole) rbind(rep(NA,2),x@coords) }))
poly.coords <- rbind(coords,holes)

#plot it
plot(xx, yy, col = "transparent")
polygon(xx3, yy3, col = "pink")
polypath(poly.coords[,1],poly.coords[,2],col="grey", rule="evenodd")

If you have to repeat this, you can re-use this code within a loop to iteratively plot the polygon differences.

Note: rgeos requires you to install the GEOS library on your machine

Upvotes: 2

Related Questions