[R] separate maps in one figure

Paul Murrell p.murrell at auckland.ac.nz
Tue Aug 12 23:21:10 CEST 2008


Hi


John P. Burkett wrote:
> My aim is to create a figure consisting of three maps: Alaska in the 
> upper left corner, the 48 contiguous US states in the center right, and 
> Hawaii in the lower left corner.  In some ways the figure I'm trying to 
> create is analogous to figure 1.5 in Paul Murrell's excellent "R 
> Graphics", which combines a map of New Zealand with a map of the world. 
>   I tried adapting the code for that figure, 
> http://www.stat.auckland.ac.nz/~paul/RGraphics/examples-map.R
> However, the following problem has me stumped:  New Zealand lies along a 
>   N.E. - S.W. axis, leaving room in the bottom right (or top left) 
> corner of a figure for a small map of the world.  In contrast the 48 
> contiguous states nearly fill a rectangular figure, leaving no room for 
> Alaska in the upper left and little room for Hawaii in the lower left. 
> I haven't figured out how to make space in a figure for the 3 maps.  I'm 
> aware of the grid package but suspect that its strictly rectangular 
> layout will leave too much empty space in the figure.
> 
> Suggestions for positioning three maps in one figure would be very welcome.


The problem in traditional graphics is that any plotting function that
messes around with par() can cause problems if you want to draw more
than one of that sort of plot on the same page.  The map() function does
more than its fair share of messing with par(), which is why the code
behind the example from my book is pretty nasty.

However, using the layout() function, it is possible to get somewhere.

You can do three maps pretty easily with a simple layout() ...


library(maps)
library(mapdata)

layout(rbind(c(1, 0),
             c(0, 2),
             c(3, 0)),
       widths=c(1, 2),
       heights=c(1, 2))

# Run the command below to see the arrangement of the plot regions
# layout.show(3)

par(oma=rep(1, 4))
par(mar=rep(0, 4))
map("world2Hires", "USA:Alaska")
# Need to explicitly call par() between each map
# to avoid problem caused by map() resetting par() internally
par(mar=rep(0, 4))
map("state")
par(mar=rep(0, 4))
map("world2Hires", "Hawaii")


... and you can do better with a bit more work using a more complex
layout() that allows the plot regions to overlap ...


# The trick is that, e.g., plot 1 occupies columns
# 1 to 3 of rows 1 to 3 in this layout, while plot 2
# occupies columns 2 to 4 of rows 2 to 6, etc
layout(rbind(c(1, 0, 1, 0),
             c(0, 2, 0, 2),
             c(1, 0, 1, 0),
             c(0, 2, 0, 2),
             c(3, 0, 3, 0),
             c(0, 2, 0, 2),
             c(3, 0, 3, 0)),
       # You can spend hours fiddling with the relative
       # widths and heights of rows and columns that are
       # or are not shared between plots
       widths=c(1, 0, .5, 2),
       heights=c(1, 1, 0, 1, 2, 0, .1))

# layout.show(3)

par(oma=rep(1, 4))
par(mar=rep(0, 4))
map("world2Hires", "USA:Alaska")
par(mar=rep(0, 4))
map("state")
par(mar=rep(0, 4))
map("world2Hires", "Hawaii")


... it would be easier to play with the placement of the three plot
regions just using par(fig), but the problems caused by map()s
manipulation of par() are then much harder to work around.

Hope that helps.

Paul
-- 
Dr Paul Murrell
Department of Statistics
The University of Auckland
Private Bag 92019
Auckland
New Zealand
64 9 3737599 x85392
paul at stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/



More information about the R-help mailing list