4 标度、坐标轴和图例
标度(scale) 控制着数据到图形属性的映射。标度将我们的数据转化为视觉上可以感知的东西例如大小、颜色、位置或形状。标度也为我们提供了读图时所使用的工具:坐标轴和图例(总的来说可称为引导元素)。
4.1 用法
标度构建器的命名:以scale_开头,,接下来是图形属性的名称(例如colour_、shape_或x_),最后以标度的名称结尾(例如gradient、hue或manual) 。离散型数据的颜色图形属性的默认标度名为scale_colour_hue(),填充色的Brewer配色标度名为scale_fill_brever()。
4.2 标度分类
标度可以粗略地分为四类:位置标度、颜色标度、手动标度、同一型标度。
对于位置型图形属性,引导元素是坐标轴;对于所有其他图形属性来说,引导元素是图例。
4.2.1 位置标度
用于将连续型、离散型和日期-时间型变量映射到绘图区域,以及构造对应的坐标轴。
辅助函数xlim()
、ylim()
。
连续型位置标度是scale_x_continuous()
、scale_y_continuous()
,均可接受trans参数,指定若干种线性或非线性的变换,每种变换由“变换器”实现(见左下图)。
日期和时间:三个参数控制外观和刻度的位置major、minor、format,常用的时间格式见右下图。
4.2.2 颜色标度
用于将连续型和离散型变量映射到颜色。
三类连续型颜色梯度(渐近色):
scale_colour_gradient() 和 scale_fill_gradient()
scale_colour_gradient2() 和 scale_fill_gradient2()
scale_colour_gradientn() 和 scale_fill_gradientn()
离散型:
默认的配包方案,即scale_colour_hue(),对类别型数据点,感兴趣的调色板是“Set1”和“Dark2”,对于面积而言是“Set2”、“Pastel1”、“Pastel2”和“Accent”。1
2
3
4
5
6
7
8> point <- qplot(brainwt, bodywt, data = msleep, log = 'xy', colour = vore)
> area <- qplot(log10(brainwt), data = msleep, fill = vore, binwidth = 1)
> point + scale_colour_brewer(palette = 'Set1')
> point + scale_colour_brewer(palette = 'Set2')
> point + scale_colour_brewer(palette = 'Pastel1')
> area + scale_fill_brewer(palette = 'Set1')
> area + scale_fill_brewer(palette = 'Set2')
> area + scale_fill_brewer(palette = 'Pastel1')
4.2.3 手动标度
用于将离散型变量映射到我们选择的符号大小、线条类型、形状或颜色,以及创建对应的图例。
scale_shape_manual(),scale_linetype_manual(),scale_colour_manual()等,重要参数是values。1
2
3
4> plot <- qplot(brainwt, bodywt, data = msleep, log = 'xy')
> colours <- c(carni = "red", "NA" = "orange", insecti = "yellow", herbi = "green", omni = "blue")
> plot + aes(colour = vore) + scale_colour_manual(values = colours)
> plot + aes(shape = vore) + scale_shape_manual(values = c(1, 2, 6, 0, 23))
4.2.4 同一型标度
用于直接将变量值绘制为图形属性,而不去映射它们。举例来说,假设想要将变量映射为符号的颜色,而此变量本身就是一个由颜色值组成的向量,那么就无须再将其映射为其他的颜色,直接渲染这些值本身即可。
4.3 通用参数
name
:设置坐标轴或图例上出现的标签,通常使用三个辅助函数xlab(),ylab()和labs()limits
:固定标度的定义域。连续型标度接受一个长度为2 的数值型向量,离散型标度接受一个字符型向量。breaks
和labels
:breaks控制着显示在坐标轴或图例上的值,即坐标轴上应该显示哪些刻度线的值,或一个连续型标度在一个图例中将被如何分段。labels 指定了应在断点处显示的标签。若设置了labels,则必须同时指定breaks,只有这样,这两个参数才能被正确匹配。formatter
:如果未指定任何标签则将在每个断点处自动调用格式刷(formatter) 来格式化生成标签。对于连续型标签,可用的标签刷为comma, percent, dollar 和scientific; 对于离散型标度则为abbreviate。
5 定位
定位由四个部分组成:位置调整、位置标度、分面和坐标系,其中,位置调整和位置标度前面已经学习过了。
5.1 分面
分面即在一个页面上自动摆放多幅图形的技法:先将数据划分为多个子集,然后将每个子集依次绘制到页面的不同面板中。这类图形也通常被称作小联号图(small multiples)。
两种分面类型:网格型(facet_grid) 和封装型(facet_vrap)。网格分面生成的是一个2维的面板网格,面板的行与列通过变量来定义;封装分面则先生成一个1维的面板条块.然后再封装到2维中。
5.1.1 网格分面
一行多列:. ~ a
一列多行:b ~ .
多行多列:a ~ b
多个变量的多个水平在行或者列上(或者同时):. ~ a + b
或a + b ~ .
边际图:margins = TRUE
展示多有边际图;margins = c('x', 'y')
列出想要展示的变量名1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#一行多列的两种实现方法,图略
> ggplot(data = mpg) +
+ geom_point(aes(cty, hwy)) +
+ facet_grid(. ~ cyl)
> qplot(cty, hwy, data = mpg) + facet_grid(. ~ cyl)
#一列多行的两种实现方法,图略
> ggplot(data = mpg) +
+ geom_histogram(aes(cty), binwidth = 2) +
+ facet_grid(cyl ~ .)
> qplot(cty, data = mpg, geom = 'histogram', binwidth = 2) + facet_grid(cyl ~ .)
#多行多列的两种实现方法,左下图
> ggplot(data = mpg) + geom_point(aes(cty, hwy)) + facet_grid(drv ~ cyl)
> qplot(cty, hwy, data = mpg) + facet_grid(drv ~ cyl)
#边际图
> p <- qplot(displ, hwy, data = mpg) + geom_smooth(method = 'lm',se = F)
> p + facet_grid(cyl ~ drv, margins = T)
5.1.2 封装分面
设置格式:~ a + b + c
,可以通过参数ncol、nrow来更新默认设置1
2
3> ggplot(data = mpg) +
+ geom_point(aes(displ, hwy)) +
+ facet_wrap(~ class, nrow = 2)
5.1.3 标度控制
scales = "fixed"
:x和y的标度在所有面板中都相同scales = "free"
:x和y的标度在每个面板都可以变化scales = "free_x"
:x的标度可变,y的尺度固定scales = "free_y"
:y的标度可变,x的尺度固定
固定标度可以在相同的基准上对子集进行比较,自由标度在展示不同量纲的时间序列非常有用。
facet_grid还有一个额外的参数space = free/fixed
,可以设置不同面板的标度比例。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15> p <- qplot(cty, hwy, data = mpg)
> p + facet_wrap(~ cyl, scales = 'free')
> library(reshape2)
> em <- melt(economics,id = 'date')
> head(em)
date variable value
1 1967-07-01 pce 506.7
2 1967-08-01 pce 509.8
3 1967-09-01 pce 515.6
4 1967-10-01 pce 512.2
5 1967-11-01 pce 517.4
6 1967-12-01 pce 525.1
> qplot(date, value, data = em, geom = 'line', group = variable) +
+ facet_grid(variable ~ ., scale = 'free_y')
5.1.4 连续型变量
对连续型变量进行分面,需要首先将其变换为离散型。
将数据分为n个长度相同的部分:cut_interval(x, n = 10)
控制划分面板的数目;cut_interval(x, length = 1)
控制每个部分的长度。
将数据划分为n个有相同数目点的部分:cut_number(x, n = 10)
注意:需要先在数据集中创建一个包含了离散化后的数据的新变量,再将新变量应用到分面表达式中。
5.2 坐标系
坐标系即通过控制两个独立的位置标度来生成一个2维的坐标系。最常见的是笛卡尔坐标系。
命名规则是coord_
加上坐标系的名字,如coord_cartesian()
5.2.1 设置范围
coord_cartesian()有两个参数xlim和ylim。与标度的范围设置的区别:当设定标度范围时,任何超出此范围的数据都会被删除;但当设定笛卡尔坐标系的范围时,使用的仍然是所有的数据,只不过只展示一小片图形区域。如下图三是坐标系的放缩,而下图二标度的范围设置则是对数据取子集,然后再重新拟合曲线。1
2
3
4
5> (d <- ggplot(diamonds, aes(carat, price)) +
+ stat_bin2d(bins = 25, colour = 'grey70') +
+ theme(legend.position = 'none'))
> d + scale_x_continuous(limits = c(0, 2))
> d + coord_cartesian(xlim = c(0, 2))
5.2.2 翻转和变换
coord_flip
调换x和y轴,拟合的是初始数据,再翻转输出结果。coord_trans
进行数据变换。标度层面的变换发生在统计量计算之前,且不会改变对象的几何形状;坐标系层面的变换发生在统计量计算之后,会影响几何形状。两种变换一起使用时,先在变换的尺度上建模,然后再反演到变换前的图形以便于解释。1
2
3
4
5
6
7#翻转
> qplot(cty, displ, data = mpg) + geom_smooth()
> qplot(cty, displ, data = mpg) + geom_smooth() + coord_flip()
#变换
> qplot(carat, price, data = diamonds, log = 'xy') + geom_smooth(method = 'lm')
> library(scales)
> last_plot() + coord_trans(x = exp_trans(10), y = exp_trans(10))
5.2.3 极坐标
极坐标常被用于环形数据,特别是时间和方向数据,参数theta决定哪个变量被映射为角度(默认为x),哪个被映射为半径。利用极坐标可以生成饼图、玫瑰图(源自条状图)和雷达图(源自直线几何对象)。1
2
3
4
5
6
7#堆叠条状图
> (pie <- ggplot(mtcars, aes(x = factor(1), fill = factor(cyl))) +
+ geom_bar(width = 1))
#饼图
> pie + coord_polar(theta = 'y')
#牛眼图
> pie + coord_polar()
6 精雕细琢
6.1 主题
全局性设置:theme_set(theme_grey())
或theme_set(theme_bw())
。theme_set()
返回先前的主题。
局部性设置:qplot(...) + theme_grey()
,会覆盖默认的全局性设置。
控制元素外观的函数被称为元素函数,内置元素函数有四个基础类型:文本、线条、矩形和空白,每个元素函数有一系列控制外观的参数。element_text()
绘制标签和标题,可控制字体的family, face, colour, size, hjust, vjust, angle, lineheight,如theme(plot.title = element_text(size = 20))
element_line()
绘制线条或线段,可控制colour, size, linestyle。element_rect()
绘制主要供背景使用的矩形,可以控制填充颜色fill和边界的colour, size, linetype。element_blank()
表示空主题,即对元素不分配相应的绘图空间。
6.2 存储输出
png()
或pdf()
,打印图形print()
,然后关闭图形设备dev.off()
1
2
3
4> a <- qplot(date, unemploy, data = economics, geom = 'line')
> png(file = 'D:/hexo/hexo/source/_posts/ggplot2-2/outp.png', width = 400, height = 300)
> print(a)
> dev.off()
6.3 一页多图
6.3.1 子图
viewport()
创建视图窗口,参数x, y, width, height 控制视图窗口的大小和位置。为了能在新视图窗口画图,需要使用print()的vp参数。1
2
3
4
5
6
7
8
9
10
11
12
13
14> b <- qplot(uempmed, unemploy, data = economics) + geom_smooth(se = F)
> c <- qplot(uempmed, unemploy, data = economics, geom = 'path')
> library(grid)
> png(file = 'D:/hexo/source/_posts/ggplot2-2/outp1.png', width = 400, height = 300)
> subvp <- viewport(width = 0.4, height = 0.4, x = 0.75, y = 0.35)
> b
> print(c, vp = subvp)
> dev.off()
#对图形外观进行微调:文本更小,移除标签,缩减图形边界
> csmall <- c + theme_gray(9) + labs(x = NULL, y = NULL) + theme(plot.margin = unit(rep(0, 4), 'line'))
> png(file = 'D:/hexo/source/_posts/ggplot2-2/outp2.png', width = 400, height = 300)
> b
> print(csmall, vp = subvp)
> dev.off()
6.3.2 矩形网格
grid.layout()
设置一个任意高和宽的视图窗口网格。1
2
3
4
5
6
7
8
9> png(file = 'D:/hexo/source/_posts/ggplot2-2/outp3.png', width = 400, height = 300)
> grid.newpage()
> pushViewport(viewport(layout = grid.layout(2,2)))
> vplayout <- function(x, y)
+ viewport(layout.pos.row = x, layout.pos.col = y)
> print(a, vp = vplayout(1, 1:2))
> print(b, vp = vplayout(2, 1))
> print(c, vp = vplayout(2, 2))
> dev.off()
- 本笔记基于Hadley Wickham的《ggplot2:数据分析与图形艺术》整理