7. Advanced R Graphics - Using External R

7. Advanced R Graphics - Using External R Packages
by F. Guillaume Blanchet, University of Alberta, November 2009
In this document, we will see how far R
can go with graphical representations. As
R is constantly developing, this document
will be a short overview of the potential R
can offer.
The following graphical examples are
presented to show you how powerful the
graphical interface of R is. Unlike the
other parts of this seminar, the code to
draw the graphics will not always precede
the figure. However, for you to be able to
reproduce it, a link to the source code on
the web will be given in replacement.
Potential of the basic graphical tools in
R (no extras)
The graphical interface of R was designed
in such a way as to make the graphical
output flexible and over all very good
looking. It allows graphics that are
statistical in nature to be drawn with a
very polished way. For example:
http://www.stat.auckland.ac.nz/~paul/RGraphics/examples-stdplots.R
The graphical interface in R is so powerful that it even allows graphics such as the following one, which
are non-statistic in nature, to be drawn through R and still look very good.
http://www.stat.auckland.ac.nz/~paul/RGraphics/examples-stevemiller.R
Using packages to draw graphics
From this point on, we will focus our attention on statistical graphics. We will also go one step further than
before by introducing packages that will allow much more flexibility than what we have seen so far. In R, a
package is a group of functions and data files that are not included in R when you open it. They need to
be downloaded and open within R to have access to all the goodies they offer.
1
Maps in R
For rudimentary mapping in R, the packages maps and mapdata are necessary. They contain maps of
every country. For the United States of America, France, and China, these packages even contain
information about provinces (or states) and counties. These packages also contain some basic
geographical features such as rivers.
> library(maps)
> library(mapdata)
If you want to plot mainland France and Corsica, with all the provinces, you simple have to type:
> map("france")
This is because France (like USA, China, and New-Zealand) is a special country in the packages maps
and mapdata packages. Every other country can be plotted like this:
> map(region="canada")
2
Note that some countries like the United Kingdom, France, or USA have colonies all over the world. These
are also considered as part of the country when you type in R.
> map(region="france")
If you feel that the look of the maps is not very nice, you can have access to a large number of different
projections in the package mapproj. You can thus project the maps for them to be more suited to you
need.
> map(region="canada",projection="gilbert")
It is also possible to plot a variable as a colour gradient for each state or province of a country. To show
how we can do this, we will use a map of the states of the Unites States of America and the USArrests
dataset, which present some information about the violent crime rates per states of the United States of
America. Lets take a look at how the assault varies between the different states of the United States of
America.
The first thing we need to do is to adjust the data to make sure that it fits with the map:
> assault.map<-c(USArrests.new$Assault[1:7],100,USArrests.new$Assault[c(8:18,
rep(19,3),rep(20,2),21:29,rep(30,4),rep(31,3),32:43,rep(44,3),rep(45,5),
46:48)])
We can then draw the map (here red means high assault rate and yellow means low):
> map("state",projection="azequidistant",fill=TRUE,
col=sort(heat.colors(max(assault.map)),decreasing=TRUE)[assault.map])
3
Star and segment plots
Star plot and segments plots are usually used to illustrate information of multivariate data. The function
that allows to draw these plots comes in the basic packages of R and is called stars(). To illustrate how
this function works we will use again the USArrests dataset.
To draw a stars plot you can type:
> data(USArrests)
> stars(USArrests,key.loc=c(15,1.5))
The argument key.loc places a legend at 15 on the x-axis and 1.5 on the y axis.
With the same function you can draw segment plots. You only have to specify the draw.segments
argument to TRUE one argument to the function stars(). So, again using the USArrests data:
> data(USArrests)
> stars(USArrests,draw.segments=TRUE,key.loc=c(15,1.5))
With a little bit of work it is also possible to overlay this information over each states of a map of the United
States of America.
The first thing that needs to be done is to load the package that contains the map of the United States of
America by states and the package that allow us to present different projection of this map (this last
package is not necessary but it will give a much more polished result)
> library(map)
> library(mapproj)
4
We then need to load the data and play with it a little in order that each segment plot overlay nicely on top
of each states it gives information about (the code was commented here to simplify the understanding):
> ### Get data
> data(USArrests)
> ### Remove entries from Hawaii and Alaska
> USArrests.new<-USArrests[!(rownames(USArrests)=="Hawaii" |
rownames(USArrests)=="Alaska"),]
> ### find the names of USArrests.new
> names.pre<-rownames(USArrests.new)
> ### Find the center of each states
states.mid<-matrix(NA,nrow=48,ncol=2)
> for(i in 1:length(names.pre)){
plot.state<-map("state",names.pre[i],plot=FALSE)
states.mid[i,1]<-mean(plot.state$x,na.rm=TRUE)
states.mid[i,2]<-mean(plot.state$y,na.rm=TRUE)
}
Lets plot a map of the continental United States of America (without Alaska) using the Azimuthal
projection centred on the North Pole, where the parallels are equally spaced and the true distance ratio is
considered from the pole.
> map("state",projection="azequidistant")
As a last step we can add the segment plots over each states. However, before we do that we will need to
make sure that the geographical centre of each state is in the same projection as the map we will plot our
segment plots on:
> ### Transform the coordinates of the state's centre for the good projection
> states.good<-mapproject(states.mid[,1],states.mid[,2],
projection="azequidistant")
> ### Make a matrix for the coordinates in the proper projection
> state.ct<-cbind(states.good$x,states.good$y)
> ### Add the segment plots to the map of the USA
> stars(USArrests.new,draw.segments=TRUE,locations=state.ct,add=TRUE,len=0.02,
labels=NULL,key.loc=c(0.4,1.1),
col.segments=c("red","yellow","blue","green"))
The resulting plot looks like this:
5
Triangular plot
Triangular plots are often used in soil science to define which type of soil we have. These types of graphic
are also implemented in R. They are part of the package plotrix. To show how to draw triangular
graphics in R we will use the soils dataset which is in the package plotrix.
> library(plotrix)
> data(soils)
> triax.plot(soils[1:10,],show.grid=TRUE,show.legend=TRUE,col.symbols=
rainbow(10),pch=10)
3D function plots
This section will focus on 3D graphs where in the third axis (z-axis) you have the information for all the
possible combination of the x-axis and the y-axis. These functions can be very useful when constructing
an interpolation map for example.
There are many ways to add a third dimension in a graphic. Most of these can be drawn without the need
of any R packages. To present how this is done, we will construct our own data:
>
>
>
>
x.coord
y.coord
func <z.coord
<- seq(-10, 10, length= 50)
<- x.coord
function(x,y) { r <- sqrt(abs(x^3)+y^2); sin(r)/r }
<- outer(x.coord, y.coord, func)
It is possible to plot a third dimension using a perspective plot...
> persp(x.coord,y.coord,z.coord,theta=30,phi=30,expand=0.5,col="lightgreen",
ltheta=120,shade=0.75,ticktype="detailed",xlab="X",ylab="Y",zlab="Z")
6
A colour image...
> image(x.coord,y.coord,z.coord,col=terrain.colors(20),xlab="X",ylab="Y")
A contour map...
> contour(x.coord,y.coord,z.coord,xlab="X",ylab="Y")
7
Or a filled contour map...
> filled.contour(x.coord,y.coord,z.coord,col=rainbow(40),xlab="X",ylab="Y")
These R functions to draw 3D function plots can also be used to draw landscape, try using the volcano
data already included in R. This data present 10 m by 10 m topographic information of the Maunga Whau
(Mount Edent), it is one of the 50 volcanos in the Auckland volcanic field.
3D scatter plots
In this section we will focus on 3D scatter plots. In contrast with the 3D function plots presented above,
you do not need to have data for all the combination of the X and Y axis. As an example, we will use the
oribatid data given is in the ade4 package. The function to plot 3D plots is called scatterplot3d
and it is found in the package scatterplot3d (which contains only one function... guess which one!).
Lets first get the data:
> library(ade4)
> data(oribatid)
We will use two environmental variables (soil density and water content in the soil) to try to model the
distribution of the first species in the dataset. Lets first isolate these three variables in order to make the r
code litter.
> dens<-oribatid$envir$density
> water<-oribatid$envir$water
> sp<-oribatid$fau[,1]
Now it is possible to plot these three variables. With scatterplot3d(), a number of arguments were
added to show a little bit of what this function can do:
> library(scatterplot3d)
> plot3D <- scatterplot3d(dens,water,sp,highlight.3d=TRUE,pch=19,type="h",
xlab="Soil density",ylab="Soil water content",zlab="species")
8
Notice that the result of scatterplot3d() was placed in the object plot3D. This was done because
scatterplot3d() is a special function that include four subfunctions, which allow to add additional
pieces to the graph previously drawn. For example, if we want to draw the result of a linear regression on
this figure, which would be a plane (not a line), we can do it following this procedure.
First we need to compute the linear regression between the species and the two explanatory variables:
> reg<-lm(sp~dens+water)
Then we can draw the result of the regression on our 3D plot.
> plot3D$plane3d(reg,col="blue",lty.box="solid")
9
Although this give an informative result, the graph may be easier to read if it was presented in a different
angle. To do this you need to use the argument angle in the scatterplot3d() function.
> plot3D.2 <- scatterplot3d(dens,water,sp,highlight.3d=TRUE,pch=19,type="h",
xlab="Soil density",ylab="Soil water content",zlab="species",angle=145)
> plot3D.2$plane3d(reg,col="blue",lty.box="solid")
Interactive 3D plots
Drawing interactive 3D plots can also be done in R with the package rgl. As it is not possible for me to
include interactive figures in this handout. The best way for you to see the potential of the package rgl is
to type these code lines:
> library(rgl)
> demo(rgl)
Choosing the right colours
When you are drawing colour graphics, it is important to think of the ones in the crowed that may be
colorblind. The package dichromat will help you to choose the right colour when drawing your graphics.
The dichromat package gives a series of colour palettes which are suitable for people with anomalous
or deficiencies in red-green vision. You can find 17 of them by typing ?colourschemes in R after
opening the dichromat package.
Here are four examples of these colour palettes:
> par(mar=c(1,2,1,1),mfrow=c(4,1))
10
> image(1:100,1,as.matrix(1:100),
col=colorRampPalette(colorschemes$BluetoDarkOrange.18)(100),
main="Blue to Dark Orange", axes=FALSE)
> image(1:100,1,as.matrix(1:100),
col=colorRampPalette(colorschemes$BluetoGreen.14)(100),
main="Blue to Green",axes=FALSE)
> image(1:100,1,as.matrix(1:100),
col=colorRampPalette(colorschemes$LightBluetoDarkBlue.10)(100),
main="Light Blue to Dark Blue",axes=FALSE)
> image(1:100,1,as.matrix(1:100),
col=colorRampPalette(colorschemes$Categorical.12)(100),
main="Adapted Rainbow", axes=FALSE)
You can notice that the function colorRampPalette() was used to construct this figure.
colorRampPalette() allows to interpolate a set of given colours to create a new colour palette.
You can also use the function dichromat() to see how people suffering from protanopia (absence of red
retinal photoreceptors, which means that reds appears dark) and deuteranopia (absence of green retinal
photoreceptors, which it difficult to distinguish red-green hue) would see the colour you are using in your
graphic. As an example, lets use the colour palettes used in this documents:
> par(mar=c(1,2,1,1),mfcol=c(3,3))
>
> image(1:100,1,as.matrix(1:100),col=heat.colors(100),main="Normal",
axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=terrain.colors(100), axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=rainbow(100), axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(heat.colors(100),"deutan"),
main="Deuteranopia", axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(terrain.colors(100),"deutan"),
axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(rainbow(100),"deutan"),
axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(heat.colors(100),"protan"),
main="Protanopia", axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(terrain.colors(100),"protan"),
axes=FALSE)
> image(1:100,1,as.matrix(1:100),col=dichromat(rainbow(100),"protan"),
axes=FALSE)
11
Not a very good use of colours it seems :-(
The function dichromat() can easily be used to evaluate the colours in a graphic you are plotting. Here
is an example using a very famous dataset sampled by Edgar Anderson on the Gaspé peninsula in
Québec.
>
>
>
>
>
>
data(iris)
colo<-c("red","green3","blue")
par(mfrow=c(1,3))
plot(iris[,1:2],pch=19,col=colo[iris$Species],main="Normal")
plot(iris[,1:2],pch=19,col=dichromat(colo[iris$Species],"deutan"),main="Deuteranopia")
plot(iris[,1:2],pch=19,col=dichromat(colo[iris$Species],"protan"),main="Protanopia")
Extras...
As you can see, there are tremendous possibilities when drawing graphics. R offers the flexibility to draw
these graphics and often someone has already taken the time to write code to make it accessible to
everyone.
What is presented in this document is just a very small sample of what can be done in R. To know more
about the possibilities of the basic R graphic parameters, you can take a look at the book by Paul Murrell
entitled R Graphics.
To see various types of graphic that can be drawn with the help of external packages. You can have a
look at the following website:
http://addictedtor.free.fr/graphiques/
At this website, the R source code to draw the graphics in addition to a figure representing what the output
should look like is given.
12