I am new to shapefiles and I've got a bit lost. I am trying to plot pooling sections in my region (Madrid) with different colors.

But I get

  Error: IllegalArgumentException: Invalid number of points in LinearRing 
  found 3 - must be 0 or >= 4

when using the fortify function on my data (please, find the full code below). I found in this form that it may have to do with the rgeos library, but my rgeos version is

rgeos version: 0.3-8, (SVN revision 460)
GEOS runtime version: 3.4.2-CAPI-1.8.2 r3921 
Polygon checking: TRUE 

which is new, since I have installed it right now.

Someboty explained me that the problem is that my data has a point or a line section, not a full polygon, which requires 4 points. I went to QGIS, open the file and checked the geometry validity. I found the following errors

3969,segment 0 of ring 0 of polygon 1 intersects segment 0 of ring 8 of   
  polygon 2 at -3.53569120482, 40.4258644642
3969,segment 0 of ring 221 of polygon 1 intersects segment 0 of ring 8 of 
   polygon 2 at -3.53569120482, 40.4258644642
3969,Geometry has 2 errors.
4166,ring 1 with less than four points
4166,Geometry has 1 errors.

so that I elliminated polygon 1 and checked again the geometry validity of the new data set, but I get the same errors.

Can anybody provide me with a hint to fix this problem?


seccionesOk <- readShapePoly('secciones_censales_buenas.shp')
seccionesOk@data$id <- as.vector(seccionesOk@data$DESBDT)

#Transform object of class "SpatialPolygonsDataFrame" in "data.frame"
seccionesOk.points = fortify(seccionesOk, region="id")

    ##### the previous line fails #######

seccionesOk.df = join(seccionesOk.points, seccionesOk@data, by="id")
colorsec=sample(1:4, size = length(seccionesOk@data$id), replace = TRUE )

cluster = data.frame(id=seccionesOk@data$id,

seccionesOk = merge(seccionesOk.df,cluster,by="id")

ggplot(seccionesOk) + 
   geom_polygon(aes(x = long, y = lat, group = NAME_1, fill = cluster)) +
   scale_fill_manual(values = 
     c("1" = "red","2"="yellow","3"="green","4"="blue")) +
      geom_path(aes(x=long,y=lat,group=NAME_1)) +
      coord_equal() + 
      theme_bw() + xlab("Longitude") + ylab("Latitude")

You can find your answers here: http://r-spatial.org/r/2017/03/19/invalid.html

With sf::st_invalid() you can check which of the polygons are corrupt and then fix them with sf::st_make_valid

| improve this answer | |

1) If you only want to plot your shapefile according to a particular field color, look at R: Spatial Cheatsheet, for example.

seccionesOk = readOGR(".", "secciones_censales_buenas")
palette(brewer.pal(6, "YlOrRd"))
plot(seccionesOk, col = plotrix:::rescale(seccionesOk$DESBDT, c(1, 6)), pch = 19)

enter image description here

2) If you want to use ggplot2to do that, the library need access to the SpatialPolygon geometry and the fortify function does this for you. But in some cases, there are "big" problems as in yours and mine (crash) even if I sort the table by the order field.

Fortunately, in such cases, James Cheshire (Maps with ggplot2) wrote a substitute that seems to work in this case (poly_coords_function.R)

seccionesOk = readShapePoly('secciones_censales_buenas.shp')

The function poly_coords_function.r requires an ID field in the SpatialPolygonsdataframe, I will rename "SP_ID" field

names(seccionesOk) = c("ID", "CODBDT", "GEOCODIGO", "DESBDT")
seccionesOk_geom = poly_coords(seccionesOk) # very long...
map = qplot(PolyCoordsY, PolyCoordsX, data=seccionesOk_geom, group=Poly_Name , fill= DESBDT, geom="polygon")

enter image description here

I hope this will help you

| improve this answer | |
  • 2
    Does not address the underlying issue of what the post was about! – user1738753 Jul 5 '16 at 22:55

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.