Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

world map - map halves of countries to different colors

Tags:

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: enter image description here

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.

like image 222
Xu Wang Avatar asked Nov 04 '12 14:11

Xu Wang


People also ask

Why are countries on a world map different colours?

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.

How many colors does a world map need?

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.

What colour is land on a map?

The cultivable land is shown in yellow colour.


1 Answers

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) 

enter image description here

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) 
like image 176
BenBarnes Avatar answered Oct 14 '22 02:10

BenBarnes