I am using the example here for discussion: ggplot map with l
library(rgdal) library(ggplot2) library(maptools) # Data from http://thematicmapping.org/downloads/world_borders.php. # Direct link: http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip # Unpack and put the files in a dir 'data' gpclibPermit() world.map <- readOGR(dsn="data", layer="TM_WORLD_BORDERS_SIMPL-0.3") world.ggmap <- fortify(world.map, region = "NAME") n <- length(unique(world.ggmap$id)) df <- data.frame(id = unique(world.ggmap$id), growth = 4*runif(n), category = factor(sample(1:5, n, replace=T))) ## noise df[c(sample(1:100,40)),c("growth", "category")] <- NA ggplot(df, aes(map_id = id)) + geom_map(aes(fill = growth, color = category), map =world.ggmap) + expand_limits(x = world.ggmap$long, y = world.ggmap$lat) + scale_fill_gradient(low = "red", high = "blue", guide = "colorbar")
Gives the following results:
I would like to map one variable to the left "half" of a country and a different variable to the right "half" of the country. I put "half" in quotes because it's not clearly defined (or at least I'm not clearly defining it). The answer by Ian Fellows might help (which gives an easy way to get the centroid). I'm hoping for something so that I can do aes(left_half_color = growth, right_half_color = category)
in the example. I'm also interested in top half and bottom half if that is different.
If possible, I would also like to map the individual centroids of the halves to something.
Colors are also used to show topography, with different shades representing distances above or below sea level. Different colors are used to communicate types of information, thus a new standard of map coloring has been made.
In mathematics, the four color theorem, or the four color map theorem, states that no more than four colors are required to color the regions of any map so that no two adjacent regions have the same color.
The cultivable land is shown in yellow colour.
This is a solution without ggplot
that relies on the plot
function instead. It also requires the rgeos
package in addition to the code in the OP:
EDIT Now with 10% less visual pain
EDIT 2 Now with centroids for east and west halves
library(rgeos) library(RColorBrewer) # Get centroids of countries theCents <- coordinates(world.map) # extract the polygons objects pl <- slot(world.map, "polygons") # Create square polygons that cover the east (left) half of each country's bbox lpolys <- lapply(seq_along(pl), function(x) { lbox <- bbox(pl[[x]]) lbox[1, 2] <- theCents[x, 1] Polygon(expand.grid(lbox[1,], lbox[2,])[c(1,3,4,2,1),]) }) # Slightly different data handling wmRN <- row.names(world.map) n <- nrow(world.map@data) world.map@data[, c("growth", "category")] <- list(growth = 4*runif(n), category = factor(sample(1:5, n, replace=TRUE))) # Determine the intersection of each country with the respective "left polygon" lPolys <- lapply(seq_along(lpolys), function(x) { curLPol <- SpatialPolygons(list(Polygons(lpolys[x], wmRN[x])), proj4string=CRS(proj4string(world.map))) curPl <- SpatialPolygons(pl[x], proj4string=CRS(proj4string(world.map))) theInt <- gIntersection(curLPol, curPl, id = wmRN[x]) theInt }) # Create a SpatialPolygonDataFrame of the intersections lSPDF <- SpatialPolygonsDataFrame(SpatialPolygons(unlist(lapply(lPolys, slot, "polygons")), proj4string = CRS(proj4string(world.map))), world.map@data) ########## ## EDIT ## ########## # Create a slightly less harsh color set s_growth <- scale(world.map@data$growth, center = min(world.map@data$growth), scale = max(world.map@data$growth)) growthRGB <- colorRamp(c("red", "blue"))(s_growth) growthCols <- apply(growthRGB, 1, function(x) rgb(x[1], x[2], x[3], maxColorValue = 255)) catCols <- brewer.pal(nlevels(lSPDF@data$category), "Pastel2") # and plot plot(world.map, col = growthCols, bg = "grey90") plot(lSPDF, col = catCols[lSPDF@data$category], add = TRUE)
Perhaps someone can come up with a good solution using ggplot2
. However, based on this answer to a question about multiple fill scales for a single graph ("You can't"), a ggplot2
solution seems unlikely without faceting (which might be a good approach, as suggested in the comments above).
EDIT re: mapping centroids of the halves to something: The centroids for the east ("left") halves can be obtained by
coordinates(lSPDF)
Those for the west ("right") halves can be obtained by creating an rSPDF
object in a similar way:
# Create square polygons that cover west (right) half of each country's bbox rpolys <- lapply(seq_along(pl), function(x) { rbox <- bbox(pl[[x]]) rbox[1, 1] <- theCents[x, 1] Polygon(expand.grid(rbox[1,], rbox[2,])[c(1,3,4,2,1),]) }) # Determine the intersection of each country with the respective "right polygon" rPolys <- lapply(seq_along(rpolys), function(x) { curRPol <- SpatialPolygons(list(Polygons(rpolys[x], wmRN[x])), proj4string=CRS(proj4string(world.map))) curPl <- SpatialPolygons(pl[x], proj4string=CRS(proj4string(world.map))) theInt <- gIntersection(curRPol, curPl, id = wmRN[x]) theInt }) # Create a SpatialPolygonDataFrame of the western (right) intersections rSPDF <- SpatialPolygonsDataFrame(SpatialPolygons(unlist(lapply(rPolys, slot, "polygons")), proj4string = CRS(proj4string(world.map))), world.map@data)
Then information could be plotted on the map according to the centroids of lSPDF
or rSPDF
:
points(coordinates(rSPDF), col = factor(rSPDF@data$REGION)) # or text(coordinates(lSPDF), labels = lSPDF@data$FIPS, cex = .7)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With