R数据可视化-ggplot2的标度

标度控制着数据到图形属性的映射,标度将我们的数据转化为视觉上可以感知的东西,如大小、颜色、位置和形状,所以通过标度可以修改坐标轴和图例的参数。

每一种图形属性都拥有一个默认的标度,此标度将在我们每次使用这个图形属性时被自动添加到图形中,这些标度列于下表中,默认属性粗体显示:

图形属性 离散型 连续型
颜色和填充色 brewer grey hue identity manual gradient gradient2 gradientn
位置 discrete continuous date
形状 shape identity manual
线条类型 linetype identity manual
大小 identity manual size

如果要添加一个不同的标度或修改默认标度的某些特征,我们必须构建一个新的标度,然后使用+将其添加到图形上。所有的标度构建器(scale)都拥有一套通用的命名方案,它们以scale_开头,接下来是图形属性的名称(例如:colour_shape_x_)最后以标度的名称结尾(gradienthuemanual)。

  • 离散图形的颜色属性采用默认标度:scale_colour_hue()
  • 离散图形的填充色属性采用ColorBrewer配色标度:scale_fill_brewer()

下面是一个例子:

1
2
3
4
5
6
# 默认标度-左图
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()

# 调整标度的参数-右图
p + scale_colour_hue("cut",breaks=c("Fair","Good","Very Good"),labels=c("A","B","C"))

标度系列函数

标度系列函数可以粗略的分为4类:

  • 位置标度:用于将连续型、离散型和日期-时间型变量映射到绘图区域,以及构造对应的坐标轴
  • 颜色标度:用于将连续型和离散型变量映射到颜色
  • 手动离散型标度:用于将离散型变量映射到我们选择的符号大小、线条类型、形状或颜色,以及创建对应的图例
  • 同一型标度:用于直接将变量值绘制为图形属性,而不去映射他们

通用参数

上面这些标度系列函数都会有一些参数,这些就是通用参数,下面简单介绍一下这些通用参数。

name

name:设置坐标轴或图例上出现的标签。可以使用三个辅助函数xlab()ylab()labs()来减少代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 默认-左上
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()

# 添加x标签-右上
p + scale_x_continuous("Diamonds carat")

# 添加x标签(使用xlab()这个辅助函数)
p + xlab("Diamonds carat")

# 同时添加x、y及colour标度-左下
p + labs(x = "Diamonds carat", y = "Diamonds price", colour = "Diamond Cut")

# 添加x标度为表达式-右下
p + xlab(expression(frac(carat,10)))

limits

limits:固定标度的定义域

  • 连续型标度接受一个长度为2的数值型向量
  • 离散型标度接受一个字符型向量

我们可以通过设定limits来移除不想在图形上展示的数据,任何不在此范围内的数据将会被丢弃

1
2
3
4
5
6
7
8
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()

# 设定x轴的范围-左图
p + scale_x_continuous(limits = c(0,3))

# 设定colour的范围-右图
p + scale_colour_hue(limits = "Fair")

breaks、labels

  • breaks表示在坐标轴/图例上哪些点的位置标标签
  • labels表示标什么标签,若设定labels,则必须同时指定breaks。
1
2
3
4
5
6
7
8
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()

# 设定x轴的坐标轴的值-左图
p + scale_x_continuous(breaks = c(0,3))

# 设定图例上的值-右图
p + scale_colour_hue(breaks = "Fair")

位置标度

每幅图都一定拥有两个位置标度,一个指定水平位置(x标度),另外一个指定竖直位置(y标度)。ggplot2提供了连续型、离散型(针对因子型、字符型和逻辑型向量)以及日期型标度。

连续型位置标度

最常用的连续型位置标度是scale_x_continuousscale_y_continuous,它们均将数据映射到x轴和y轴。而最有趣的变式是通过变换来生成的,每一个连续型标度都可以接受一个trans 参数,允许指定若干种线性或非线性的变换。

下面是支持的变换:

