Chapter 4.1.1 Exercises

base-f
In [1]:
require(grDevices) # for colours
tN <- table(Ni <- stats::rpois(100, lambda = 5)); tN
r <- barplot(tN, col = rainbow(20))
 1  2  3  4  5  6  7  8  9 10 14 
 4  8 13 16 17 17  8  9  4  3  1 
In [1]:
require(graphics)

# A Color Wheel

pie(rep(1, 12), col = rainbow(12))
In [2]:
#------ Some palettes ------------

demo.pal <-
function(n, border = if (n < 32) "light gray" else NA,
main = paste("color palettes; n=", n),
ch.col = c("rainbow(n, start=.7, end=.1)", "heat.colors(n)",
"terrain.colors(n)", "topo.colors(n)",
"cm.colors(n)"))
{
nt <- length(ch.col)
i <- 1:n; j <- n / nt; d <- j/6; dy <- 2*d
plot(i, i+d, type = "n", yaxt = "n", ylab = "", main = main)
for (k in 1:nt) {
rect(i-.5, (k-1)*j+ dy, i+.4, k*j,
col = eval(parse(text = ch.col[k])), border = border)
text(2*j, k * j + dy/4, ch.col[k])
}
}
n <- if(.Device == "postscript") 64 else 16
    
# Since for screen, larger n may give color allocation problem

demo.pal(n)
In [1]:
# Let’s create a pirateplot of the ChickWeight data. I’ll set the dependent variable to weight, and the independent variable to Time using the argument formula = weight ~ Time:

yarrr::pirateplot(formula = weight ~ Time, # dv is weight, iv is Diet
                   data = ChickWeight,
                   main = "Pirateplot of chicken weights",
                   xlab = "Diet",
                   ylab = "Weight")
In [7]:
# There are many different pirateplot themes, these themes dictate the overall look of the plot. To specify a theme, just use the theme = x argument, where x is the theme number:

yarrr::pirateplot(formula = weight ~ Diet, # dv is weight, iv is Diet
                   data = ChickWeight,
                   theme = 1,
                   main = "Pirateplot of chicken weights",
                   xlab = "Diet",
                   ylab = "Weight")
In [10]:
library(yarrr)
# For example, here is a pirateplot height data from the pirates dataframe using theme = 3. Here, I’ll plot pirates’ heights as a function of their sex and whether or not they wear a headband. I’ll also make the plot all grayscale by using the pal = "gray" argument:

yarrr::pirateplot(formula = height ~ sex + headband,    # DV = height, IV1 = sex, IV2 = headband
                  data = pirates,           
                  theme = 3,
                  main = "Pirate Heights",
                  pal = "gray")
In [11]:
# For example, I could create the following pirateplots using theme = 0 and specifying elements explicitly:

pirateplot(formula = weight ~ Time,
           data = ChickWeight,
           theme = 0,
           main = "Fully customized pirateplot",
           pal = "southpark", # southpark color palette
           bean.f.o = .6, # Bean fill
           point.o = .3, # Points
           inf.f.o = .7, # Inference fill
           inf.b.o = .8, # Inference border
           avg.line.o = 1, # Average line
           bar.f.o = .5, # Bar
           inf.f.col = "white", # Inf fill col
           inf.b.col = "black", # Inf border col
           avg.line.col = "black", # avg line col
           bar.f.col = gray(.8), # bar filling color
           point.pch = 21,
           point.bg = "white",
           point.col = "black",
           point.cex = .7)
In [12]:
# If you don’t want to start from scratch, you can also start with a theme, and then make selective adjustments:

pirateplot(formula = weight ~ Time,
           data = ChickWeight,
           main = "Adjusting an existing theme",
           theme = 2,  # Start with theme 2
           inf.f.o = 0, # Turn off inf fill
           inf.b.o = 0, # Turn off inf border
           point.o = .2,   # Turn up points
           bar.f.o = .5, # Turn up bars
           bean.f.o = .4, # Light bean filling
           bean.b.o = .2, # Light bean border
           avg.line.o = 0, # Turn off average line
           point.col = "black") # Black points
In [13]:
# Just to drive the point home, as a barplot is a special case of a pirateplot, you can even reduce a pirateplot into a horrible barplot:

# Reducing a pirateplot to a (at least colorful) barplot

pirateplot(formula = weight ~ Diet,
           data = ChickWeight,
           main = "Reducing a pirateplot to a (horrible) barplot",
           theme = 0,                                    # Start from scratch
           pal = "black",
           inf.disp = "line",                            # Use a line for inference
           inf.f.o = 1,                                  # Turn up inference opacity
           inf.f.col = "black",                          # Set inference line color
           bar.f.o = .3)
