R Code for Chapter 12: Graphics I — The Basic Plots
#===============================================================================
# Chapter 12 - R Graphics I - Basic Plots
#===============================================================================
# Some data on democracy and corruption
#
# cGDP is per capita GDP. This data comes from the World Bank
#
# The CPI is a measure of the perception of corruption. 0 is highly corrupt
# and 10 is very low corruption. This widely used, if still controversial,
# measure comes from the NGO Transparency International
# (www.transparencyinternattional.org). This is the 2010 series.
#
# P4 is from the Polity IV dataset. It is the "polity" score which is a widely
# used measure of political regime type. It runs from -10, which is fully
# autocracy to +10 which is fully democratic. You can read more about this data
# at http://www.systemicpeace.org/polity/polity4.htm. The data is available at
# http://www.systemicpeace.org/inscr/inscr.htm. This is the 2009 data.
#
# As with much real world data, there are several missing cases for each series.
#
# Data setup and housekeeping
# Download and setup dataframe
myData = read.delim(file = "http://www.kktg.net/R/Chapter12Data.txt",
colClasses = c("character", "numeric", "numeric", "numeric"), header = T)
# Create a categorical version of the dem/polity data
myData$dem = # Dem if Polity >7
ifelse(myData$P4 > 7, 1, 0)
myData$corrupt = # Corrupt if CPI<4
ifelse(myData$CPI < 4, 1, 0)
myData$cGDPk = myData$cGDP/1000 # Per capita GDP in 1000s
# Remove all observations with missing data
myData = myData[!is.na(myData$CPI) & !is.na(myData$P4),]
# This is the code I used for creating the actual illustrations in the book. For
# this purpose I needed to create publication ready png files. Each of the plots
# is preceded by the code for opening and setting up an external png file with
# the png() function. The png file is created when the dev.off() command runs
# at the end of the plot.
#
# If you want to just create the plots in an R graphics window, or the RStudio
# plot window, you can just isolate and run the actual graphics code between
# the png() setup function and the dev.off() command.
#
# For saving all of the illustrations to external files, I created a
# subdirectory, "illustrations", that attaches to whatever the working
# directory is.
# Create a subdirectory of the current working directory to hold the new plots
dir.create("illustrations")
# 12.1 A simple scatterplot =============================================== 12.1
png(filename = "illustrations/fig-12-1-scatterplot.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
plot(myData$P4, myData$CPI) # What could be simpler than that?
dev.off() # Output png file
# 12.2 Pairs plots ======================================================== 12.2
png(filename = "illustrations/fig-12-2-pairs-plot.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
pairs(myData[,-1]) # Pairs plot w/all num vars in data frame
dev.off() # Output png file
png(filename = "illustrations/fig-12-3-pairs-plot2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
pairs(myData[,c(2:4)]) # Pairs plot w/o binary vars
dev.off() # Output png file
# 12.3 Line plots ========================================================= 12.3
meanCPI = tapply(myData$CPI, # Create a variable with the mean CPI
myData$P4, # at each level of P4
mean)
Polity = as.numeric( # Create variable with P4 levels
row.names(meanCPI)) # using the row names from myMeans
png(filename = "illustrations/fig-12-4-line-plot1.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
plot(Polity, meanCPI, type = "l") # Basic line plot
dev.off() # Output png file
png(filename = "illustrations/fig-12-5-line-plot2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
plot(Polity, meanCPI, type = "o") # Line plot with points overlayed
dev.off() # Output png file
png(filename = "illustrations/fig-12-6-line-plot3.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
plot(Polity, meanCPI, type = "b") # Plot with lines between points
dev.off() # Output png file
# 12.4 Boxplots =========================================================== 12.4
png(filename = "illustrations/fig-12-7-boxplot1.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .25, .25)) # Change margins for png graphs
boxplot(myData[,3:4]) # Boxplot (leaving out binary data)
dev.off() # Output png file
png(filename = "illustrations/fig-12-8-boxplot2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .25, .25)) # Change margins for png graphs
boxplot(myData$CPI ~ myData$P4) # Boxplot of CPI by Polity score
dev.off() # Output png file
png(filename = "illustrations/fig-12-9-boxplot3.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .25, .25)) # Change margins for png graphs
boxplot(myData$CPI ~ # Boxplot of CPI by
cut(myData$P4, # Polity score cut into 4
quantile(myData$P4), # quartiles w/ equal num of obs
include.lowest = T)) # Include lowest value in split
dev.off() # Output png file
# 12.5 Histograms and bar charts ========================================== 12.5
png(filename = "illustrations/fig-12-10-histogram1.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
hist(myData$P4, main = NA) # Histogram of polity data
dev.off() # Output png file
png(filename = "illustrations/fig-12-11-density plot.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Change margins for png graphs
plot(density(myData$P4), main = NA) # Kernel density plot of polity data
dev.off() # Output png file
# barplots ---------------------------------------------------------------------
P4breaks = cut(myData$P4, breaks = 5) # Create factor with P4 in 5 bins
newP4 = tapply(myData$P4, # Create vector of bar heights
P4breaks, # based on the bins we created
length) # count number of obs in each bin
png(filename = "illustrations/fig-12-12-barplot1.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .25, .25)) # Change margins for png graphs
barplot(newP4) # Create a barplot
dev.off() # Output png file
CPIbreaks = cut(myData$CPI,
breaks = 5) # Create factor with P4 in 5 bins
newCPI = tapply(myData$CPI, # Create vector of bar heights
CPIbreaks, # based on the bins we created
length) # count number of obs in each bin
png(filename = "illustrations/fig-12-13-barplot2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, 1, .25, .25)) # Change margins for png graphs
barplot(newCPI, # Create a barplot
horiz = T, # Rotate to horizontal
ylab = "CPI Corruption Score") # Add y-axis label
dev.off() # Output png file
# 12.6 Dot plots ========================================================== 12.6
# Create a basic dotchart of the corruption data
CPIcounts = tapply(myData$CPI, # Aggregate CPI data
as.factor(round(myData$CPI)), # in bins based on integer values
length) # count number of obs in each bin
png(filename = "illustrations/fig-12-14-dotplot.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4)) # Height at 4 inches
par(mai = c(.5, .5, .25, .25)) # Change margins for png graphs
dotchart(CPIcounts) # Produce basic dot chart
dev.off() # Output png file
# 12.7 Pie charts ========================================================= 12.7
CPIbreaks = cut(myData$CPI, # Create factor dividing CPI data
c(0, 3.3, 6.6, 10)) # into 3 bins
CPIcounts = tapply(myData$CPI, # Create vector of bar heights
CPIbreaks, # based on the bins we created
length) # counting num of obs in each bin
names(CPIcounts) = paste( # Create labels by pasting
c("High", # low/medium/high text
"Medium",
"Low"),
names(CPIcounts), # to existing bin labels
sep = "--") # separated by "--"
png(filename = "illustrations/fig-12-15-piechart-BW.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4)) # Height at 4 inches
par(mai = c(.25, .25, .75, .25)) # Change margins for pie chart
pie(CPIcounts, # Create a pie chart w/CPI shares
col = c("white", "gray", "darkgray"),# Set colors
main = "Corruption") # Add a title
dev.off() # Output png file
# 12.8 Mosaic Plots ======================================================= 12.8
# There are two steps here. First we have to transform the data into a
# contingency table. This is an array that shows the frequency of observations
# at each combination of the variables of interest.
# A simple 2x2 table
myTable = table( # Create a contingency table
myData$dem, # with x = dem/not dem
myData$corrupt) # and y = corrupt/not corrupt
myTable # Display contingency table
png(filename = "illustrations/fig-12-16-mosaicplot1.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .5, .25)) # Change margins for png graphs
mosaicplot(myTable, # Create mosaic plot for myTable
main = "Democracy & Corruption", # Set main title
xlab = "Dem", # Set x axis label
ylab = "Corrupt") # Set y axis label
dev.off() # Output png file
# A little more complex 10x4 table
myTable2 = table( # Create a contingency table
cut(myData$P4, # with x = polity score
quantile(myData$P4)), # cut into quantiles (i.e. same num
# of observations in each group)
round(myData$CPI, 0)) # and y = rounded CPI score.
myTable2 # Display contingency table
png(filename = "illustrations/fig-12-17-mosaicplot2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.5, .5, .3, .25)) # Change margins for png graphs
mosaicplot(myTable2, # Create mosaic plot for myTable2
main = NA, # Turn off default plot title
xlab = "PolityIV", # Set x axis label
ylab = "CPI 0=most corrupt") # Set y axis label
dev.off() # Output png file
R Code for Chapter 13: Graphics II -- The Boring Stuff
#===============================================================================
# Chapter 13 -- R Graphics II - Customization - The boring stuff
#===============================================================================
# This chapter provides the sometimes boring background foundation for
# customizing R graphic output.
#
# 13.1 The graphics device ================================================ 13.1
# 13.1a Screen-based devices ============================================= 13.1a
#Simple plot examples
myX = seq(1:10) # Some x values
myY = c(1, 3, 2, 2, 4, 8, 7, 1, 8, 10) # Some y values
# An onscreen window
windows() # Open graphics window
plot(myX, myY) # plot myX and myY
bringToTop() # Bring graphics window to front
dev.off() # Close graphics window
# 13.1b Raster/bitmap devices ============================================ 13.1b
# A png file
png(filename = "myPlot300.png", # Set filename for png output
bg = "light gray", # Set background to light gray
units = "in", # Set units to inches
res = 300, # Set resolution to 300dpi
height = 4, # Set height to 4 inches
width = 6, # Set width to 6 inches
pointsize = 12) # Set default pointsize to 12
plot(myX, myY) # plot myX and myY
dev.off() # Close graphics device
# 13.1c Vector-based devices ============================================= 13.1c
# Postscript printing
postscript(file = "fig3.eps", # create EPS file
horizontal = FALSE, # don't rotate to landscape
bg = "white", # white background
onefile = FALSE, # One picture per file,
paper = "special", # paper size =pic size
width = 4.5, height = 3, # set image size
pointsize = 10) # set font size
plot(myX, myY) # plot myX and myY
dev.off() # Close graphics device
# PDF output - multiple files
pdf(file = "MyGraphs%02d.pdf", # Set up PDF files for output
onefile = FALSE, # Use one file per plot
family = "Palatino", # Set default font to Palatino
paper = "letter") # Set paper size
plot(x = c(1:10), y = log(c(1:10))) # Create a plot
plot(x = c(1:100), y = log(c(1:100))) # Create another plot
dev.off() # Output and close device
# PDF fonts - single file
# This code prints out the set of built-in PDF fonts
pdf(file = "illustrations/fig-13-1-PDF-fonts.pdf",
family = "Palatino", # Set default font to Palatino
paper = "letter") # Set paper size
plot.new() # Start new plot
text(x = .5, y = .8, # Add text in the middle of the plot
"AvantGarde", # Text to print
family = "AvantGarde", # Use AvantGarde font
cex = 2) # Set fontsize to 2
text(x = .5, y = .7, # Add text in the middle of the plot
"Bookman", # Text to print
family = "Bookman", # Use Bookman font
cex = 2) # Set fontsize to 2
text(x = .5, y = .6, # Add text in the middle of the plot
"Courier", # Text to print
family = "Courier", # Use Courier font
cex = 2) # Set fontsize to 2
text(x = .5, y = .5, # Add text in the middle of the plot
"Helvetica", # Text to print
family = "Helvetica", # Use Helvetica font
cex = 2) # Set fontsize to 2
text(x = .5, y = .4, # Add text in the middle of the plot
"Helvetica-Narrow", # Text to print
family = "Helvetica-Narrow", # Use Helvetica-Narrow font
cex = 2) # Set fontsize to 2
text(x = .5, y = .3, # Add text in the middle of the plot
"NewCenturySchoolbook", # Text to print
family = "NewCenturySchoolbook", # Use NewCenturySchoolbook font
cex = 2) # Set fontsize to 2
text(x = .5, y = .2, # Add text in the middle of the plot
"Palatino", # Text to print
family = "Palatino", # Use Palatino font
cex = 2) # Set fontsize to 2
text(x = .5, y = .1, # Add text in the middle of the plot
"Times", # Text to print
family = "Times", # Use Times font
cex = 2) # Set fontsize to 2
dev.off() # Output and close device
# 13.3 The plot layout ==================================================== 13.3
# The plot area and margins
myX = seq(1:10) # Some x values
myY = c(1, 3, 2, 2, 4, 8, 7, 1, 8, 10) # Some y values
# Plot, region, and device areas
png(filename = "illustrations/fig-13-2-plot regions-BW.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(omi = c(.5, .5, .5, .5), # Set outer margin at .5 inches
mai = c(.8, .8, .8, .8), # Set inner margin btwn figure & plot
fin = c(4.5, 2.5)) # Set the plot at 4.5 x 2.5 inches
plot(myX, myY) # Start new plot in device window
box("outer", # Create a box on outer margin
col = "darkgray", lwd = 6) # with a thick dark gray line
box("inner", col = "black", lty = 2) # Dashed line for figure region (inner)
box("figure", col = "black", lwd = 4) # Black line for figure region (figure)
box("plot", col = "black") # Thin black line for plot region (plot)
mtext('Device Region: omi = .5"', # Put text in margin of device region
line = 1, outer = TRUE) # indicating the outer margin
mtext('Figure Region: mai = .8"', # Put text in the figure margin
line = 2) # on the 2nd line
text(x = 5, y = 5, "Plot Region") # Place text in center of plot region
dev.off() # Output png file
# 13.4 Graphic coordinates ================================================ 13.4
# Regular x,y coordinates
myX = c(0:20) # Create x var that runs 0 to 20
myY = myX * .5 # Create y var that runs 0 to 10
png(filename = "illustrations/fig-13-3-placed objects.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Plot margins - no title
plot(myX, myY, type = "n") # Plot x & y, but suppress points
text(x = 15, y = 6, "Hello World!") # Add text at x = 15 and y = 6
polygon(x = c(7, 15, 15, 7), # Add a rectangle at x coords
y = c(1, 1, 3, 3)) # and y coords
points(x = c(5, 18), y = c(6, 1), # Add a dashed line between points
type = "l", lty = 2) # at given x and y coordinates.
xtext = "x coordinates 0-20" # Some text for adding to plot
ytext = "y coordinates 0-10" # Some more text for plot
arrows(x0 = 6, y0 = 8, x1 = 0, # Add a horizontal arrow
lwd = 2) # Set line width to 2
text(x = 10, y = 8, xtext) # Add coordinates text
arrows(x0 = 14, y0 = 8, x1 = 20, # Add another horizontal arrow
lwd = 2) # Set line width to 2
arrows(x0 = 4, y0 = 2, y1 = 0, # Add a vertical arrow
lwd = 2) # Set line width to 2
text(x = 4, y = 5, ytext, srt = 90) # Add rotated y coordinates text
arrows(x0 = 4, y0 = 8, y1 = 10, # Add another vertical arrow
lwd = 2) # Set line width to 2
dev.off() # Output png
# Proportional coordinates
par()$usr # Show usr coords from previous plot
png(filename = "illustrations/fig-13-4-usr coords.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Plot margins - no title
plot(myX, myY, type = "n") # Plot x & y, but suppress points
par(usr = c(0, 1, 0, 1)) # Set coordinates based on % of plot area
text(.5, .5, "Hello World!") # Place text in middle of plot
polygon(x = c(.25, .75, .75, .25), # Place box at 25% from edges
y = c(.25, .25, .75, .75),
lwd = 4) # Set the line width at 4
xtext2 = "x coordinates 0-1" # Some text for adding to plot
ytext2 = "y coordinates 0-1" # Some more text for plot
arrows(x0 = .35, y0 = .8, x1 = 0, # Add a horizontal arrow
lwd = 2) # Set line width to 2
text(x = .5, y = .8, xtext2) # Add coordinates text
arrows(x0 = .65, y0 = .8, x1 = 1, # Add another horizontal arrow
lwd = 2) # Set line width to 2
arrows(x0 = .2, y0 = .2, y1 = 0, # Add a vertical arrow
lwd = 2) # Set line width to 2
text(x = .2, y = .5, ytext2, srt = 90) # Add rotated y coordinates text
arrows(x0 = .2, y0 = .8, y1 = 1, # Add another vertical arrow
lwd = 2) # Set line width to 2
dev.off() # Output png file
# 13.5 Overlaying plots =================================================== 13.5
myX1 = c(1, 3, 4, 7, 9, 12, 15)
myY1 = c(15, 17, 14, 19, 24, 23, 24)
myY2 = c(8, 6, 3, 5, 4, 2, 1)
png(filename = "illustrations/fig-13-5-overlay-BW.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(1, 1, .25, .25)) # Plot margins - no title
plot(myX1, myY1, # Plot myX1 and myY1
ylim = c(0, 25), # Set Y axis range for both plots
type = "l", # Line plot
ylab = "myY1 & myY2") # Set Y axis label
par(new = T) # Overlay the next plot
plot(myX1, myY2, # Plot myX1 and myY2
type = "l", # Line plot
lty = 2, # Set line type to dashes
axes = FALSE, # Turn off the axes
xlab = NA, ylab = NA) # Turn off the labels
dev.off() # Output png file
# 13.6 Multiple plots ===================================================== 13.6
png(filename = "illustrations/fig-13-6-mfrow.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
# mfrow approach
par(mfrow = c(1, 2)) # Set mfrow for 1 row 2 columns
plot.new() # New plot
box("plot") # Draw box around plot area
box("fig") # Figure area box
text(x = .5, y = .5, # Put text in middle of plot
labels = "This is plot 1", # identifying plot 1
cex = 1.5) # Set font size
plot.new() # New plot
box("plot") # Draw box around plot area
box("fig") # Figure area box
text(x = .5, y = .5, # Put text in middle of plot
labels = "This is plot 2", # identifying plot 2
cex = 1.5) # Set font size
dev.off() # Output png file
# The layout Function ==========================================================
# Some simple examples
layout(matrix(c(1:4), ncol = 2)) # A simple 2x2 grid using layout
layout.show(4) # Show the resulting grid
png(filename = "illustrations/fig-13-7-layout method.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
layout( # Setup a multiplot layout
matrix(c(1:15), # Create a matrix of 15 cells
ncol = 3, # in 3 columns (5 rows of 3 cells)
byrow = T), # Order the cells by row
heights = c(2, 2, .5, .5, 1)) # Set row heights
layout.show(15) # Show the layout grid
dev.off() # Output png file
# A more complex layout example ------------------------------------------------
png(filename = "illustrations/fig-13-8-layout2.png",
units = "in", # Set measurements in inches
res = 1200, # Set resolution at 1200dpi
width = 6, # Width at 6 inches
height = 4) # Height at 4 inches
par(mai = c(.6, .6, .5, .1)) # Set margins around plots
layout( # Set up a multiplot layout
matrix(c(1, 1, 4, 2, 3, 4), # Create a matrix of 6 cells
ncol = 3, # in 3 columns (3 cells per row)
byrow = T), # Order the cells by row
heights = c(.6, .4), # Set row heights
widths = c(.34, .33, .33)) # Set column widths
layout.show(4) # Preview the layout grid
myX = c(0:10) # Some data for plots
myY = log(myX + 1)
myZ = c(30, 60)
# Some plots to fill in layout
plot(myX, myY, type = "b", main = "Plot 1")
par(mai = c(.6, .6, .5, .1)) # Change plot margins
plot(myX, myX^2, ylim = c(0, 100), type = "o", main = "Plot 2")
par(mai = c(.6, .35, .5, .1)) # Change plot margins
barplot(myZ, ylim = c(0, 100), main = "Plot 3")
par(mai = c(.6, .2, .5, .1)) # Change plot margins
dotchart(10 - myX, main = "Plot 4")
dev.off() # Output the png file