名称 变换函数$f(x)$ 逆变换函数$f^{−1}(x)$
asn $tanh^{−1}(x)$ $tanh(y)$
exp $e^x$ $log(y)$
identity $x$ $y$
log $log(x)$ $e^y$
log10 $log_{10}(x)$ $10^y$
log2 $log_2(x)$ $2^y$
logit $log(\frac{x}{1−x})$ $\frac{1}{1+e(y)}$
pow10 $10^x$ $log_{10}(y)$
probit $\phi(x)$ $\phi^{−1}(y)$
recip $x^{−1}$ $y^{−1}$
reverse $−x$ $−y$
sqrt $x^{\frac{1}{2}}$ $y^2$

对于连续型位置标度,变换有简写形式,比如scale_x_continuous(trans = “log10”)可以简写为scale_x_log10()。参数trans对任意连续型标度均有效,但只有位置标度有简写形式。

当然,可以直接对变量进行变换,而不使用标度变换。比如我们可以直接绘制log10(x),而不去使用scale_x_log10()

这两种做法将在绘图区域生成完全相同的结果,但是坐标轴和刻度标签却是不同的

下面是一个对比:

1
2
3
4
5
6
7
8
# 自行变换log10()-左图
p <- ggplot(data = diamonds, mapping = aes(x = log10(carat), y = log10(price), color = factor(cut)))
p <- p + geom_point()

# scale_x_log10()变换-右图
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()
p <- p + scale_x_log10() + scale_y_log10()

日期和时间

日期和时间值基本上属于连续型标度,但在标注坐标轴时有着特殊的处理方式。目前我们仅支持属于date类的日期值和属于POSIXct类的时间值。如果你的日期和时间值是其他格式的,则需要as.Date()as.POSIXct()对其进行转换。

一共有三个参数可以控制坐标轴外观和刻度的位置:major、minor、format:

  • major、minor:以时间的单位(即年月周日时分秒)来指定主要和次要断点的位置,并且允许以这些单位的倍数出现,比如,major = "2weeks"将在每隔两周的位置放置一个主刻度。如果未指定,日期刻度可以自动选出合适的默认值。
  • format:指定了刻度标签的格式。

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
library(scales)

# 时间序列-左上
p <- ggplot(data = economics, mapping = aes(x = date, y = psavert))
p <- p + geom_line()

# 添加水平线-右上
p <- p + geom_hline(xintercept = 0, yintercept = 0, colour = "gray50")

# 每隔10年为一个断点-左下
p + scale_x_date(breaks = date_breaks("10 years"))

# 使用年月日的格式仅显示在2004年内的图形-右下
p + scale_x_date(limits = as.Date(c("2004-01-01","2005-01-01")), labels = date_format("%Y-%m-%d"))

离散型位置标度

离散型位置标度scale_x_discretescale_y_discrete将输入中的各个水平映射为整数。结果的顺序可用参数breaks进行控制,不想要的水平可以使用limits(或xlim、ylim)进行丢弃。

由于我们经常也会在图形的非整点位置放置标签和标注,所以离散型位置标度也可以接受连续型的值。如果你尚未调整breaks或limits,某个因子水平的所在位置的数值表示可以使用as.numeric()进行计算:以从1开始的整数表示。

离散型位置标度的参数主要是前面提到的通用参数

下面看一个例子:

1
2
3
4
5
6
7
8
9
# 默认方案-左图
p <- ggplot(data = diamonds, mapping = aes(cut, price))
p <- p + geom_boxplot()

# 更改横轴标度-中图
p + scale_x_discrete(labels = c("Fair" = "A","Good" = "B", "Very Good" = "C","Premium" = "D","Ideal" = "E"))

# 移除不想展示的cut-右图
p + scale_x_discrete(limits = c("Fair","Good"))

颜色标度

以下标度对边界色(colour)图形属性填充色(fill)图形属性均有效。

连续型颜色标度

根据颜色梯度中的色彩数量划分,共有三类连续型颜色梯度(即渐变色):

  • scale_colour_gradient()scale_fill_gradient():双色梯度。参数low和high控制梯度两端的颜色
  • scale_colour_gradient2()scale_fill_gradient2():三色梯度。顺序为低-中-高,这两种标度还在中点处拥有一个中间色
  • scale_colour_gradientn()scale_fill_gradientn():自定义n色梯度

颜色梯度常被用来展示一个二维表面的高度,用以描述第三维度,颜色的深浅代表着不同的值。例如描述地势高低时,地势的高低常常用颜色深浅来展现。

