R可视化20|最基础元素详解(Modern Statistical Graphics)
"pythonic生物人"的第119篇分享
之前介绍的ggplot2、其扩展ggstatsplot、gganatogram等都属于R 的作图函数中的「高层函数(high-level)的高度封装产物」。 本文详解R 的作图函数中的的「低层函数(low-level)即颜色、点、线(直线、曲线、线段甚至箭头)、矩形、任意多边形、文本以及图例等」。 参考书籍:「《「现代统计图形」》-」谢益辉,感觉作者是个很有意思的人,「RStudio公司」软件工程师,美国爱荷华州立大学统计系博士,2006年创建中国著名的统计学在线社区——「统计之都」(现在依旧很活跃)。 「PS,本来不想再写R基础绘图的,但是看到这本书后,感觉很有水准,So I am back」。
「本文目录」
1、颜色
之前在Python及ggplot2可视化时,写了多篇配色文章,可戳:
Python可视化|matplotlib05-内置单颜色(一)
Python可视化|matplotlib06-外部单颜色(二)
Python可视化|matplotlib07-自带颜色条Colormap(三)
Python可视化|08-Palettable库中颜色条Colormap(四)
Python|R可视化|09-提取图片颜色绘图(五-颜色使用完结篇)
Python可视化18|seborn-seaborn调色盘(六)
食色性也!颜色小抄免费大放送(一)
食色性也-颜色小抄免费大放送(二)
R可视化07|ggplot2图层-标度图层(scale layer)-颜色盘篇
R 中颜色的设置主要需要依靠 「grDevices」 包(default),包中关于颜色的函数大致分为三类:固定颜色选择函数、颜色生成和转换函数、特定颜色主题调色板。
固定颜色选择函数:colors/colours()、sample()、palette()
colors/colours()提取单个颜色
例如ivory'
(象牙色)、'lavender'
(浅紫色),共计657种。
> length(colors())
[1] 657
绘制速查表
pdf("colors-bar.pdf", height = 120)
par(mar = c(0, 10, 3, 0) + 0.1, yaxs = "i")
barplot(rep(1, length(colors())),
col = rev(colors()), names.arg = rev(colors()), horiz = TRUE,
las = 1, xaxt = "n", main = expression("657 of " ~ italic(colors()))
)
dev.off()
sample()随机抽取颜色
palette()修改默认色盘
颜色生成和转换函数
rgb()
红绿蓝三原色混合来构造颜色
#rgb使用实例
xx <- c(1912, 1912:1971, 1971)
yy <- c(min(nhtemp), nhtemp, min(nhtemp))
plot(xx, yy, type = "n", xlab = "Year", ylab = "Temperatures")
for (i in seq(255, 0, -3)) {
yy <- c(45, nhtemp - (nhtemp - min(nhtemp)) * (1 - i / 255), 45) # rgb() 中的绿色成分逐渐变小
polygon(xx, yy, col = rgb(1, i / 255, 0), border = NA)
Sys.sleep(0.05)#动态描述作图过程
}
box() # 补齐边框
hsv()
色调(Hue)、饱和度(Saturation)和纯度(Value)来构造颜色hcl()
色调(Hue)、色度(Chroma)和亮度(Luminance)构造颜色gray(), grey()
生成灰色系列色rgb2hsv()
将 RGB 颜色转换为 HSV 颜色col2rgb()
将任意一种 R 颜色值转换为 RGB 表示
具体用法,参考R帮助文档。
特定颜色主题调色板
用一系列渐变的颜色表现了特定的主题。
rainbow()
用彩虹色
「scales辅助展示颜色」
library(scales)#scales辅助展示颜色
show_col(rainbow(5),labels=T)
heat.colors()
从红色渐变到黄色再变到白色(以体现“高温”、“白热化”)
terrain.colors()
从绿色渐变到黄色再到棕色最后到白色(这些颜色适合表示地理地形)
topo.colors()
从蓝色渐变到青色再到黄色最后到棕色cm.colors()
从青色渐变到白色再到粉红色
RColorBrewer
> library(RColorBrewer)
> brewer.pal(9, "Blues")
[1] "#F7FBFF" "#DEEBF7" "#C6DBEF" "#9ECAE1" "#6BAED6" "#4292C6" "#2171B5"
[8] "#08519C" "#08306B"
「连续型调色板 Sequential palettes」生成一系列连续渐变的颜色,通常用来标记连续型数值的大小
display.brewer.all(type = "seq") # 连续型:18 种
display.brewer.all(type = "div") # 极端化:9 种
display.brewer.all(type = "qual") # 离散型:8 种
2、点
即python绘图里面的marker,R中使用「pch」等参数及低层函数、「points()函数」控制点。
python版本可戳:Python可视化|matplotlib03-一文掌握marker和linestyle使用
demo("pointTypes", package = "MSG")#可用的点类型
idx <- as.integer(iris[["Species"]])# 先将鸢尾花的类型转化为整数 1、2、3,便于使用向量
plot(iris[, 3:4],
pch = c(24, 21, 25)[idx],#pch = c(24, 21, 25)[idx]传入向量设置点类型
col = c("black", "red", "blue")[idx], panel.first = grid()
)
legend("topleft",
legend = levels(iris[["Species"]]),
col = c("black", "red", "blue"), pch = c(24, 21, 25), bty = "n"
)
par(mar = c(0.2, 0.2, 0.2, 0.2), mfrow = c(2, 2))
for (n in c(63, 60, 76, 74)) {
set.seed(711)
plot.new()
box()
size <- c(replicate(n, 1 / rbeta(2, 1.5, 4)))#随机大小
center <- t(replicate(n, runif(2)))[rep(1:n, each = 2), ]#随机位置
color <- paste("#", apply(
replicate(2 * n, sample(c(0:9, LETTERS[1:6]), 8, TRUE)), 2, paste,
collapse = ""
), sep = "")#随机颜色
points(center, cex = size, pch = rep(20:21, n), col = color)#修改rep(8,13, n)中数字即可展示不同形状
}
3、曲线、直线、线段、箭头、X-样条
plot(1:10, type = "n", xlim = c(0, 10), ylim = c(0, 10))# 不作图,只画出框架,且指定坐标轴范围
# 10 个正态随机数绝对值的波动线
lines(1:10, abs(rnorm(10)))
#直线线性设置
abline(a = 0, b = 1, col = "gray") # 对角线
abline(a = 0, b = 2, col = "red",,lty='711911')
#lty控制直线线性,一般取值 0~6
#'711911' 表示:7 单位长实线、1 单位长空白、1 单位长实线、9 单位长空白、1 单位长实线、1 单位长空白。
#这个十六进制的数字串的最长长度限制为 8 位。
#水平垂直直线
abline(v = 2, h = 2, lty = 2)
text(8, 3, "abline(a = 0, b = 1)") # 添加文本
#添加箭头
arrows(8, 3.5, 6, 5.7, angle = 40)
#
# 参数用了向量:不同灰度的线段
segments(rep(3, 4), 6:9, rep(5, 4), 6:9, col = gray(seq(0.2, 0.8, length = 4)))
text(4, 9.8, "segments")
4、矩形、多边形
「polygon()
函数」绘制多边形,「rect()函数」绘制矩形,一个简单例子。
x <- rnorm(40) # 产生 40 个正态随机数
plot(x, xlab = "", type = "l") # 画折线图
polygon(c(1, 1:40, 40), c(0, x, 0), col = "pink")#绘制多边形
xy <- par("usr") # 获取当前图形区域坐标范围,以便下用
rect(xy[1], xy[3], xy[2], 0, col = "white")# 用白色矩形挡住了 0 以下的部分
lines(x) # 重画一遍 x 的线条
abline(h = 0, col = "lightgray") # 添加水平线
5、网格线
用添加背景网格线的办法来辅助读者的视线对齐坐标轴,以便图形阅读者知道图中元素的更精确的位置,「函数 grid()
」 所实现的就是这一个功能。
x <- rnorm(40) # 产生 40 个正态随机数
plot(x, xlab = "", type = "l") # 画折线图
grid(nx = NULL, col = "red", lty = "dotted", lwd = par("lwd"),equilogs = TRUE)
6、标题、任意文本、周边文本
三者都是用来辅助解释图形的信息。
标题(主副标题和坐标轴标题), title()
任意文本, text()
图形周边文本, mtext()
x <- rnorm(40) # 产生 40 个正态随机数
plot(x, xlab = "", type = "l") # 画折线图
title(main = '《三国演义》', sub = '蜀国', xlab = '刘备', ylab = '诸葛亮')
text(10, -1, "text文本",col='red') # 添加文本
mtext('mtext文本', side = 3, line = 0)
7、图例
告诉图形使用者图中各组不同样式的元素分别代表何种对象。
一个例子,也是**“6、标题、任意文本、周边文本”**很好的例子。
par(mar = c(4, 4, 4, 3))
plot(0:10, type = "n", xlab = "", ylab = "", xlim = c(0, 12))
grid(col = "gray")
title(
main = "Demonstration of text in R Graphics",#主标题
xlab = "X-axis title", #x轴标题
ylab = "Y-axis title"#y轴标题
)
mtext("Here is \"side = 4\"", side = 4, line = 1)#图的四条边上添加文本
x <- c(6, 4, 6, 8)
y <- c(8, 5, 2, 5)
s <- c(0, 90, 180, 270)
for (i in 1:4) {
text(x[i], y[i], sprintf("srt = %d", s[i]), srt = s[i])
}
segments(c(6, 0, 6, 12), c(10, 5, 0, 5), c(0, 6, 12, 6),
c(5, 0, 5, 10),
lty = c(2, 1, 1, 2)#添加线段
)
legend(-0.2, 9.8, c("Upper", "Lower"),
lty = 2:1, cex = 0.8,
bty = "n"
)#图例
8、坐标轴
axis()
函数来辅助完成对坐标轴的设置和调整,一个例子。
data(Export.USCN, package = "MSG")
par(mar = c(4, 4.5, .1, 4.5))
# 看似条形图,实为粗线条,宽度 lwd = 10
plot(1:13, Export.USCN$Export,
xlab = "Year / Country",
ylab = "US Dollars ($10^{16}$)", xaxt = "n", type = "h",
lwd = 10, col = c(rep(2, 6), NA, rep(4, 6)), lend = 1,
panel.first = grid()
)
# 设置 x 轴的刻度标记:\n 的意思是换行符
xlabel <- paste(Export.USCN$Year, "\n", Export.USCN$Country)
xlabel[7] <- ""
abline(v = 7, lty = 2) # 添加一条分隔线
# 使用带有换行符的刻度标记
axis(1, 1:13, labels = xlabel, tick = FALSE, cex.axis = 0.75)
# 换算为人民币再计算另一个坐标轴刻度(汇率 8.27)
ylabel <- pretty(Export.USCN$Export * 8.27)
axis(4, at = ylabel / 8.27, labels = ylabel)
mtext("Chinese RMB ($10^{16}$)", side = 4, line = 2)
box()
往期精彩:
有意见请移步到QQ群629562529反馈,一起进步哈!