R最强项就是可视化,而ggplot2是其中最为著名的包
3.1 ggplot2基本语法
ggplot2 基于图层化语法:图形是一层一层的图层叠加而成。
选取整洁数据将其映射为几何对象(如点、线等) ,几何对象具有美学特征(如坐标轴、颜色等) ,若需要则对数据做统计变换,调整标度,将结果投影到坐标系,再根据喜好选择主题。
绘图流程
包括10个部件, 前3个是必须得, 其他ggplot2会自动帮你设置。
- 数据 data
- 映射 mapping
- 几何对象 geom
- 标度 scale
- 统计变换 stats
- 坐标系 coord
- 位置调整 position adjustments
- 分面 facet
- 主题 theme
- 输出 output
基本模板
ggplot(data = ,
mapping = aes()) +
geom_function(mappong = aes(),
stat = ,
position = )+
<SCALE_FUNCTION> +
<COORDINATE_FUNCTION> +
<FACET_FUNCTION> +
<THEME_FUNCTION>
数据、映射、几何对象
- 数据:用于绘图的数据,需要是整洁的数据框
-
映射: 函数aes() 是ggplot2 中的映射函数, 指明了变量与图形所见元素之间的联系,告诉ggplot 图形元素想要关联哪个变量数据.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv))
经常将图形的美学color, size 等映射到数据集的分类变量,以实现不同分组用不同的美学来区分. 。所以,若要为美学指定特定值,比如color = "red", 是不能放在映射
aes() 中的。
-
几何对象: 每个图形都是采用不同的视觉对象来表达数据
通常用不同类型的‘‘几何对象’’ 从不同角度来表达数据,如散点图、平滑曲线、线形图、条形图、箱线图等。
ggplot2 提供了50 余种‘‘几何对象’’,均以geom_xxxx() 的方式命名,常用的有:
ggplot() 中的数据和映射,是全局的,可供所有几何对象共用;位于’’ 几何对象’’ 中的数据和映射,是局部的,只供该几何对象使用;
‘‘几何对象’’ 优先使用局部的,局部没有则用全局的。
分组使用group
- 标度scale_
标度函数控制几何对象中的标度映射:不只是x, y 轴,还有color, fill, shape, size 产生的图例。 -
常用的标度函数
scales 包提供了很多现成的设置刻度标签风格的函数
1. 修改坐标轴刻度及标签
1.1 用scale_*_continuous() 修改连续变量坐标轴的刻度和标签:
- 参数breaks 设置各个刻度的位置
- 参数labels 设置各个刻度对应的标签
用scale_*_discrete() 修改离散变量坐标轴的标签:
1.2 scale_x_discrete(labels = c("4" = " 四驱", "f" = " 前驱", "r" = " 后驱"))
1.3 用scale_x_date() 设置日期刻度,参数date_breaks 设置刻度间隔,date_labels 设置标签的日期格式;
1.4 借助scales 包中的函数设置特殊格式,比如百分数(percent)、科学计数法(scientific)、美元格式(dollar) 等。
2. 修改坐标轴标签、图例名及图例位置
函数xlab(), ylab(), 设置x 轴、y 轴标签
前面已使用color 美学,则可以在labs() 函数中使用参数color 修改颜色的图例名.
图例位置是在theme 图层通过参数legend. position 设置,可选取值有“none,” “left,” “right,” “bottom,” “top.”
3. 设置坐标轴范围
xlim(), ylim() 函数,设置x 轴和y 轴的范围
4.变换坐标轴
ggplot2 提供的坐标变换函数scale_x_log10() 等是变换坐标系,能够在视觉效果相同的情况下,使用原始数据的坐标刻度
5.设置图形标题
用labs() 函数的参数title, subtitle, caption 设置标题、副标题、脚注标题(默认右下角)
如果想改成顶部居中,需要加theme 图层专门设置
6. 设置fill, color 颜色
数据的某个维度信息可以通过颜色来展示,颜色直接影响图形的美感。
可以直接使用颜色值,但是更建议使用RColorBrewer(调色板)或colorspace 包。
6.1 离散变量
6.2 连续变量
7. 添加文字标注-ggrepel 包
ggrepel 包提供了geom_label_repel() 和geom_text_repel() 函数,为图形添加文字标注。
首先要准备好标记点的数据,然后增加文字标注的图层,需要提供标记点数据,以及要标注的文字给label 美学,若来自数据变量,则需要用映射
library(ggrepel)
best_in_class = mpg %>% # 选取每种车型hwy 值最大的样本
group_by(class) %>%
slice_max(hwy, n = 1)
ggplot(mpg, aes(displ, hwy)) +
geom_point(aes(color = class)) +
geom_label_repel(data = best_in_class, aes(label = model))
若要在图形某坐标位置添加文本注释,则用annotate() 函数,需要提供添加文本的中心坐标位
4 统计变换、坐标系、位置调整
- 统计变换(Statistics):构建新的统计量进而绘图,称为‘‘统计变换’’,简称‘‘统计’’。
ggplot2 中的提供了30 多种‘‘统计’’,均以stat_xxxx() 的方式命名。可以分为两类:
- 可以在几何对象函数geom_*() 中创建,通常直接使用后者即可:
-
不能在几何对象函数geom_*() 中创建
-
例子:
用stat_summary() 做统计汇总并绘图。通过传递函数做统计计算,首先注意x 和y 美学映射到calss 和hwy; fun = mean 是根据x 计算y,故对每个车型计算一个平均的hwy;fun.max, fun.min 同样根据x 分别计算y 的均值加减标准差;统计计算的结果将传递给几何对象参数geom 用于绘图:
ggplot(mpg, aes(x = class, y = hwy)) +
geom_violin(trim = FALSE, alpha = 0.5, color = "green") + # 小提琴图
stat_summary(fun = mean,
fun.min = function(x) {mean(x) - sd(x)},
fun.max = function(x) {mean(x) + sd(x)},
geom = "pointrange", color = "red")
用stat_smooth(), 与geom_smooth() 相同, 添加光滑曲线:
- method: 指定平滑曲线的统计函数,如lm 线性回归, glm 广义线性回归, loess 多项式回归, gam 广义加法模型(mgcv 包) , rlm 稳健回归(MASS 包) 等
- formula: 指定平滑曲线的方程,如y ~ x, y ~ poly(x, 2), y ~ log(x) ,需要与method 参数搭配使用
- se: 设置是否绘制置信区间
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_smooth(method = "lm",
formula = y ~ splines::bs(x, 3),
se = FALSE) # 不绘制置信区间
坐标系(Coordinante)
ggplot2 默认坐标系是直角坐标系coord_cartesian(),常用的坐标系操作还有:
坐标轴翻转,从水平图到竖直图:
ggplot(mpg, aes(class, hwy)) +
geom_boxplot() + # 箱线图
coord_flip() # 从竖直变成水平
直角坐标下的条形图,转化为极坐标下的风玫瑰图:
ggplot(mpg, aes(class, fill = drv)) +
geom_bar() +
coord_polar()
位置调整(Position adjustments)
(1) 条形图中的条形位置调整:
position_stack(): 竖直堆叠
position_fill(): 竖直(百分比) 堆叠,按比例放缩保证总高度为1
position_dodge(), position_dodge2(): 水平堆叠##使用更多
ggplot(mpg, aes(class, fill = drv)) +
geom_bar(position = position_dodge(preserve = "single"))
(2) 散点图中的散点位置调整:
- position_nudge(): 将散点移动固定的偏移量
- position_jitter(): 给每个散点增加一点随机噪声(抖散图)
- position_jitterdodge(): 增加一点随机噪声并躲避组内的点,特别用于箱线图+ 散点图
有时候需要将多个图形排布在画板中,借助patchwork 包更方便。
library(patchwork)
p1 = ggplot(mpg, aes(displ, hwy)) +
geom_point()
p2 = ggplot(mpg, aes(drv, displ)) +
geom_boxplot()
p3 = ggplot(mpg, aes(drv)) +
geom_bar()
p1 | (p2 / p3)
分面、主题、输出
- 1 分面(Facet): 利用分类变量将图形分为若干个‘‘面” (子图),即对数据分组再分别绘图,称为‘‘分面’’。
(1) facet_wrap(): 封装分面,先生成一维的面板系列,再封装到二维中。 - 分面形式:~ 分类变量, ~ 分类变量1 + 分类变量2
- scales 参数设置是否共用坐标刻度,"fixed"(默认, 共用), "free"(不共用),也可以用free_x, free_y 单独设置
- 参数nrow 和ncol 可设置子图的放置方式
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(~ drv, scales = "free")
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_wrap(~ drv + cyl)
(2) facet_grid(): 网格分面,生成二维的面板网格,面板的行与列通过分面变量定义。
- 分面形式:行分类变量~ 列分类变量
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
facet_grid(drv ~ cyl)
-
主题(theme)
你可以为图形选择不同风格的主题(外观),ggplot2 提供了8 套可选主题:
-
使用或修改主题,只需要添加主题图层:
ggplot(mpg, aes(displ, hwy, color = drv)) +
geom_point() +
theme_bw()
更多的主题,还可以用ggthemes 包,其中包含一些顶级期刊专用绘图主题;当然也可以用theme()函数定制自己的主题(略)。
- 3 输出(output)
用ggsave() 函数,将当前图形保存为想要格式的图形文件,如png, pdf 等:
ggsave("my_plot.pdf", width = 8, height = 6, dpi = 300)## 参数width 和height 通常只设置其中一个
ggplot2 图形示例
Nathan Yau 将数据可视化的过程总结为如下的4 个思索:
- 你拥有什么样的数据?
- 你想要表达什么样的数据信息?
- 你会什么样的数据可视化方法?
- 你从图表中能获得什么样的数据信息?
一般的6类:
类别比较图、数据关系图、数据分布图、时间序列图、局部整体图、地理空间图
ggpubr 包提供了很多函数,轻松绘制适合用于期刊论文发表的图形
(1)类别比较图:类别比较图,通常是展示和比较分类变量或分类变量组合的频数
热图:邻接矩阵、混淆矩阵、相关系数矩阵也可以用热图来可视化展示
ComplexHeatmap 包可绘制更复杂的热图:带层次聚类的热图。
(2)数据关系图
主要包括:
数据相关性图:展示两个或多个变量之间的关系,比如散点图、气泡图、曲面图等
-
数据流向图:展示两个或多个状态或情形之间的流动量或关系强度,比如网络图等
网络图:网络图可以可视化实体(个体/事物)间的内部关系,比如社会媒体网络、朋友网络、合作网络、疾病传播网络等。
可视化网络图的包有:igraph, tidygraph + ggraph. 还有更加强大的visNetwork 包。 结点数据,包括id(用于边数据),label(用于图显示),group(设置分组颜色),value(权重,关联结点的大小)等
边数据,包括from(起点),to(终点),label(用于图显示),value(权重,关联边的粗细)等
library(visNetwork)
visNetwork(nodes, edges)
(3) 数据分布图:主要展示数据中数值出现的频率或分布规律,比如直方图、概率密度图、箱线图等
(4)时间序列图:展示数据随时间的变化规律或者趋势。比如,括折线图、面积图等。
折线图与面积图:用geom_line() 与geom_area()绘制
(5)局部整体图:,展示部分与整体的关系。比如,饼图、树状图等
(6)地理空间图:是在地图上展示数据关系,即与地理位置信息联系起来绘图。地理位置通常是用经度、纬度表示。
sf 包实现了将简单要素表示为R 中的data.frame, 以及一系列处理此类数据的工具。
sf 格式数据框中,属性要素是正常的列,几何要素(geometry) 存放为列表列。
(7)动态交互图-ggplotly 包
只要对ggplot2 绘制的图形对象套一个ggplotly() 函数,则图形变成可交互状态:当鼠标移动到图形元素上时,将自动显示对应的数值。
library(plotly)
p = gapminder %>%
filter(year == 2007) %>%
ggplot(aes(gdpPercap, lifeExp, size = pop, color = continent)) +
geom_point() +
theme_bw()
ggplotly(p)
gganimate 包是基于ggplot2 的动态可视化拓展包,让图形元素随时间等逐帧变化起来,可导出为.gif 动图。
library(gganimate)
ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop)) +
geom_point() +
geom_point(aes(color = continent)) +
scale_x_log10() +
labs(title = " 年份: {frame_time}", x = " 人均GDP", y = " 预期寿命") +
transition_time(year)
anim_save("output/gapminder.gif") # 保存为gif 文件