下面我们用R自带的一个向量数据集volcano,因为ggplot2只接受数据框格式,因此我们先把数据转换成数据框格式:

1
2
3
4
library(reshape2)

volcano3d <- melt(volcano)
names(volcano3d) <- c("x", "y", "z")

下面展示双色梯度scale_fill_gradient()的用法:

1
2
3
4
5
6
7
8
9
# 默认参数-左图
p <- ggplot(data = volcano3d,mapping = aes(x,y,fill=z))
p <- p + geom_tile()

# 控制填充颜色的值范围-中图
p + scale_fill_gradient(limits = c(120,170))

# 通过参数low与high,控制颜色在low与high之间渐变-右图
p + scale_fill_gradient(low = "blue", high = "red")

下面展示三色梯度scale_fill_gradient2()的用法:

1
2
3
4
5
# 默认参数,即midpoint=0-左图
p + scale_fill_gradient2(low = "blue", high = "red")

# 设置midpoint=150-右图
p + scale_fill_gradient2(low = "blue", high = "red", midpoint = 150)

以上两图都设定了颜色由 blue 到 red 渐变,但是左图使用默认参数 midpoint=0,右图使用参数midpoint=150,而 z 值的范围是 94~195,所有他们在图中实际渐变色为,左图:浅红-红,右图:蓝-白-红

下面展示自定义n色梯度scale_fill_gradientn()的用法:

1
2
3
4
5
# 手动设置颜色-左图
p + scale_fill_gradientn(colours = c("black","blue","red","white"))

# 采用R语言预设的调色盘-右图
p + scale_fill_gradientn(colours = topo.colors(10))

离散型颜色标度

离散型数据有两种颜色标度。一种可以自动选择颜色,另一种可以手工从颜色集中选择颜色。

  • 默认的配色方案,即scale_colour_hue()scale_fill_hue(),可通过沿着hcl色轮选取均匀分布的色相来生成颜色。这种方案对颜色较少时有比较好的效果,但对于更多不同的颜色就不好区分开来。

  • 另一种可选的方案是ColorBrewer配色。即scale_colour_brewer()scale_fill_brewer()。要想了解所有的调色板,可以使用RColorBrewer::display.brewer.all()查看。我们可以用参数palette=”调色板名称或者数字”来使用。例如,使用第二个调色板时用palette = 2(等价于palette = 'YIOrBr')。

1
2
3
4
5
6
7
8
9
10
11
12
# 默认方案,即scale_colour_hue()-左上图
p <- ggplot(data = diamonds, mapping = aes(cut, price, fill = color))
p <- p + geom_boxplot()

# 采用ColorBrewer配色-右上图
p + scale_fill_brewer()

# 采用ColorBrewer配色中第二个调色板-左下图
p + scale_fill_brewer(palette = 2)

# 采用ColorBrewer配色中'Spectral'调色板-右下图
p + scale_fill_brewer(palette = "Spectral")

手动离散型标度

离散型标度scale_linetype()scale_colour_manual()scale_size_discrete()scale_shape()是按一定的顺序将因子的水平映射到一系列取值中。如果想要定制这些标度,需要使用以下手动型标度创建新的标度

  • scale_linetype_manual()
  • scale_colour_manual()
  • scale_size_discrete()
  • scale_shape_manual()

手动型标度拥有一个重要参数values,我们可以用它来指定这个标度应该生成的值。

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 默认颜色-左上图
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, color = factor(cut)))
p <- p + geom_point()

# 手动改变颜色-右上图
p + scale_colour_manual(values = c("Fair" = "red","Good" = "yellow","Very Good" = "green","Premium" = "blue","Ideal" = "black"))

# 默认大小-左下图
p <- ggplot(data = diamonds, mapping = aes(x = carat, y = price, size = factor(cut)))
p <- p + geom_point()

# 手动改变大小-右下图
p + scale_size_manual(values = c(10,8,6,4,2))

同一型标度

当你的数据能被R中的绘图函数理解时,即数据空间和图形属性空间相同时,可以使用同一性标度(identity scale),这意味着此时无法仅从数据本身派生出有意义的图例,所以默认是不绘制图例。

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