The following code works well for drawing polygons

SP <- SpatialPolygons(spd)
centroids  <- coordinates(SP)
x  <- centroids[,1]
y  <- centroids[,2]
SP1  <- SpatialPolygonsDataFrame(SP, data = data.frame(x = x, y = y, z = z, row.names = row.names(SP)))
ggplot(data = SP1, aes(x = long, y = lat, group = group)) + geom_path()

Instead if I change the last two lines of the code to fill these polygons based on some value vector it does not work:

penetration <- runif(n = length(SP), min = 1, max = 10)
SP1  <- SpatialPolygonsDataFrame(SP, data = data.frame(x = x, y = y, z = z,  value = penetration, row.names = row.names(SP)))
ggplot(data = SP1, aes(x = long, y = lat, group = group)) + geom_polygon(aes(fill=SP1$value))

spd is created with data from the following link:

data source: https://www.google.com/maps/d/viewer?mid=1mf9TQY3bocarO4SaIXAtco_C1LE&hl=en_US

I then extracted coordinates from the kml file... which is then into a list of Polygons so that I could draw it using some plotting function...

tkml <- getKMLcoordinates(kmlfile="Pune all Electoral Wards.kml", ignoreAltitude=T)
len <-length(tkml)

del <- NA
for(i in 1:len)
  if(length(tkml[[i]]) == 2)
    del <- c(del, i)
del <- del[-1]
tkmlCleaned <- tkml[!tkml %in% tkml[del]]
size <- length(tkmlCleaned)
sr <- vector(mode = "list", length = size)
srs <- vector(mode = "list", length = size)
spd <- list()
for(j in 1:length(sr))

  sr[[j]] <- Polygon(tkmlCleaned[[j]])
  srs[[j]] <- Polygons(list(sr[[j]]), j)
  spd <- c(srs[[j]], spd)
  • Start with library(rgdal); spd <- readOGR("Pune all Electoral Wards.kml", "Pune Prabhags 2012 onwards"); plot(spd, col = sample(grey(seq(0, 1, length = nrow(spd))))) then learn about plotting polys with ggplot2 (or generally). Do you just want to recreate the map/s in the webpage, as they appear? This is all bit trickier than it should be, but this is a better starting point IMO – mdsumner Aug 19 '16 at 9:02
  • I missed a couple things, you can't use the value column literally like that, you have to merge the attributes back on after fortify(SP1) - which you seem to have left out? More soon, but please update with answers – mdsumner Aug 19 '16 at 9:26
  • Yes I want to recreate the map based on population density of the wards... – AdiPiratla Aug 19 '16 at 11:00
  • I did not quite understand the usage of fortify. I am trying to make sense of it and will let you know if I get results – AdiPiratla Aug 19 '16 at 11:12

There's a lot more to this, it's interestingly painful in a couple of places. There are easier steps in some ways with less base ggplot2 functions, but I'm not used to them yet.

Maybe this will help you . . .


## we can only read one layer at a time, to see which layers are there run
##ogrListLayers("Pune all Electoral Wards.kml")
#"Pune Prabhags 2012 onwards"
#"PMC Adminstrative Ward Offices"

spd <- readOGR("Pune all Electoral Wards.kml", "PMC Adminstrative Ward Offices")


## this is the table of all coordinates, classified by object and part-of-object
spdtab <- fortify(spd)

## but note that we don't have any of the layer-attributes

## to put them on we can use merge(), but it's much easier with dplyr IMO
gislayerdata <- mutate(as.data.frame(spd), id = as.character(row_number()))
spdtab <- inner_join(spdtab, gislayerdata, "id")

ggplot(spdtab) + aes(x = long, y = lat, group = group, fill = Name) + 
   geom_polygon() + 
   guides(fill = FALSE) 
  • I am getting an error on using fortify function ... spdtab <- fortify(spd) Error: ggplot2 doesn't know how to deal with data of class SpatialPointsDataFrame Is there anything I am missing? Thanks in advance – AdiPiratla Aug 19 '16 at 10:56
  • It's not for points, it's for polygons or lines. Your KML contains polygons. The "fortify" version of SpatialPointsDataFrame is just as.data.frame(x), since there's only one coordinate per row. Fortify is just all the coordinates in one table, with "id" the object (one row in SpolyDF), "group" (or piece) the sub-geometry (i.e. a ring polygon), order, hole status, and x/y coords. – mdsumner Aug 19 '16 at 13:16

you don't mention which error it yields, but, for these cases,

aes(x=long, y=lat, group=group, fill=group)

has worked for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.