
Last chance! 50% off unlimited learning
Sale ends in
## S3 method for class 'plot':
image(...,
add = FALSE, nlevel = 64, horizontal = FALSE,
legend.shrink = 0.9, legend.width = 1.2, legend.mar =
ifelse(horizontal, 3.1, 5.1), legend.lab = NULL,legend.line = 2,
graphics.reset = FALSE, bigplot = NULL, smallplot =
NULL, legend.only = FALSE, col = tim.colors(nlevel),
lab.breaks = NULL, axis.args = NULL, legend.args =
NULL, midpoint=FALSE, border=NA, lwd=1.0)
par()$plt
may be changed to reflect a
smaller plotting region that has accommodated room for the legend subplot. If xlim
and ylim
are specified the pixels may overplot the axis lines.
Just use the box
function to redraw them.
image.plot
is simple, divide the plotting region
into two smaller regions bigplot
and smallplot
. The image
goes in one and the legend in the other. This way there is always room for
the legend. Some adjustments are made to this rule by not shrinking the
bigplot
if there is already room for the legend strip and also
sticking the legend strip close to the image plot. One can specify the
plot regions explicitly by bigplot
and smallplot
if the
default choices do not work. There may be problems with small plotting
regions in fitting both of these elements in the plot region and one may
have to change the default character sizes or margins to make things fit.
Sometimes this function will not reset the type of margins correctly and the
"null" call par(mar = par("mar"))
may help to fix this issue.Almost cloropleths too: It should be noted that this image function is slightly
different than a cloropleth map because
the legend is assuming that a continous scale has been discretized into a series of colors.
To make image.plot function as a cloropleth graphic one would of course use the
breaks
option
and for clarity perhaps code the different regions as different integer values.
In addition, for publication quality one would want to use the legend.args
to
add more descriptive labels at the midpoints in the color strip.
Relationship of x, y and z:
If the z component is a matrix then the user should be aware that
this function locates the matrix element z[i,j] at the grid locations
(x[i], y[j]) this is very different than simply listing out the
matrix in the usual row column tabular form. See the example below
fo details on the difference in formatting. What does one do
if you don't really have the "z" values on a regular grid? See the
functions quilt.plot.Rd
and as.image
to discretise
irregular observations to a grid.
Grids with unequally spacing:
If x and y are matrices that are a smooth transformation of a regular grid then
z[i,j] is rendered at a quadrilateral that is centered at x[i,j] and
y[i,j] (midpoint
TRUE). The details of how this cell is found
are buried in poly.image
but it it essentially found using midpoints between the centers.If midpoint
is FALSE then x
and y are interpreted as the corners of the quadrilateral cells. But
what about z? The four values of z are now averaged to represent a
value at the midpoint of the cell and this is what is used for
plotting. Quadrilateral grids were added to help with plotting
the gridded output of geophysical models where the regular grid is
defined according to one map projection but the image plotting is required
in another projection. Typically the regular grid becomes distorted in
a smooth way when this happens. See the regional climate example for
a illustration of this application. One can add border colors in this case
easily because these choices are jsut passed onto the polygon function.
Adding the pixel grid for rectangular images:
For adding the grid of pixel borders to a rectangular image try this example
after calling image.plot
dx<- x[2] - x[1]
dy <- y[2]-y[1]
xtemp<- seq( min( x)- dx/2, max(x)+ dx/2,, length(x) +1)
ytemp<- seq( min( y)- dy/2, max(y)+ dy/2,, length(y) +1)
xline( xtemp, col="grey50", lwd=2); yline( ytemp, col="grey50", lwd=2)
Here x
and y
here are the x and y grid values from the image list.
Fine tuning color scales: This function gives some flexibility in
tuning the color scale to fit the rendering of z values. This can
either be specially designed color scale with specific colors ( see
help on designer.colors
), positioning the colors at specific
points on the [0,1] scale, or mapping distinct colors to intervals of
z. The examples below show how to do each of these. In addition, by
supplying lab.break
strings or axis parameters one can
annotate the legend axis in an informative matter.
The details of placing the legend and dividing up the plotting real estate: It is surprising how hard it is to automatically add the legend! All "plotting coordinates" mentioned here are in device coordinates. The plot region is assumed to be [0,1]X[0,1] and plotting regions are defined as rectangles within this square. We found these easier to work with than user coordinates.
legend.width
and legend.mar
are in units of character
spaces. These units are helpful in thinking about axis labels that
will be put into these areas. To add more or less space between the
legend and the image plot alter the mar parameters. The default mar
settings (5.1,5.1,5.1,2.1) leaves 2.1 spaces for vertical legends and
5.1 spaces for horizontal legends.
There are always problems with
default solutions to placing information on graphs but the choices made
here may be useful for most cases. The most annoying thing is that after
using plot.image and adding information the next plot that is made may
have the slightly smaller plotting region set by the image plotting.
The user should set reset.graphics=TRUE
to avoid the plotting size
from changing. The disadvantage, however, of resetting the graphics
is that one can no longer add additional graphics elements to the image
plot. Note that filled.contour always resets the graphics but provides
another mechanism to pass through plotting commands. Apparently
filled.contour
, while very pretty, does not work for multiple plots.
levelplot
that is part of the lattice package has a very
similar function to image.plot and a formula syntax in the call.
By keeping the zlim
argument the same across images one can generate the
same color scale. (See the image help file.) One useful technique for a
panel of images is to just draw the images with image
and then use image.plot to add a legend to the last plot. (See example
below for messing with the outer margins to make this work.)
Usually a square plot (pty="s"
) done in a rectangular plot region will
have room for the legend stuck to the right side without any other
adjustments. See the examples below for more complicated arrangements
of multiple image plots and a summary
legends.
Adding just the legend strip:
Note that to add just the legend strip all the numerical information one
needs is the zlim
argument and the color table!
About color tables:
We like tim.colors
as a default color scale and so if this what you use this can be omitted. The
topographic color scale (topo.colors
) is
also a close second showing our geophysical bias.
Users may find larry.colors
useful for coding distinct regions
in the style of a cloropleith map. See also
terrain.colors
for a subset of the topo ones and designer.colors
to "roll
your own" color table. One nice option in this last function is to fix color transitions at
particular quantiles of the data rather than at equally spaced
intervals. For color choices see how the nlevels
argument figures
into the legend and main plot number of colors. Also see the colors
function
for a listing of all the colors that come with the R base environment.
x<- 1:10
y<- 1:15
z<- outer( x,y,"+")
image.plot(x,y,z)
# or
obj<- list( x=x,y=y,z=z)
image.plot(obj, legend.lab="Sverdrups")
# to show how we are reset to the main image add some points on diagonal
# (with some clipping beyond 10 anticipated)
points( 5:12, 5:12, pch="X", cex=3)
# adding breaks and distinct colors for intervals of z
# with and without lab.breaks
brk<- quantile( c(z))
image.plot(x,y,z, breaks=brk, col=rainbow(4))
# annotate legend strip at break values and add a label
image.plot(x,y,z, breaks=brk, col=rainbow(4),
lab.breaks=names(brk))
#
# compare to
quantile(c(z), c( .05, .1,.5, .9,.95))-> zp
image.plot(x,y,z,
axis.args=list( at=zp, labels=names(zp) ) )
# a log scaling for the colors
ticks<- c( 1, 2,4,8,16,32)
image.plot(x,y,log(z), axis.args=list( at=log(ticks), labels=ticks))
# see help file for designer.colors to generate a color scale that adapts to
# quantiles of z.
#
#fat (5 characters wide) and short (50\% of figure) color bar on the bottom
image.plot( x,y,z,legend.width=5, legend.shrink=.5, horizontal=TRUE)
# adding label with all kinds of additional arguments.
# use side=4 for vertical legend and side= 1 for horizontal legend
# to be parallel to axes. See help(mtext).
image.plot(x,y,z,
legend.args=list( text="unknown units",
col="magenta", cex=1.5, side=4, line=2))
#### example using a irregular quadrilateral grid
data( RCMexample)
image.plot( RCMexample$x, RCMexample$y, RCMexample$z[,,1])
ind<- 50:75 # make a smaller image to show bordering lines
image.plot( RCMexample$x[ind,ind], RCMexample$y[ind,ind], RCMexample$z[ind,ind,1],
border="grey50", lwd=2)
#### multiple images with a common legend
set.panel()
# Here is quick but quirky way to add a common legend to several plots.
# The idea is leave some room in the margin and then over plot in this margin
par(oma=c( 0,0,0,4)) # margin of 4 spaces width at right hand side
set.panel( 2,2) # 2X2 matrix of plots
# now draw all your plots using usual image command
for ( k in 1:4){
image( matrix( rnorm(150), 10,15), zlim=c(-4,4), col=tim.colors())
}
par(oma=c( 0,0,0,1))# reset margin to be much smaller.
image.plot( legend.only=TRUE, zlim=c(-4,4))
# image.plot tricked into plotting in margin of old setting
set.panel() # reset plotting device
#
# Here is a more learned strategy to add a common legend to a panel of
# plots consult the split.screen help file for more explanations.
# For this example we draw two
# images top and bottom and add a single legend color bar on the right side
# first divide screen into the figure region (left) and legend region (right)
split.screen( rbind(c(0, .8,0,1), c(.8,1,0,1)))
# now subdivide up the figure region into two parts
split.screen(c(2,1), screen=1)-> ind
zr<- range( 2,35)
# first image
screen( ind[1])
image( x,y,z, col=tim.colors(), zlim=zr)
# second image
screen( ind[2])
image( x,y,z+10, col=tim.colors(), zlim =zr)
# move to skinny region on right and draw the legend strip
screen( 2)
image.plot( zlim=zr,legend.only=TRUE, smallplot=c(.1,.2, .3,.7),
col=tim.colors())
close.screen( all=TRUE)
# you can always add a legend arbitrarily to any plot;
# note that here the plot is too big for the vertical strip but the
# horizontal fits nicely.
plot( 1:10, 1:10)
image.plot( zlim=c(0,25), legend.only=TRUE)
image.plot( zlim=c(0,25), legend.only=TRUE, horizontal =TRUE)
# combining the usual image function and adding a legend
# first change margin for some more room
par( mar=c(10,5,5,5))
image( x,y,z, col=topo.colors(64))
image.plot( zlim=c(0,25), nlevel=64,legend.only=TRUE, horizontal=TRUE,
col=topo.colors(64))
#
#
# sorting out the difference in formatting between matrix storage
# and the image plot depiction
# this really has not much to do with image.plot but I hope it is useful
A<- matrix( 1:48, ncol=6, nrow=8)
# first column of A will be 1:8
# ... second is 9:16
image.plot(1:8, 1:6, A)
# add labels to each box
text( c( row(A)), c( col(A)), A)
# and the indices ...
text( c( row(A)), c( col(A))-.25,
paste( "(", c(row(A)), ",",c(col(A)),")", sep=""), col="grey")
# "columns" of A are horizontal and rows are ordered from bottom to top!
#
# matrix in its usual tabular form where the rows are y and columns are x
image.plot( t( A[8:1,]), axes=FALSE)
Run the code above in your browser using DataLab