Default plots in R are generally very basic and not very suitable for publication. However, one of the characteristics of R is that plots are highly customizable, so that you can basically create any plot you are able to think of as long as you are able to write the necessary code. In this lecture we are going to explore a few ways to make our plots look a bit better.
load("community.rda")
soil.data[1:5,]
## pH.KCl N.. P.mg.kg K.mg.kg Proovi.nimi
## 1 3.72 0.4246261 31.57133 79.04454 Vapramae
## 2 3.65 0.1364021 22.26459 42.73691 Illi
## 3 4.25 0.2500752 58.04788 60.71264 Vitipalu
## 4 4.40 2.3192906 63.00445 131.18302 Konguta
## 5 2.62 0.3698321 25.62339 131.56542 Vehendi
library(clipr)
write_clip(soil.data[1:5,]) ## you can paste now to excel or word!
#While the write_clip alternative should work for all systems, Windows users can also try this (which doesn't require loading any package):
# write.table(soil.data[1:5,], "clipboard", sep="\t")
#Now we can read from the memory (whatever it is in the computer clipboard):
read.table("clipboard")
o <- cor(soil.data[, -5])
o
write_clip(round(o, 3))
# Paste to your work now!
diff.ph <- dist(soil.data$pH.KCl)
diff.rich <- dist(rowSums(vas.plants > 0))
plot(diff.ph, diff.rich) # an ugly plot.
# The axis titles are not very informative, and the text is quite small
# Lots of overlapping points, it is hard to see where there is more density of points
# Units in y axis are written in vertical, but horizontal is a bit easier to read (and often required)
# Many times we dont want a full box around our plot
# It would be better to have a title
# We could include some summary statistic, for example the correlation
# Making it better step by step
plot(diff.ph,diff.rich,
xlab="Difference in soil pH",
ylab="Difference in plant richness",
cex.lab=1.2, # size of axis labels
pch=16, # dots
col=rgb(0,0,0,0.25), # grey semi-transparent color
axes=F) # no axes, we will add them later
axis(side = 1, #Axis 1. 1 means bottom; 2 is left, 3 is top, 4 is right
lwd = 1.5, #lwd controls axis thickness
cex.axis = 1.2, # cex.axis change font size
tcl = 0.5) # tcl determines size and orientation of tickmarks
axis(2, lwd = 1.5, cex.axis = 1.2, las = 1, tcl = 0.5) # same for y axis, las=1 give axis numbers horizontal
box(lwd = 2, bty = "l") # making axes lines
mtext(paste0(letters[1], ") Distance scatterplot"), # adding title (you could use LETTERS for capital letters)
side = 3, # same as with axis: 3 is "top"
cex = 1.5, # size of text
line = 0.5, #how much above the plot we want it
adj = 0) # left-justified (0.5 is centered, 1 is right)
r <- round(cor(diff.ph, diff.rich), 2)
legend("topright", #you can also use x and y coordinates, but this is more general
legend = paste("r =", r),
bty = "n", #we dont want a box around the legend
cex = 1.5)
## Find coordinates by clicking on the graph (number is how many)
locator(1)
## Find a point (same things as in inital plot). Esc for ending
identify(dist(soil.data$pH.KCl), dist(rowSums(vas.plants > 0)))
plot(diff.ph, diff.rich,
xlab = "Difference in soil pH",
ylab = "Difference in plant richness")
par(pty = "s") # square graph always
plot(diff.ph, diff.rich,
xlab = "Difference in soil pH",
ylab = "Difference in plant richness")
par(mar = c(5, 3, 1, 1))
# graph margins in lines form c(bottom, left, top, right).
# Default is c(5, 4, 4, 2) + 0.1
par(cex=1.5) # general size value for all things
plot(diff.ph,diff.rich,
xlab="Difference in soil pH",
ylab="Difference in plant richness")
par(pty="m") # not square, maximal plotting region
#You can reset graphic settings to default ones (and close the current plot) by executing dev.off()
dev.off()
## null device
## 1
plot(
NA,
xlim = c(0, 1),
ylim = c(0, 1),
axes = F,
xlab = "",
ylab = ""
) # An empty plot that we will fill
colors()[1:50] # color names
## [1] "white" "aliceblue" "antiquewhite" "antiquewhite1"
## [5] "antiquewhite2" "antiquewhite3" "antiquewhite4" "aquamarine"
## [9] "aquamarine1" "aquamarine2" "aquamarine3" "aquamarine4"
## [13] "azure" "azure1" "azure2" "azure3"
## [17] "azure4" "beige" "bisque" "bisque1"
## [21] "bisque2" "bisque3" "bisque4" "black"
## [25] "blanchedalmond" "blue" "blue1" "blue2"
## [29] "blue3" "blue4" "blueviolet" "brown"
## [33] "brown1" "brown2" "brown3" "brown4"
## [37] "burlywood" "burlywood1" "burlywood2" "burlywood3"
## [41] "burlywood4" "cadetblue" "cadetblue1" "cadetblue2"
## [45] "cadetblue3" "cadetblue4" "chartreuse" "chartreuse1"
## [49] "chartreuse2" "chartreuse3"
colUse <- "blueviolet"
points(0.1, 0.9, pch = 17, cex = 5, col = colUse)
# Transparency by using rgb (red, green, blue) and transparency measure alpha
colUse = rgb(0.5, 0.5, 0, alpha = 0.5)
points(c(0.1, 0.14), c(0.5, 0.5), pch = 18, cex = 5, col = colUse)
# Making a color name semi-transparent
index <- 1
for (i in seq(0, 1, length = 30)) {
col.t = as.vector(col2rgb(colors()[index])) / 255
col = rgb(col.t[1], col.t[2], col.t[3], alpha = i) # alpha is defining transparency (0....1)
points(i, i, pch = 16, cex = 5, col = col)
index <- index + 1
}
# Color palettes
plot(NA, xlim = c(1, 10), ylim = c(1, 11), axes = F, xlab = "", ylab = "")
topo.colors(10)
## [1] "#4C00FF" "#0019FF" "#0080FF" "#00E5FF" "#00FF4D" "#4DFF00" "#E6FF00"
## [8] "#FFFF00" "#FFDE59" "#FFE0B3"
points(1:10, rep(1, 10), col = topo.colors(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(2, 10), col = rainbow(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(3, 10), col = heat.colors(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(4, 10), col = terrain.colors(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(5, 10), col = cm.colors(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(6, 10), col = gray.colors(10)[1:10], pch = 16, cex = 5)
# mixing own colors
points(1:10, rep(7, 10), col = colorRampPalette(c("red", "yellow"))(10)[1:10],
pch = 16, cex = 5)
points(1:10, rep(8, 10), col = colorRampPalette(c("red", "yellow", "blue", "black"))(10)[1:10],
pch = 16, cex = 5)
library(viridis)
# visible in grey tones as well! Seen by color-blind people!
points(1:10, rep(9, 10), col = viridis(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(10, 10), col = magma(10)[1:10], pch = 16, cex = 5)
points(1:10, rep(11, 10), col = cividis(10)[1:10], pch = 16, cex = 5)
We have already explored par(mfrow = c(2, 2)) but
sometimes we need more complicated designs.
par(oma = c(3, 1, 3, 1)) # margins outside the combined graph (bottom, left, top, right)
# design matrix
m = matrix(c(1, 1, 1,
2, 2, 3),
byrow = T,
nrow = 2, ncol = 3)
m
## [,1] [,2] [,3]
## [1,] 1 1 1
## [2,] 2 2 3
layout(m)
layout.show(3) # just checking
par(cex = 1) # Select general size factor
par(mar = c(0, 0, 0, 0)) # margins for each of the individual graphs (bottom, left, top, right)
library(maps) # global maps
map("world", fill = T, col = cividis(12), border = F, ylim = c(-60, 85))
box()
mtext("a) Graph one", 3, adj = 0, line = 0.5)
par(mar=c(4,6,1,1)) # we give more space for axis titles
plot(diff.ph,diff.rich,
xlab="Difference in soil pH",
ylab="Difference in\nplant richness",
col=viridis(24)[diff.rich+1])
mtext("b) Graph two",3,adj=0,line=0.5)
hist(diff.rich,main="",xlab="Difference in\nplant richness", col=plasma(12))
mtext("c) Graph three",3,adj=0,line=0.5)
mtext("General title", 3, outer = T, line = 0, cex = 1.5)
mtext("General footnote", 1, outer = T, line = 0, cex = 0.8, adj = 1)
layout(1) # ending layout
# Overlapping graphs
par(mar = c(4, 4, 8, 2))
plot(diff.ph, diff.rich,
xlab = "Difference in soil pH",
ylab = "Difference in plant richness")
par(fig = c(0, 1, 0.8, 1), new = T) # in relative space of the previous window 0..1
par(mar = c(0, 4, 0.5, 2))
hist(diff.ph, axes = F, xlab = "", ylab = "", main = "", col = "grey")
par(fig = c(0, 1, 0, 1), new = T) # new graph over all
par(mar = c(0, 0, 0, 0)) # no edges
plot(c(0, 1), c(0, 1), ann = F, bty = 'n', type = 'n', xaxt = 'n', yaxt = 'n') # empty graph
text(x = 0.5, y = 0.5, "All this is an example", cex = 3.5, srt = 45,
col = rgb(1, 0, 0, 0.5), family = "serif")
pdf("my.graph.pdf", width = 12, height = 12) # size in inches
## Copy your three graphs here
dev.off() # closing (saving) pdf file
## png
## 2
png("my.graph.png", width = 6, height = 6, units = "in", res = 600) # resolution dpi
## Copy graphs on top of each other here
dev.off() # closing
## png
## 2