In [14]:
# Additional pirateplot customizations

pirateplot(formula = weight ~ Diet, 
           data = ChickWeight,
           main = "Adding quantile lines and background colors",
           theme = 2,
           cap.beans = TRUE,
           back.col = transparent("blue", .95), # Add light blue background
           gl.col = "gray", # Gray gridlines
           gl.lwd = c(.75, 0),
           inf.f.o = .6, # Turn up inf filling
           inf.disp = "bean", # Wrap inference around bean
           bean.b.o = .4, # Turn down bean borders
           quant = c(.1, .9), # 10th and 90th quantiles
           quant.col = "black") # Black quantile lines
In [15]:
# If you include the plot = FALSE argument to a pirateplot, the function will return some values associated with each bean in the plot. In the next chunk, I’ll create a pirateplot

pirateplot(formula = tattoos ~ sex + headband,
           data = pirates)
In [16]:
# Save data from the pirateplot to an object

tattoos.pp <- pirateplot(formula = tattoos ~ sex + headband,
                         data = pirates,
                         plot = FALSE)
In [17]:
# Now I can access the summary and inferential statistics from the plot in the tattoos.pp object. The most interesting element is $summary which shows summary statistics for each bean (aka, group):
# Show me statistics from groups in the pirateplot

tattoos.pp

# Once you’ve created a plot with a high-level plotting function, you can add additional elements with low-level functions. For example, you can add data points with points(), reference lines with abline(), text with text(), and legends with legend().
$summary
sexheadbandbean.numnavginf.lbinf.ub
female no 1 55 4.9636364.309725 5.502491
male no 2 47 4.2553193.363596 5.034151
other no 3 11 5.2727272.055791 7.148908
female yes 4 409 10.0317859.750876 10.301091
male yes 5 443 9.9841999.673966 10.241748
other yes 6 35 10.6285719.887777 11.383459
$avg.line.fun
'mean'
$inf.method
'hdi'
$inf.p
0.95
In [25]:
library(ggplot2)
ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy)) + 
  facet_grid(drv ~ cyl)
In [1]:
require(stats) # for rnorm
plot(-4:4, -4:4, type = "n") # setting up coord. system
points(rnorm(200), rnorm(200), col = "red")
points(rnorm(100)/2, rnorm(100)/2, col = "blue", cex = 1.5)
In [2]:
op <- par(bg = "light blue")
x <- seq(0, 2*pi, len = 51)

## something "between type='b' and type='o'":

plot(x, sin(x), type = "o", pch = 21, bg = par("bg"), col = "blue", cex = .6,
main = 'plot(..., type="o", pch=21, bg=par("bg"))')
par(op)
In [3]:
## Not run:
## The figure was produced by calls like

png("pch.png", height = 0.7, width = 7, res = 100, units = "in")
par(mar = rep(0,4))
plot(c(-1, 26), 0:1, type = "n", axes = FALSE)
text(0:25, 0.6, 0:25, cex = 0.5)
points(0:25, rep(0.3, 26), pch = 0:25, bg = "grey")

## End(Not run)
In [4]:
##-------- Showing all the extra & some char graphics symbols ---------

pchShow <-
function(extras = c("*",".", "o","O","0","+","-","|","%","#"),
cex = 3, ## good for both .Device=="postscript" and "x11"
col = "red3", bg = "gold", coltext = "brown", cextext = 1.2,
main = paste("plot symbols : points (... pch = *, cex =",
cex,")"))
{
nex <- length(extras)
np <- 26 + nex
ipch <- 0:(np-1)
k <- floor(sqrt(np))
dd <- c(-1,1)/2
rx <- dd + range(ix <- ipch %/% k)
ry <- dd + range(iy <- 3 + (k-1)- ipch %% k)
pch <- as.list(ipch) # list with integers & strings
if(nex > 0) pch[26+ 1:nex] <- as.list(extras)
plot(rx, ry, type = "n", axes = FALSE, xlab = "", ylab = "", main = main)
abline(v = ix, h = iy, col = "lightgray", lty = "dotted")
for(i in 1:np) {
pc <- pch[[i]]
## 'col' symbols with a 'bg'-colored interior (where available) :
points(ix[i], iy[i], pch = pc, col = col, bg = bg, cex = cex)
if(cextext > 0)
text(ix[i] - 0.3, iy[i], pc, col = coltext, cex = cextext)
}
}

