Has anyone ever plotted a 3-D (cube) legend as shown below? Essentially trivariate mapping.

I would like to recreate the below using the same variables of population, built (% area that is built up) and light (a variable already derived from satellite imagery). I'm interested in recreating the cube itself and the labels. The explanation boxes would be a bonus but not critical!

enter image description here

enter image description here

(The reference for the above image is EU Commission as part of the Global Human Settlements Layer: https://twitter.com/vladimirsucha/status/1140292484695764995)

1 Answer 1


This function generates an approximation to that legend using the 3d capabilities of the rgl package:

key3d <- function(){
    s = seq(0, 1, len=5)
    xyz = expand.grid(x=s, y=s, z=s)
    ## this order replicates the example
    col = rgb(xyz[,2], xyz[,1], xyz[,3])
    spheres3d(xyz, col=col, radius=0.075, lit=FALSE)
    ## m can be got from the plot with par3d()$userMatrix
    m = structure(c(-0.692, -0.426, 0.582, 0,
                    0.722, -0.395, 0.569, 0,
                    0, 0.814, 0.581, 0,
                   0, 0, 0, 1), .Dim = c(4L, 4L))

enter image description here

Note that it uses spheres instead of cubes (cubes could be done but are a bit more work because each cube can have its own rotation). The matrix m constructed in the code sets the view point and rotation, and is near enough to looking straight down that axis - the exact values probably need some trigonometry to work out but this is close enough.

Adding text to a rgl plot can be done using text3d. Its a bit fiddly to get right so here's one corner for starters. You might need to play with alignments and position to get it perfect:

key_labels <- function(){
    text3d(1.1,-0.1,1.1,"pop -", col="white",adj=c(1,1))
    text3d(1.1,-0.1,1.1,"built +", col="white",adj=c(1,0))
    text3d(1.1,-0.1,1.1,"light +", col="white",adj=c(1,-1))


enter image description here

Note this is all done to a different graphics window than R's usual plots, so you may not be able to integrate this with another graphic. You can however save it as an image file and use that.

  • Thank you! This is super helpful. So if I understand correctly, there is no current way to plot 3 variables so your answer is super helpful to create the legend itself, but plotting on a map will require perhaps creating a manual colour scheme
    – Beth C
    Commented Jan 18, 2023 at 11:55
  • If you want to plot the map with this colour scheme you write a function that turns your three variables to a a colour - in this case one variable is the amount of red, the second green, the third blue (or some permutation). If you rescale your variables to (0,1) you can use the rgb function like I did to create the legend. Or for rasters you layer 3 rasters to create an appropriately scaled RGB raster and the colours popout automatically. Maybe ask a new question on colouring a raster map with a trivariate scheme if you can't find an answer online?
    – Spacedman
    Commented Jan 18, 2023 at 12:04
  • Ah that makes sense, thank you. Will give it a go and post another question if I struggle. Thanks for your patience and assistance today.
    – Beth C
    Commented Jan 18, 2023 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.