简体   繁体   中英

ggplot mapping Aesthetics error

I am trying to use ggplot to map an area and label based on values in the @data slot. My error is the same as in the questions here , here , and here , but I can't translate those answers to my problem. I can plot states from the US maps from getData in the raster package but am having trouble from there. For an example these are the data sets I tried (I listed packages because I thought they might have something to do with the problem)...

library(rgdal)
library(raster)
library(ggplot2)
library(maps)
library(maptools)
library(ggmap) # used for theme_nothing() later    
us <- getData("GADM",country="USA",level=1)
PA <- us[us$NAME_1 == 'Pennsylvania',]
AK <- us[us$NAME_1 == 'Alaska',]

When I try this I get a funky map (PA is a single polygon).

ggplot(data=PA, aes(long, lat)) +
 geom_polygon(aes(group=group), color='black', fill=NA) +
 geom_text(data=PA, aes(long, lat, label = PA$NAME_1))

在此处输入图片说明

And when I try this I get the Aesthetics error (AK consists of 2 polygons).

ggplot(data=AK, aes(long, lat)) +
 geom_polygon(aes(group=group), color='black', fill=NA) +
 geom_text(data=AK, aes(long, lat, label = AK$NAME_1))

Regions defined for each Polygons Regions defined for each Polygons Error: Aesthetics must be either length 1 or the same as the data (816071): x, y, label

I'm not sure why I have to put the $ in the geom_text with a data call already present, but it doesn't recognize the variable without it. I also tried to just color the 2 AK polygons by their OBJECTID as in this code, but get the same Aesthetics error.

ggplot(data=AK, aes(long, lat)) +
 geom_polygon(aes(group=group), color='black', fill=AK$OBJECTID)

Thanks for any insight. I really want to use R for mapping more often.

As mentioned in the other answers and comments, modifying geom_text is the first change to be made. My main addition is the use of coord_map() , which is part of ggplot2. coord_map() properly scales the axes for the typical lat-long mapping.

ggplot(data=AK, aes(long, lat)) +
  geom_polygon(aes(group=group), 
               color = "black", 
               fill = NA, 
               alpha = 0.2) + 
  coord_map()

This results in a very long (thus not shown) but accurate mapping. This is due to Alaska's extreme coordinates being interpreted a little improperly by the default scale.

With a little clipping of the axes with scale_x_continuous at -190 and -120 a better cropping is available.

ggplot(data=AK, aes(long, lat)) +
  geom_polygon(aes(group=group), 
               color = "black", 
               fill = "darkgreen", 
               alpha = 0.2) + 
  coord_map()+
  scale_x_continuous(limits = c(-190, -120)) +
  annotate(geom = "text", 
           x = coordinates(AK)[2, 1], # note: [2,] refers to mainland label 
           y = coordinates(AK)[2, 2], 
           label = AK$NAME_1[1],
           size = 10)  

阿拉斯加剧情 Notice that the label coordinates need to be selected a little differently for Alaska than Pennsylvania as the Alaska data.frame contains two objects. coordinates(AK)[1,] supplies the label coordinates for the largest island while coordinates(AK)[2,] is the label coordinates for the mainland.

For further reading, I was working a bit with mapping census data with the census shape files and Kevin Johnson's blog post on Making Maps in R was very helpful. The census shape files come in different resolution levels so if you have hang ups with say the many coordinates present in Alaska's outline, the 5m or 20m census shape file versions may be more manageable.

The excess of "Pennsylvania" text entries is caused by giving all the long 's and lat 's values to the geom_text function. You need to switch to a function that takes only single coordinates. After making the PA object, I can do this, which admittedly seems like a hack. The S4 object classes are supposed to have proper extractor methods, but I searched in the ?SpatialPolygonsDataFrame help page and links and do not find an extractor for the labpt slot. (Then @aosmith filled in that blank and I looked up how to set the aspect ration to 1.0):

plot(PA)
text(x= PA@polygons[[1]]@Polygons[[1]]@labpt[1],   
     y=PA@polygons[[1]]@Polygons[[1]]@labpt[2], 
     label=PA$NAME_1)

I tried plotting the Alaska object but my R session hung up. AK is a fairly complex spatial object with all those islands. When you look at the structure, you see way more than 2 polygons:

..@ polygons   :List of 2
  .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
  .. .. .. ..@ Polygons :List of 4147

You will probably need to loop through list of 4147 to find the polygon with the largest area or put in hand-coded coordinates. The ggplot version of this plotting effort on PA might start with this (although the aspect ratio needs to be fixed,):

ggplot(data=PA, aes(long, lat)) +
 geom_polygon(aes(group=group), color='black', fill=NA) + 
 annotate(geom="text", x=coordinates(PA)[1], y=coordinates(PA)[2], label = PA$NAME_1) + 
 coord_fixed(ratio=1)

在此处输入图片说明

Still not much luck using ggplot to solve my problem. I have switched to plot and spplot for now and have found out how to label the polygon in the center and the Labpt slot as here... invisible(text(getSpPPolygonsLabptSlots(PA), labels=as.character(PA$NAME_1), cex=0.5)) Thought this might help someone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM