Robert I. Kabacoff - R in action
.pdf
386 |
CHAPTER 16 Advanced graphics |
The same plot symbols, line types, and colors are specified within the densityplot() function $. Additionally, the line width and jitter are increased to improve the appearance of the graph. Finally, the key is set to use the previously defined list. This approach to specifying a legend for the grouping variable allows a great deal of flexibility. In fact, you can create more than one legend and place them in different areas of the graph (not shown here).
Before completing this section, let’s consider an example that includes group and conditioning variables in a single plot. The CO2 data frame, included with the base R installation, describes a study of cold tolerance of the grass species Echinocholoa crus-galli.
The data describe carbon dioxide uptake rates (uptake) for 12 plants (Plant), at seven ambient carbon dioxide concentrations (conc). Six plants were from Quebec and six plants were from Mississippi. Three plants from each location were studied under chilled conditions and three plants were studied under nonchilled conditions. In this example, Plant is the group variable and both Type (Quebec/Mississippi) and Treatment (chilled/nonchilled) are conditioning variables. The following code produces the plot in figure 16.7.
Listing 16.5 xyplot with group and conditioning variables and customized legend
library(lattice) colors <- "darkgreen" symbols <- c(1:12) linetype <- c(1:3)
key.species <- list(title="Plant", space="right", text=list(levels(CO2$Plant)),
points=list(pch=symbols, col=colors))
xyplot(uptake~conc|Type*Treatment, data=CO2, group=Plant,
type="o",
pch=symbols, col=colors, lty=linetype, main="Carbon Dioxide Uptake\nin Grass Plants", ylab=expression(paste("Uptake ",
bgroup("(", italic(frac("umol","m"^2)), ")"))), xlab=expression(paste("Concentration ",
bgroup("(", italic(frac(mL,L)), ")"))), sub = "Grass Species: Echinochloa crus-galli", key=key.species)
Note the use of \n to give you a two-line title and the use of the expression() function to add mathematical notation to the axis labels. Here, color is suppressed as a group differentiator by specifying a single color in the col= option. In this case, adding 12 different colors is overkill and distracts from the goal of easily visualizing the relationships in each panel. Clearly, there’s something different about the Mississippi grasses in the chilled condition.
388 |
CHAPTER 16 Advanced graphics |
As an example, let’s change the default symbol used for superimposed points (that is, points in a graph that includes a group variable). The default is an open circle. We’ll give each group their own symbol instead.
First, view the current defaults and save them into a list called mysettings:
>show.settings()
>mysettings <- trellis.par.get()
Next, look at the defaults that are specific to superimposed symbols:
> mysettings$superpose.symbol $alpha
[1] 1 1 1 1 1 1 1
$cex
[1] 0.8 0.8 0.8 0.8 0.8 0.8 0.8
$col
[1] "#0080ff" "#ff00ff" "darkgreen" "#ff0000" "orange" "#00ff00" [7] "brown"
$fill
[1] "#CCFFFF" "#FFCCFF" "#CCFFCC" "#FFE5CC" "#CCE6FF" "#FFFFCC" "#FFCCCC"
$font
[1] 1 1 1 1 1 1 1
$pch
[1] 1 1 1 1 1 1 1
Here you see that the symbol used for each level of a group variable is an open circle (pch=1). Seven levels are defined, after which symbols recycle.
Finally, issue the following statements:
mysettings$superpose.symbol$pch <- c(1:10) trellis.par.set(mysettings) show.settings()
Lattice graphs now use symbol 1 (open circle) for the first level of a group variable, symbol 2 (open triangle) for the second, and so on. Additionally, symbols have been defined for 10 levels of a grouping variable, rather than 7. The changes will remain in effect until all graphic devices are closed. You can change any graphic setting in this manner.
16.2.5Page arrangement
In chapter 3 you learned how to place more than one graph on a page using the par() function. Because lattice functions don’t recognize par() settings, you’ll need a different approach. The easiest method involves saving your lattice graphs as objects, and using the plot() function with either the split= or position= option specified.
The split option divides a page up into a specified number of rows and columns and places graphs into designated cells of the resulting matrix. The format for the split option is
The lattice package |
389 |
split=c(placement row, placement column,
total number of rows, total number of columns)
For example, the following code
library(lattice)
graph1 <- histogram(~height|voice.part, data=singer,
main="Heights of Choral Singers by Voice Part") graph2 <- densityplot(~height, data=singer, group=voice.part,
plot.points=FALSE, auto.key=list(columns=4)) plot(graph1, split=c(1, 1, 1, 2))
plot(graph2, split=c(1, 2, 1, 2), newpage=FALSE)
places the first graph directly above the second graph. Specifically, the first plot() statement divides the page up into one column and two rows and places the graph in the first column and first row (counting top-down and left-right). The second plot() statement divides the page up in the same way, but places the graph in the first column and second row. Because the plot() function starts a new page by default, you suppress this action by including the newpage=FALSE option. (I’ve omitted the graph to save space.)
You can gain more control of sizing and placement by using the position= option. Consider the following code:
library(lattice)
graph1 <- histogram(~height|voice.part, data=singer,
main="Heights of Choral Singers by Voice Part") graph2 <- densityplot(~height, data=singer, group=voice.part,
plot.points=FALSE, auto.key=list(columns=4)) plot(graph1, position=c(0, .3, 1, 1))
plot(graph2, position=c(0, 0, 1, .3), newpage=FALSE)
Here, position=c(xmin, ymin, xmax, ymax), where the x-y coordinate system for the page is a rectangle with dimensions ranging from 0 to 1 on both the x and y axes, and the origin (0,0) at the bottom left. (Again, the resulting graph is omitted to save space.)
You can also change the order of the panels in a lattice graph. The index.cond= option in a high-level lattice graph function specifies the order of the conditioning variable levels. For the voice.part factor, the levels are
> levels(singer$voice.part) |
|
|||
[1] |
"Bass 2" |
"Bass 1" |
"Tenor 2" "Tenor 1" "Alto 2" |
"Alto 1" |
[7] |
"Soprano |
2" "Soprano |
1" |
|
Adding index.cond=list(c(2, 4, 6, 8, 1, 3, 5, 7)) would place the "1" voice parts together, followed by "2" voice parts. When there are two conditioning variables, include two vectors in the list. In listing 16.5, adding index.cond=list(c(1, 2), c(2, 1)) would reverse the order of treatments in figure 16.7.
To learn more about lattice graphs, take a look the excellent text by Sarkar (2008) and its supporting website at http://lmdvr.r-forge.r-project.org. The Trellis Graphics User’s Manual (http://cm.bell-labs.com/cm/ms/departments/sia/doc/trellis.user. pdf) is also an excellent source of information.
In the next section, we’ll explore a second comprehensive alternative to R’s native graphic system. This one is based on the ggplot2 package.
390 |
CHAPTER 16 Advanced graphics |
16.3 The ggplot2 package
The ggplot2 package implements a system for creating graphics in R based on a comprehensive and coherent grammar. This provides a consistency to graph creation often lacking in R, and allows the user to create graph types that are innovative and novel.
The simplest approach for creating graphs in ggplot2 is through the qplot() or quick plot function. The format is
qplot(x, y, data=, color=, shape=, size=, alpha=, geom=, method=, formula=, facets=, xlim=, ylim=, xlab=, ylab=, main=, sub=)
where the parameters/options are defined in table 16.4.
Table 16.4 qplot options
Option |
Description |
|
|
alpha |
Alpha transparency for overlapping elements expressed as a fraction between 0 |
|
(complete transparency) and 1 (complete opacity). |
color, shape, |
Associates the levels of variable with symbol color, shape, or size. For line plots, |
size, fill |
color associates levels of a variable with line color. For density and box plots, |
|
fill associates fill colors with a variable. Legends are drawn automatically. |
data |
Specifies a data frame. |
facets |
Creates a trellis graph by specifying conditioning variables. Its value is expressed |
|
as rowvar ~ colvar (see the example in figure 16.10). To create trellis graphs |
|
based on a single conditioning variable, use rowvar~. or .~colvar. |
geom |
Specifies the geometric objects that define the graph type. The geom option is |
|
expressed as a character vector with one or more entries. geom values include |
|
"point", "smooth", "boxplot", "line", "histogram", "density", |
|
"bar", and "jitter". |
main, sub |
Character vectors specifying the title and subtitle. |
method, |
If geom="smooth", a loess fit line and confidence limits are added by default. |
formula |
When the number of obser vations is greater than 1,000, a more efficient |
|
smoothing algorithm is employed. Methods include "lm" for regression, "gam" |
|
for generalized additive models, and "rlm" for robust regression. The formula |
|
parameter gives the form of the fit. |
|
For example, to add simple linear regression lines, you’d specify |
|
geom="smooth", method="lm", formula=y~x. Changing the formula to |
|
y~poly(x,2) would produce a quadratic fit. Note that the formula uses the |
|
letters x and y, not the names of the variables. |
|
For method="gam", be sure to load the mgcv package. For method="rml", |
|
load the MASS package. |
x, y |
Specifies the variables placed on the horizontal and ver tical axis. For univariate |
|
plots (for example, histograms), omit y. |
xlab, ylab |
Character vectors specifying horizontal and ver tical axis labels. |
xlim, ylim |
Two-element numeric vectors giving the minimum and maximum values for the |
|
horizontal and ver tical axes, respectively. |
|
|
392 |
CHAPTER 16 Advanced graphics |
Figure 16.9 Scatter plot between auto mileage and car weight, with
separate regression lines and confidence bands by engine transmission
type (manual, automatic)
The resulting graph is provided in figure 16.9. This is a useful type of graph, not easily created using other packages.
As a third example, we’ll create a faceted (trellis) graph. Each facet (panel) displays the scatter plot between gas mileage and car weight. Row facets are defined by the transmission type, whereas column facets are defined by the number of cylinders present. The size of each data point represents the car’s horsepower rating.
library(ggplot2)
mtcars$cyl <- factor(mtcars$cyl, levels=c(4, 6, 8),
labels=c("4 cylinders", "6 cylinders", "8 cylinders")) mtcars$am <- factor(mtcars$am, levels=c(0, 1),
labels=c("Automatic", "Manual")) qplot(wt,mpg, data=mtcars, facets=am~cyl, size=hp)
The graph is displayed in figure 16.10. Note how simple it is to create a complex graph (actually a bubble chart). You may want to try adding shape and color options to the function call and see how the resulting graph is affected.
We’ll end this section by revisiting the singer data with which we began the chapter. This code produces the graph in figure 16.11:
library(ggplot2)
data(singer, package="lattice")
qplot(height, data=singer, geom=c("density"), facets=voice.part~., fill=voice.part)
394 |
CHAPTER 16 Advanced graphics |
Comparing the distribution of heights is easier in this format than in the format presented in figure 16.1. (Once again, this looks better when displayed in color.)
We’ve only scratched the surface of this powerful graphical system. Interested readers are referred to Wickham (2009), and the ggplot2 website (http://had.co.nz/ ggplot2/) for more information. We’ll end this chapter with a review of interactive graphics and R functions that support them.
16.4 Interactive graphs
The base installation of R provides limited interactivity with graphs. You can modify graphs by issuing additional program statements, but there’s little that you can do to modify them or gather new information from them using the mouse. However, there are contributed packages that greatly enhance your ability to interact with the graphs you create. In this section, we’ll focus on functions provided by the playwith, latticist, iplots, and rggobi packages. Be sure to install them before first use.
16.4.1 Interacting with graphs: identifying points
Before getting to the specialize packages, let’s review a function in the base R installation that allows you to identify and label points in scatter plots. Using the identify() function, you can label selected points in a scatter plot with their row number or row name using your mouse. Identification continues until you select Stop or right-click on the graph. For example, after issuing the following statements
plot(mtcars$wt, mtcars$mpg)
identify(mtcars$wt, mtcars$mpg, labels=row.names(mtcars))
the cursor will change from a pointer to a crosshair. Clicking on scatter plot points will label them until you select Stop from the Graphics Device menu or right-click on the graph and select Stop from the context menu.
Many graphic functions in contributed packages (including functions from the car package discussed in chapter 8) employ this method for labeling points. Unfortunately, the identify() function doesn’t work with lattice or ggplot2 graphs.
16.4.2playwith
The playwith package provides a GTK+ graphical user interface that allows users to edit and interact with R plots. You can install the playwith package on any platform using install.packages("playwith", depend=TRUE). On platforms running Mac
OS X and Linux, it’s best to also install the JGR graphic user interface (see appendix A), and run playwith from within this GUI.
The playwith()function allows users to identify and label points, view all variable values for an observation, zoom and pan, add annotations (text, arrows, lines, rectangles, titles, labels), change visual elements (colors, text sizes, and so on), apply previously saved styles, and output the resulting graph in a variety of formats. This is easily demonstrated with an example. After running the following code
Interactive graphs |
395 |
library(playwith)
library(lattice)
playwith(
xyplot(mpg~wt|factor(cyl)*factor(am), data=mtcars, subscripts=TRUE, type=c("r", "p"))
)
the window in figure 16.12 will appear on the screen. Try out the buttons on the left, as well as the menu items. The GUI is fairly self-explanatory. Unlike the identify() function, playwith() works with lattice and ggplot2 graphs as well as base R graphs. Some options in the Theme menu only work properly with base graphics. Additionally, some features work with ggplot2 graphs (such as annotating) and some don’t (such as identifying points).
To learn more about the playwith package, visit the project website at http://code. google.com/p/playwith/.
Figure 16.12 The playwith window. The user can edit the graph using the mouse with this GTK+ GUI.











Bass 2
Tenor 2
Alto 2
Soprano 2 Soprano 1