I would like to plot a tilted map, similar to the image below. I would prefer to do this using ggplot2 but I'm glad if there is a solution using base R. Any ideas on how to do this?

Here is a dataset for a reproducible example:


# load data

# plot Census Tract map

![enter image description here

  • How "tilted" do you want it? Looking at the longitude lines this looks more like a 3d perspective of a sphere than anything "tilted". You could create a regular image using whatever R mapping you are familiar with, then drape it as a texture using rgl and fiddle with it in 3d. Or just use QGIS and the 3d plugin... – Spacedman Apr 14 '16 at 16:18
  • I guess the image I used might not be the greatest example. What I had in mind was something more like this – rafa.pereira Apr 14 '16 at 16:35

The examples in your link look like the coordinates have been transformed via a shear and a scale matrix. You can easily apply this to the coordinates you get from the usual fortify/join data that ggplot requires.

Need a unique character ID value:


Fortify on that ID and join attribute data:

ofort = fortify(oregon.tract,region="id")
ofort = left_join(ofort, oregon.tract@data, c("id"="id"))

Shear/scale matrix [[2,1],[0,1]] obtained by some trial and error:

sm = matrix(c(2,1.2,0,1),2,2)

Get transformed coordinates:

xy = as.matrix(ofort[,c("long","lat")]) %*% sm

Put as extra columns in fortified data:

ofort$x = xy[,1]; ofort$y = xy[,2]

Plot the "white" attribute as fill colours:

ggplot(ofort, aes(x=x, y=y, group=id, fill=white)) + geom_polygon() + coord_fixed()


enter image description here

| improve this answer | |

Extending on @Spacedman's answer, creating a stacked map like the one shown in the question becomes quite simple. You just need to add another map layer and displace its y axis: e.g. aes(x=x, y=y+5) :

ggplot(data= ofort) + 
  geom_polygon( aes(x=x, y=y, group=id), fill= "white", color="gray30") + # layer 1
  geom_polygon( aes(x=x, y=y+5, group=id, fill=white)) +                  # layer 2
  geom_polygon( aes(x=x, y=y+10, group=id, fill=pop2000-white)) +         # layer 3
  theme(axis.text=element_blank(), axis.ticks=element_blank()) +
  scale_fill_distiller(palette = "RdBu", name = "Population") +
  annotate("text", x = -197, y = 55, size=5, color="gray35", label = "Non-white") +
  annotate("text", x = -197, y = 50, size=5, color="gray35", label = "White") +
  annotate("text", x = -197, y = 45, size=5, color="gray35", label = "Census tracts") +

enter image description here

| improve this answer | |

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.