1

I have a large spatial data frame, head information here:

class       : SpatialPolygonsDataFrame 
features    : 6 
extent      : 1268821, 1610480, 4828587, 5485976  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +units=m +no_defs 
variables   : 3
names       :       TA2013_label, TimaruID, DistrictShortNames 
min values  : Ashburton District,        0,          Ashburton 
max values  :       Dunedin City,        0,       Dunedin City 

As suggested in the header, I have: SouthIslandTAs@data@TA2013_label, SouthIslandTAs@data@TimaruID, and SouthIslandTAs@data@DistrictShortNames. TA2013_label is a factor with 23 levels, TimaruID is numeric (0,1), and DistrictShortNames is character. Previously, the data contained the labels for all territorial local authorities in New Zealand. I removed the North Island data and reduced the number of factor levels to the 23 remaining for the South Island.

I cannot plot this map in ggplot. However, it plots fine with the tmap package. But the latter creates large white margins around the plot when saving as a PDF and I can't work out how to remove these, hence the shift to ggplot.

This is the code for tmap:

tm_shape(SouthIslandTAs) + tm_polygons("TimaruID", group= "TA2013_label", border.col="grey", style = "jenks", 
                                   palette = "Greens") +
  tm_layout(legend.show = FALSE) +
  tm_text("DistrictShortNames", size=.6, col= "black")

I get a map of South Island (NZ) territorial authorities with Timaru District shown as a darker green, compared to the light green of the rest of the TAs.

But I can't get the code working in ggplot.

I have tried:

ggplot(data = SouthIslandTAs, aes(x = long, y = lat, fill = TA2013_label, group = group)) +
geom_polygon()
Regions defined for each Polygons
Error in FUN(X[[i]], ...) : object 'TA2013_label' not found

and

ggplot() + 
geom_polygon(data = SouthIslandTAs, aes(x=long, y = lat, group = group), fill = TA2013_label, color = "red")
Regions defined for each Polygons
Error in FUN(X[[i]], ...) : object 'TA2013_label' not found

and

ggplot() + 
geom_polygon(data = SouthIslandTAs, aes(x=long, y = lat, group = TA2013_label), fill = TimaruID, color = "red")
Error in layer(data = data, mapping = mapping, stat = stat, geom = GeomPolygon,  : 
object 'TimaruID' not found

and

ggplot() + 
geom_polygon(data = SouthIslandTAs, aes(x=long, y = lat, group = TA2013_label), fill = "TimaruID", color = "red")
Regions defined for each Polygons
Error in FUN(X[[i]], ...) : object 'TA2013_label' not found

Thinking it might be a problem with missing @data, I tried adding that in and got the following error (and no plot):

 ggplot(data = SouthIslandTAs, aes(x = long, y = lat, fill = data@TA2013_label, group = group)) +   
 geom_polygon()
 Regions defined for each Polygons
 Error in FUN(X[[i]], ...) : 
 trying to get slot "TA2013_label" from an object of a basic class ("function") with no slots

I can get basic plots output:

ggplot() + geom_polygon(data = SouthIslandTAs, aes(x=long, y = lat, group = group))

and

ggplot() + 
geom_polygon(data = SouthIslandTAs, aes(x=long, y = lat, group = group), fill = NA, color = "red")

but I get the same warning for both of those:

Regions defined for each Polygons

I don't understand why tmap is fine with the data, but ggplot isn't. I get no errors or warnings with tmap.

Michelle
  • 1,281
  • 2
  • 16
  • 31
  • Can you provide a reproducible example of your dataset ? (see this link: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610#5963610) – dc37 Feb 24 '20 at 22:22
  • It is an 8Mb file of only 23 geographic locations. I would need to provide the entire file. – Michelle Feb 24 '20 at 23:02
  • Well, I'm not an expert in this kind of files... I'm not sure how you should proceed. Have you try the answer I provided you below ? – dc37 Feb 24 '20 at 23:04
  • I've just added a question to your answer. – Michelle Feb 24 '20 at 23:06

1 Answers1

3

Without a reproducible example of your dataset, it's hard to be sure of the solution to your question, but maybe you can plot your data with ggplot2 after converting it to a sf object and then use geom_sf:

library(sf)
library(sp)
library(ggplot2)
SF_Obj <- st_as_sf(SouthIslandTAs, fill = TRUE, plot = FALSE)
ggplot()+ geom_sf(data = SouthIslandTAs, aes(fill = TA2013_label))

Here an example using USA maps from raster package:

States <- raster::getData("GADM", country = "United States", level = 1)  
ggplot() + geom_polygon(data = States, aes(x=long, y = lat, group = group, fill = NAME_1))

I get the same error than you:

Regions defined for each Polygons Error in FUN(X[[i]], ...) : object 'NAME_1' not found

But when I do:

library(sf)
library(sp)
library(ggplot2)
library(dplyr)
sf_states <- sf::st_as_sf(States, plot = FALSE, fill = TRUE)
sf_states %>% filter(!(NAME_1 %in% c("Alaska","Hawaii"))) %>% 
  ggplot() + geom_sf(aes(fill = NAME_1), show.legend = FALSE)

I get:

enter image description here

Assigning specific filling color

To assign specific colors starting from the sf object, you can create a new column with some color names specified and then use scale_fill_identity:

library(sf)
library(sp)
library(ggplot2)
library(dplyr)
sf_states %>% filter(!(NAME_1 %in% c("Alaska","Hawaii"))) %>% 
  mutate(COLOR = ifelse(NAME_1 %in% c("Oregon","Florida"),"green","red")) %>%
  ggplot() + geom_sf(aes(fill = COLOR), show.legend = FALSE)+
  scale_fill_identity()

enter image description here

If you prefer filling with 0 and 1 depending of the country, you can get the same plot by doing:

sf_states %>% filter(!(NAME_1 %in% c("Alaska","Hawaii"))) %>% 
  mutate(COLOR = ifelse(NAME_1 %in% c("Oregon","Florida"),1,0)) %>%
  ggplot() + geom_sf(aes(fill = as.factor(COLOR)), show.legend = FALSE)+
  scale_fill_manual(values = c("red","green"))

Does it answer your question ? If not, please consider providing a reproducible example of your dataset

dc37
  • 15,840
  • 4
  • 15
  • 32
  • How would you do a one-colour fill for just (as an example) Oregon and Florida, and have a different colour fill for the other states? I'm using a 0,1 code for the ID for which colour to use where. So Oregon and Florida would be a 1 and the other states would be a 0, using NAME_1 in your example. Oregon and Florida would be a darker green than the others, which is why I am using the "Greens" palette in tmap. – Michelle Feb 24 '20 at 23:06
  • I edited my answer accordingly, let me know if it is working. – dc37 Feb 24 '20 at 23:12
  • Thank you! Working perfectly. – Michelle Feb 24 '20 at 23:59