pchShow()
pchShow(c("o","O","0"), cex = 2.5)
pchShow(NULL, cex = 4, cextext = 0, main = NULL)
In [5]:
## ------------ test code for various pch specifications -------------
# Try this in various font families (including Hershey)
# and locales. Use sign = -1 asserts we want Latin-1.
# Standard cases in a MBCS locale will not plot the top half.
TestChars <- function(sign = 1, font = 1, ...)
{
MB <- l10n_info()$MBCS
r <- if(font == 5) { sign <- 1; c(32:126, 160:254)
} else if(MB) 32:126 else 32:255
if (sign == -1) r <- c(32:126, 160:255)
par(pty = "s")
plot(c(-1,16), c(-1,16), type = "n", xlab = "", ylab = "",
xaxs = "i", yaxs = "i",
main = sprintf("sign = %d, font = %d", sign, font))
grid(17, 17, lty = 1) ; mtext(paste("MBCS:", MB))
for(i in r) try(points(i%%16, i%/%16, pch = sign*i, font = font,...))
}
TestChars()
try(TestChars(sign = -1))
TestChars(font = 5) # Euro might be at 160 (0+10*16).
# macOS has apple at 240 (0+15*16).
try(TestChars(-1, font = 2)) # bold
In [4]:
library(yarrr)

# Here is a basic scatterplot with standard (non-transparent) colors:
# Plot with Standard Colors

plot(x = pirates$height, 
     y = pirates$weight, 
     col = "blue", 
     pch = 16, 
     main = "col ='blue'")
In [5]:
# Now here’s the same plot using the transparent() function in the yarrr package:
# Plot with transparent colors using the transparent() function in the yarrr package

plot(x = pirates$height, 
     y = pirates$weight, 
     col = yarrr::transparent("blue", trans.val = .9), 
     pch = 16, 
     main = "col = yarrr::transparent('blue', .9)")

# Later we’ll cover more advanced ways to come up with colors using color palettes (using the RColorBrewer package or the piratepal() function in the yarrr package) and functions that generate shades of colors based on numeric data (like the colorRamp2() function in the circlize package).
In [5]:
# Now here’s the same plot using the transparent() function in the yarrr package:
# Plot with transparent colors using the transparent() function in the yarrr package

plot(x = pirates$height, 
     y = pirates$weight, 
     col = yarrr::transparent("blue", trans.val = .9), 
     pch = 16, 
     main = "col = yarrr::transparent('blue', .9)")

# Later we’ll cover more advanced ways to come up with colors using color palettes (using the RColorBrewer package or the piratepal() function in the yarrr package) and functions that generate shades of colors based on numeric data (like the colorRamp2() function in the circlize package).
In [5]:
hist(x = ChickWeight$weight,
     main = "Chicken Weights",
     xlab = "Weight",
     xlim = c(0, 500))
In [9]:
# We can get more fancy by adding additional arguments like breaks = 20 to force there to be 20 bins, and col = "papayawhip" and bg = "hotpink" to make it a bit more colorful:

hist(x = ChickWeight$weight,
     main = "Fancy Chicken Weight Histogram",
     xlab = "Weight",
     ylab = "Frequency",
     breaks = 20, # 20 Bins
     xlim = c(0, 500),
     col = "papayawhip", # Filling Color
     border = "hotpink") # Border Color
In [7]:
# If you want to plot two histograms on the same plot, for example, to show the distributions of two different groups, you can use the argument to the second plot.

hist(x = ChickWeight$weight[ChickWeight$Diet == 1],
     main = "Two Histograms in one",
     xlab = "Weight",
     ylab = "Frequency",
     breaks = 20,
     xlim = c(0, 500),
     col = gray(0, .5))

hist(x = ChickWeight$weight[ChickWeight$Diet == 2],
     breaks = 30,
     add = TRUE, # Add plot to previous one!
     col = gray(1, .8))
In [10]:
# A barplot typically shows summary statistics for different groups. The primary argument to a barplot is height: a vector of numeric values which will generate the height of each bar. To add names below the bars, use the names.arg argument. For additional arguments specific to barplot(), look at the help menu with ?barplot:

barplot(height = 1:5,  # A vector of heights
        names.arg = c("G1", "G2", "G3", "G4", "G5"), # A vector of names
        main = "Example Barplot", 
        xlab = "Group", 
        ylab = "Height")
In [16]:
# Of course, you should plot more interesting data than just a vector of integers with a barplot. In the plot below, I create a barplot with the average weight of chickens for each week:
# Calculate mean weights for each time period

diet.weights <- aggregate(weight ~ Time, 
                      data = ChickWeight,
                      FUN = mean)

# Create barplot

barplot(height = diet.weights$weight,
        names.arg = diet.weights$Time,
        xlab = "Week",
        ylab = "Average Weight",
        main = "Average Chicken Weights by Time",
        col = "mistyrose")
