R语言学习笔记20
29 ggplot作图入门
在作常用的图形时, 只需要两个步骤: 首先将图形所展现的数据输入到ggplot()函数中, 然后调用某个geom_xxx()函数, 指定图形类型,如散点图、曲线图、盒形图等。
如果需要进一步控制图形细节, 只要继续调用其它函数, 就可以控制变量值的表现方式(scale)、图例、配色等。 这使得我们很容易做出基本的图形, 在有需要时再深入学习, 做出更为满意的图形。
与基本R中的作图系统相比, ggplot2的作图有规律可循, 作图结果直接达到出版印刷质量, 除了可以按照一些既定模式做出常见种类的图形, 也很容易将不同图形种类组合在一起, 或者设计新颖的图形。 基本R的作图结果通常不够美观, 如果要将不同种类图形组合在一起比较困难, 对设计新的图形类型支持也不够好。
ggplot2的作图一般步骤为:
- 准备数据,一般为数据框, 且一般为长表, 即每个观测时间占一行, 每个观测变量占一列。
- 将数据输入到
ggplot()
函数中, 并指定参与作图的每个变量分别映射到哪些图形特性, 比如映射为x坐标、y坐标、颜色、形状等。 这些映射称为aesthetic mappings或aesthetics。 - 选择一个合适的图形类型, 函数名以
geom_
开头, 如geom_point()
表示散点图。 图形类型简称为geom。 将ggplot()
部分与geom_xxx()
部分用加号连接。 到此已经可以作图,下面的步骤是进一步的细化设定。 - 设定适当的坐标系统, 如
coord_cartesian()
,scale_x_log10()
等。 仍用加号连接。 - 设定标题和图例位置等,如
labs()
。 仍用加号连接。
这个流程的一个大致的模板为:
p <- ggplot(data=<输入数据框>, |
其中<…>表示额外的选项。 变量p包含做出的图形的所有数据与设定, 变量名可以任意取。
# 安装socviz |
后续的例子中用到一些数据集:
- 来自gapminder扩展包的gapminder数据集, 有若干个国家不同年份的一些数据, 包括所属洲、期望寿命、人口数、人均GDP。 有1704个观测和6个变量。
- socviz包的
gss_sm
数据集,是2016年美国一般社会调查数据的部分内容。 有2867个观测,32个变量。 社会调查数据的变量主要取属性值, 比如无序分类、有序分类、分组的数值、整数值等。 - socviz包的organdata数据集, 是17个OECD国家历年的器官捐献情况以及一些其它记录。
- socviz扩展包的
elections_historic
数据集。 包括美国历次总统大选当选人、所属党派、支持比例等。 - socviz扩展包的asasec数据集。 这是美国社会学学会(ASA)的各分会2005年到2015年的一些数据。
- ggplot2包中的
midwest
数据集包含了美国中西部的一些县的统计数据, 如面积等。 - 来自ggplot2包的钻石数据集。
# gapminder的头部: |
country | continent | year | lifeExp | pop | gdpPercap |
---|---|---|---|---|---|
Afghanistan | Asia | 1952 | 28.801 | 8425333 | 779.4453 |
Afghanistan | Asia | 1957 | 30.332 | 9240934 | 820.8530 |
Afghanistan | Asia | 1962 | 31.997 | 10267083 | 853.1007 |
Afghanistan | Asia | 1967 | 34.020 | 11537966 | 836.1971 |
Afghanistan | Asia | 1972 | 36.088 | 13079460 | 739.9811 |
出现的问题记录
加载R包的时候,出现报错
......,载入了名字空间‘rlang’ 0.4.5,但需要的是>= 0.4.6
解决方案:
remove.packages('rlang') |
然后又出现报错
错误: package or namespace load failed for ‘tidyverse’ in loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]]): |
使用上面的方法安装包
remove.packages('vctrs')
install.packages('vctrs')
remove.packages('vctrs') |
gss_sm的头部:
library(socviz) |
year | id | ballot | age | childs | sibs | degree | race | sex | region | income16 | relig | marital | padeg | madeg | partyid | polviews | happy | partners | grass | zodiac | pres12 | wtssall | income_rc | agegrp | ageq | siblings | kids | religion | bigregion | partners_rc | obama |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2016 | 1 | 1 | 47 | 3 | 2 | Bachelor | White | Male | New England | $170000 or over | None | Married | Graduate | High School | Independent | Moderate | Pretty Happy | NA | NA | Aquarius | 3 | 0.9569935 | Gt $170000 | Age 45-55 | Age 34-49 | 2 | 3 | None | Northeast | NA | 0 |
2016 | 2 | 2 | 61 | 0 | 3 | High School | White | Male | New England | $50000 to 59999 | None | Never Married | Lt High School | High School | Ind,near Dem | Liberal | Pretty Happy | 1 Partner | Legal | Scorpio | 1 | 0.4784968 | Gt $50000 | Age 55-65 | Age 49-62 | 3 | 0 | None | Northeast | 1 | 1 |
2016 | 3 | 3 | 72 | 2 | 3 | Bachelor | White | Male | New England | $75000 to $89999 | Catholic | Married | High School | Lt High School | Not Str Republican | Conservative | Very Happy | 1 Partner | Not Legal | Pisces | 2 | 0.9569935 | Gt $75000 | Age 65+ | Age 62+ | 3 | 2 | Catholic | Northeast | 1 | 0 |
2016 | 4 | 1 | 43 | 4 | 3 | High School | White | Female | New England | $170000 or over | Catholic | Married | NA | High School | Not Str Republican | Moderate | Pretty Happy | NA | NA | Cancer | 2 | 1.9139870 | Gt $170000 | Age 35-45 | Age 34-49 | 3 | 4+ | Catholic | Northeast | NA | 0 |
2016 | 5 | 3 | 55 | 2 | 2 | Graduate | White | Female | New England | $170000 or over | None | Married | Bachelor | High School | Not Str Democrat | Slightly Liberal | Very Happy | 1 Partner | Legal | Scorpio | 1 | 1.4354903 | Gt $170000 | Age 45-55 | Age 49-62 | 2 | 2 | None | Northeast | 1 | 1 |
散点图
基本的散点图
以gapminder数据集作为输入数据, 做出简单的散点图, 并逐步进行改善。 这个数据集有多个国家在多个年份的期望寿命与人均GDP值, 作期望寿命对人均GDP的散点图, 每个国家的每个年份作为一个点。 散点图最重要的映射是x轴与y轴两个维度。
首先调用ggplot()函数, 指定数据集, 将人均GDP映射到x轴, 将期望寿命映射到y轴, 结果保存为一个R变量:
p <- ggplot(data = gapminder, |
x、y轴是最常见的映射, 也可以将变量映射为颜色、符号、线型等.
p <- ggplot(gapminder, aes(gdpPercap, lifeExp))
在如上指定了数据和映射后, 只要用geom_xxx()指定一个图形类型, 并与ggplot()的结果用加号连接就可以作图了
p + geom_point() |
上面的程序等同于调用print(p + geom_point())。
print(p + geom_point()) |
在R函数中或者在循环中需要显式地调用print(), 否则不会显示结果。 当载入了tidyverse系统时可以写成 (p + geom_point()) %>% print()。
逐步改善
指定数据集、指定映射、选择适当的图形类型就可以做出基本的图形, 随后可以逐步对坐标系、坐标系刻度、标签与图例、配色等进行改善。 实际上,ggplot2包已经提供了十分合理的预设值, 用户只要进行一些必要的改动即可。
作图步骤之间用加号连接,这是ggplot包特有的语法。 例如, 用相同的映射做出拟合曲线图:
p + geom_smooth() |
使用最了解的数据集d.class作图
p2 <- ggplot(data=d.class, mapping = aes(x=height,y=weight)) |
用相同的映射做出散点图并叠加拟合曲线图:
p + geom_point() + geom_smooth() |
p2 + geom_point() + geom_smooth() |
geom_smooth()的默认设置调用了gam()函数来拟合曲线, 可以用geom_smooth()的参数选择不同的拟合方法, 如直线拟合:
p + geom_point() + geom_smooth(method = 'lm') |
p2 + geom_point() + geom_smooth(method = 'lm') |
注意geom_xxx()函数计算所需的变量值是从ggplot()函数保存在变量p中的信息提取的。
在以上的所有图形中, x轴变量(人均GDP)分布非正态,严重右偏, 使得大多数散点重叠地分布在直角坐标系的左下角。 将x轴用对数刻度可以改善, 函数为scale_x_log10():
p + geom_point() + geom_smooth(method = "gam") + scale_x_log10() |
对数刻度实际上是对原始数据进行对数变换, 而geom_smooth()的拟合计算是在对数变换之后进行的。
p + scale_x_log10() + geom_point() + geom_smooth(method = "gam") |
调用scales扩展包的适当函数进行改善, 作为scale_x_log10()的labels选项
p + scale_x_log10(labels=scales::dollar) + geom_point() + geom_smooth(method = "gam") |
scale_xxx()的labels选项指定如何标出坐标刻度数字, 参数值是一个函数对象, 如果scales包中找不到适当的功能, 可以自定义一个函数将数值转换为字符串。 scales包提供了comma, date, dollar, math, number, ordinal, pvalue, scientific, time等坐标刻度值转换函数。
测试将图形的x和Y轴颠倒,然后对y轴取10为底的对数
pt <- ggplot(data=gapminder, mapping = aes(x=lifeExp, y = gdpPercap)) |
颜色、符号、线型等映射
在ggplot()函数的mapping参数的aes()设定中将变量映射到x、y轴, 颜色、符号、线型等图形元素类型, 也可以作为图形设置将某些图形元素设置为固定值。
例如, 用不同颜色表示不同大洲, 就是将continent变量映射到color:
p <- ggplot(data=gapminder, |
程序中仅指定了将大洲映射到颜色维, 并不具体指定所用的颜色。
作带有局部多项式曲线拟合的散点图:
p + geom_point() + |
不同散点用了不同颜色表示其continent变量的值, 五个大洲分别进行了曲线拟合, 曲线使用了不同颜色但置信域颜色相同, 使得难以认读。 在图形右侧自动生成了颜色与continent变量值的对应关系图例。
下面的图形仍分不同大洲作曲线拟合, 并将置信区间阴影的颜色也用不同大洲区分, 方法是在aes()中将color和fill都指定为变量continent:
p <- ggplot(data=gapminder, |
将颜色指定为一个固定值
选颜色:
select.colors <- function(){ |
p <- ggplot(data=gapminder, |
散点并没有使用指定的颜色, 而且图形右侧有一个chartreuse4图例。 这是因为, aes()仅用来指定变量与图形元素类型的映射, 所以实际上是生成了一个仅有一个常数值"chartreuse4"的新变量, 用颜色表示这个新变量。 为了指定固定颜色, 应将color=作为geom_xxx()函数的选项, 而不是放在aes()映射中
p <- ggplot(data=gapminder, |
geom_xxx()函数接受许多关于颜色、透明度、符号、线型的设置参数。 比如, 下面的程序指定了散点的透明度, 以及拟合直线的粗细:
# 其中参数alpha代表透明度 |
size指定了线的以毫米为单位的粗细, se = FALSE关闭了置信区间显示。 用alpha =设置了透明度, 取0和1之间的值, 数值越小越透明。 在有许多个点时适当设置透明度可以比较好地显示出重叠的点, 重叠点越多点的颜色越深。 虽然这里设置了固定的透明度, 也可以在aes()中将透明度alpha映射到某个变量, 使得该变量值大小用点的透明度表示。
画线时可以用linetype参数指定线型, 0表示实线, 1到6分别表示不同的虚线线型。
下面用labs()函数给图形加上适当的标题:
p <- ggplot(data=gapminder, |
可以看出, labs()规定了上方的标题、小标题, x轴、y轴的标题, 右下方的标注(caption)。 坐标轴刻度数值的规定则需要在scale_xxx()函数中给出。
在geom函数中映射变量
在前面的一个例图中, 在ggplot()
函数中将color
和fill
映射到了continent
变量, 使得不仅散点颜色代表了不同大洲, 还使得每个大洲单独拟合了曲线。 如果希望所有大洲拟合同一条曲线怎么办?
在必要时, 可以在geom_xxx()
函数中用mapping = aes(<...>)
单独指定变量映射。 例如, 下面的程序在geom_point()
中将不同大洲映射为不同颜色, 而不影响geom_smooth()
中的颜色以及分组:
p <- ggplot(data=gapminder, |
这里常用到的aes是aesthetic(美学的)的缩写
也可以将一个分类变量映射到不同绘图符号。 例如,取gapminder 2007年数据子集, 将大洲映射到符号(shape):
# 如果报错为找不到对象year,则是没有启用filter函数对应的包 |
这种映射仅适用于点数比较少的情况, 还用了size参数指定符号的大小(单位:毫米)。 如果所有点使用同一符号并需要指定符号, 可以在geom_point()中用shape参数指定, 可以用0到25的整数值表示, 比如19为实心点, 也可以用字符串符号名称表示, 如"circle"表示实心点。 参见ggplot2帮助目录中的vignette ggplot2: ggplot2-specs。