In [17]:
# Clustered barplot
# I can represent these data in a matrix as follows. In order for the final barplot to include the condition names, I’ll add row and column names to the matrix with colnames() and rownames().

swim.data <- cbind(c(2.1, 3), # Naked Times
                   c(1.5, 3)) # Clothed Times

colnames(swim.data) <- c("Naked", "Clothed")
rownames(swim.data) <- c("No Shark", "Shark")

# Print result

swim.data
NakedClothed
No Shark2.11.5
Shark3.03.0
In [20]:
library(yarrr)

# Now, when I enter this matrix as the height = swim.data argument to barplot(), I’ll get multiple bars.

barplot(height = swim.data,
        beside = TRUE,                        # Put the bars next to each other
        legend.text = TRUE,                   # Add a legend
        col = c(transparent("green", .2), 
                transparent("red", .2)),
        main = "Swimming Speed Experiment",
        ylab = "Speed (in meters / second)",
        xlab = "Clothing Condition",
        ylim = c(0, 4))
In [1]:
require(stats) # both 'density' and its default method
with(faithful, {
plot(density(eruptions, bw = 0.15))
rug(eruptions)
rug(jitter(eruptions, amount = 0.01), side = 3, col = "light blue")
})
In [2]:
round(jitter(c(rep(1, 3), rep(1.2, 4), rep(3, 3))), 3)

# These two 'fail' with S-plus 3.x:

jitter(rep(0, 7))
jitter(rep(10000, 5))
  1. 1.019
  2. 0.975
  3. 1.019
  4. 1.231
  5. 1.173
  6. 1.212
  7. 1.161
  8. 3.018
  9. 3.028
  10. 2.968
  1. 0.0199426069203764
  2. -0.00856208842247725
  3. 0.00801153072156012
  4. 0.0100945311039686
  5. 0.019429789390415
  6. 0.00185623729601503
  7. -0.0133928899094462
  1. 10032.2192846797
  2. 10191.5607441217
  3. 9905.05240466446
  4. 10110.4315572418
  5. 9972.90893644094
In [7]:
library(yarrr)

# Diagram of some examples

plot(1, ylim = c(0, 1), xlim = c(0, 12), bty = "n",
xaxt = "n", yaxt = "n", ylab = "", xlab = "", type = "na")

text(6, .9, "transparent('red', trans.val = x)")
points(x = 1:11, y = rep(.8, 11), pch = 16,
col = transparent("red", seq(0, 1, .1)), cex = 2)
text(x = 1:11, y = rep(.85, 11), seq(0, 1, .1))

text(6, .7, "transparent('red', trans.val = x)")
points(x = 1:11, y = rep(.6, 11), pch = 16,
col = transparent("blue", seq(0, 1, .1)), cex = 2)
text(x = 1:11, y = rep(.65, 11), seq(0, 1, .1))

text(6, .5, "transparent('forestgreen', trans.val = x)")
points(x = 1:11, y = rep(.4, 11), pch = 16,
col = transparent("forestgreen", seq(0, 1, .1)), cex = 2)
text(x = 1:11, y = rep(.45, 11), seq(0, 1, .1))

text(6, .3, "transparent('orchid1', trans.val = x)")
points(x = 1:11, y = rep(.2, 11), pch = 16,
col = transparent("orchid1", seq(0, 1, .1)), cex = 2)
text(x = 1:11, y = rep(.25, 11), seq(0, 1, .1))
Warning message in plot.xy(xy, type, ...):
“plot type 'na' will be truncated to first character”Warning message in final.col[i] <- rgb(orig.col[1, i], orig.col[2, i], orig.col[3, :
“number of items to replace is not a multiple of replacement length”Warning message in final.col[i] <- rgb(orig.col[1, i], orig.col[2, i], orig.col[3, :
“number of items to replace is not a multiple of replacement length”Warning message in final.col[i] <- rgb(orig.col[1, i], orig.col[2, i], orig.col[3, :
“number of items to replace is not a multiple of replacement length”Warning message in final.col[i] <- rgb(orig.col[1, i], orig.col[2, i], orig.col[3, :
“number of items to replace is not a multiple of replacement length”
In [8]:
# Scatterplot with transparent colors

a.x <- rnorm(100, mean = 0, sd = 1)
a.y <- a.x + rnorm(100, mean = 0, sd = 1)

par(mfrow = c(3, 3))

for(trans.val.i in seq(0, .1, length.out = 9)) {

plot(a.x, a.y, pch = 16, col = transparent("blue", trans.val.i), cex = 1.5,
xlim = c(-5, 5), ylim = c(-5, 5), xlab = "x", ylab = "y",
main = paste("trans.val = ", round(trans.val.i, 2), sep = ""))

}