ggplot2的组图拓展包(1):patchwork(上篇)
专注系列化、高质量的R语言教程
推文索引 | 联系小编 | 付费合集
patchwork是ggplot绘图系统的拓展包,主要功能是将多个ggplot格式的图形组合成一幅大图,即组图。
patchwork工具包十分好用,它主要利用几个类似四则运算符号的操作符进行组图,只要掌握每个操作符的功能特点及少量函数的用法,就可以很灵活地进行组图。
本篇目录如下:
0 示例图形
1 竖杠`|`和斜杠`/`
1.1 单独运算
1.2 混合运算
2 加号`+`
2.1 单独运算
2.2 plot_layout函数(上)
3.3 混合运算
3 减号`-`
3.1 单独运算
3.2 混合运算
0 示例图形
首先,参考官方文档[1],生成如下4个ggplot对象:
library(ggplot2)
p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp*100)) + ggtitle('Plot 1')p2 <- ggplot(mtcars) + geom_point(aes(mpg, wt)) + ggtitle('Plot 2')p3 <- ggplot(mtcars) + geom_point(aes(hp, wt, colour = mpg)) + ggtitle('Plot 3')p4 <- ggplot(mtcars) + geom_bar(aes(gear)) + facet_wrap(~cyl) + ggtitle('Plot 4')1 竖杠|和斜杠/
patchwork工具包最基础的操作符应当是加号+,这也是继承ggplot2工具包的符号,不过竖杠|和斜杠/的功能相对单纯,因此首先加以介绍。
在R语言的基础语法中,竖杠|表示逻辑“或”,斜杠/ 表示“除法”,但在这里它们被赋予了另外的功能:竖杠|表示横向组图,斜杠/表示纵向组图。
1.1 单独运算
分别使用|和/进行组图:
library(patchwork)
p1 | p2 | p3
p1 / p2 / p3
通过观察组图结果,可以发现一个特点:这两个操作符会为每个图形的plot region平均分配空间。
在推文graphics | 基础绘图系统(二)—— 绘图参数及par函数中,学堂君介绍了基础绘图系统的图形共存在4个区域,这里再展示一下:

但在默认情况下,device region、display region的边界会与figure region重叠,也就是外侧三个区域实际上是重合的,因此图形区域主要存在plot region和figure region的区别。
明白几个区域的概念,现在再来分析组图结果:
p1的纵坐标刻度标签较其他图更长,但它的plot region仍和其他两幅图仍然一致;因为纵坐标刻度标签位于figure region内而不位于plot region,因此它的figure region较p2更宽;同样,
p3在figure region中包含一个图例,这也使得它的figure region较p2更宽。
综上,可以得出结论:|和/操作符会平均分配各子图的plot region,而figure region内的要素则会额外分配空间。
此外,这两个操作符在组图时还严格贯彻“对齐”的审美观,尤以/更加明显,可以看到:
在横向组图中,子图的plot region上、下边框是对齐的;在纵向组图中,尽管纵坐标刻度标签不一致以及部分子图存在图例,子图的plot region左、右边框也是对齐的;
在纵向组图中,尽管纵坐标刻度标签的宽度不一致,但纵坐标变量名标签也严格对齐,刻度标签较窄的子图在与变量名标签之间还留出一部分空间。
那么如果参与组图的子图本身就包含子图,它们会如何分配空间呢?看如下例子:
p1 | p2 | p4
p1 / p2 / p4
从组图结果可以看出,子图的子图是作为一个整体来参与平均分配plot region的。这就涉及到嵌套水平(nesting level)的概念了。以上例来说,p1、p2是与p4处于同一嵌套水平,而不是与它的子图处于同一嵌套水平。
1.2 混合运算
|和/可以混合使用以实现更复杂的组图,那么它们运算的优先级是怎样的呢?
先看如下三个例子:
p1 | p2 / p3
p1 / p2 | p3
p1 / p2 | p3 / p4
从组图结果可以明显看出,/的优先级高于|。
此外,从嵌套水平的角度看,当只使用上述操作符的其中一个时,所有参与组图的子图都位于同一个嵌套水平;而当混合使用这两个操作符时,优先级高的操作符会先产生一个嵌套水平,其结果整体再与其他操作符产生一个更高的嵌套水平。
2 加号+
2.1 单独运算
从排列方向上看,加号+的功能不是那么纯粹。在默认情况下,它会根据参与组图的图形数量决定布局:
p1 + p2
p1 + p2 + p3
p1 + p2 + p3 + p4
2.2 plot_layout函数(上)
plot_layout()函数可以对组图的布局做进一步的调整。
调整行、列数:
p1 + p2 + p3 +plot_layout(ncol = 2) p1 + p2 + p3 +plot_layout(nrow = 2)
调整排列方向的优先顺序:
p1 + p2 + p3 +plot_layout(ncol = 2, byrow = F)
调整各列子图的plot region的宽度比例:
p1 + p2 + p3 +plot_layout(ncol = 2, widths = c(1.5,1))
调整各行子图的plot region的高度比例:
p1 + p2 + p3 +plot_layout(ncol = 2, heights = c(1, 1.5))
plot_layout()函数的其他功能会在后文进一步介绍。
3.3 混合运算
加号+与竖杠|和斜杠/混合运算时,优先级是怎样的呢?
先看+与|的优先级比较:
p1 + p2 | p3
p1 | p2 + p3
显然,+的优先级高于|。
再看+与/的优先级比较:
p1 + p2 / p3
显然,+的优先级低于/。
综上,三个操作符的优先级顺序为/ > + > |。
3 减号-
3.1 单独运算
按照工具包作者的说法,与其将-看作是减号,还不如看作是连字符。从排列方向上看,它也是横向进行组图的,但与|和+存在区别。
区别主要体现在嵌套水平的产生上。其实不管是|、/,还是+,单独使用它们中的一个,都会将所有子图置于同一嵌套水平,而-每使用一次都会产生一个嵌套水平。
看如下两个例子:
p1 - p2
p1 - p2 - p3
可以看出,在连续使用两次-时,首先会将p1和p2在同一嵌套水平上横向组图,然后再将组图结果作为整体与p3在同一嵌套水平上进行横向组图。当连续使用-时,从左往右各子图的宽度比就会是:
3.2 混合运算
在混合运算时,-的优先级和+是一致的。从左往右,谁先出现就先使用谁。
p1 + p2 - p3
先计算
p1 + p2,再作为整体与p3横向组合。
p1 - p2 + p3
这里显示
+的功能很特殊。尽管先计算了p1 - p2,但p3仍然与它们处于同一嵌套水平。
-的优先级低于/:
p1 - p2 / p3
-的优先级高于|:
p1 | p2 - p3
p1 - p2 | p3
注意与
p1 - p2 + p3的结果作比较。
综上,三个操作符的优先级顺序为/ > + = - > |。
未完待续。
参考资料
[1]
patchwork: Getting Started: https://mirrors.tuna.tsinghua.edu.cn/CRAN/web/packages/patchwork/vignettes/patchwork.html
相关文章:
ggplot2的组图拓展包(1):patchwork(上篇)
专注系列化、高质量的R语言教程推文索引 | 联系小编 | 付费合集patchwork是ggplot绘图系统的拓展包,主要功能是将多个ggplot格式的图形组合成一幅大图,即组图。patchwork工具包十分好用,它主要利用几个类似四则运算符号的操作符进行组图&…...
Python 异步: 异步迭代器(15)
动动发财的小手,点个赞吧! 迭代是 Python 中的基本操作。我们可以迭代列表、字符串和所有其他结构。 Asyncio 允许我们开发异步迭代器。我们可以通过定义一个实现 aiter() 和 anext() 方法的对象来在 asyncio 程序中创建和使用异步迭代器。 1. 什么是异步…...
HD-G2L-IOT V2.0核心板MPU压力测试
1. 测试对象HD-G2L-IOT基于HD-G2L-CORE V2.0工业级核心板设计,双路千兆网口、双路CAN-bus、2路RS-232、2路RS-485、DSI、LCD、4G/5G、WiFi、CSI摄像头接口等,接口丰富,适用于工业现场应用需求,亦方便用户评估核心板及CPU的性能。H…...
scikit-image:遥感图像geotiff格式转mat格式
scikit-imagescikit-image 是一个专门用于图像处理的 Python 库,它可以与 Scipy 库和其他可能有助于计算的 Python 库一起使用。Github地址:https://github.com/scikit-image/scikit-image Star有5.3k首先pip安装scikit-image包,或者直接使用…...
吉利银河L7、长城哈弗B07、比亚迪宋Plus DM-i,自主品牌决战混动
2月23日,吉利推出全新的中高端新能源产品序列——吉利银河。当日,吉利推出了首款智能电混SUV「银河L7」,新车将在二季度交付。本月10日,长城汽车也计划举办智能新能源干货大会,其「颠覆技术」等宣传直面新一代的新能源…...
附录3:说一说 Ambari 视图编译相关
一、Ambari View Ambari 视图,即 Ambari Views 。其实 Ambari 视图并不是很好用,所以大部分人很自然地就把 Ambari 视图给忽略了,心里会冒出一句:“还有这东西?”。然而作为 Ambari 的一部分,今天还是要讲一下,万一有人追求 Ambari 完整性,要编译并安装汉化他们呢? …...
Arduino双色LED实验记录
接线图片:双色LED实物和布线有区别:代码:int RED_LED 11; //设置红色为11 int GREEN_LED 10; //设置绿色为10 int val 0;//全局变量val void setup() {// put your setup code here, to run once:pinMode(RED_LED,OUTPUT);//引脚配置pinMo…...
flex布局
十分简单灵活,区区几行代码都可以实现各种页面的布局,曾经学习页面布局时候,深受float、display、position这些属性的困扰,但是学习flex布局,只需要学习几个CSS属性,就可以写出简介优雅复杂的页面布局。 F…...
【操作系统原理实验】命令解释器模拟实现
选择一种高级语言如C/C等,编写一类似于DOS、UNIX中的命令行解释程序。 1)设计系统命名行提示符; 2)自定义命令集(8-10个); 3)用户输入help命令以查找命令的帮助; 4)列出命令的功能,区分内部命令…...
使用nvm管理node版本
下载nvm版本参考文章:https://blog.csdn.net/langmanboy/article/details/126357952下载安装选择nvm的目录为d:\nvm,nodejs的目录为d:\nodejs:v14.0.0:执行nvm install 14生成的目录v16.0.0:执行nvm install 16生成的目…...
jQuery BootStrap
1、jQuery的使用方式 1、下载jQuery库文件 网址 2、将下载好的js文件放到项目中,并引入到需要的HTML文件中 3、使用jQuery 注意:jQuery库文件的导入必须在自己写的代码之前。就绪函数在页面上可以写n个。 <!DOCTYPE html> <html lang"en…...
Vue2.0开发之——购物车案例-Footer组件封装(50)
一 概述 导入Footer子组件定义fullState计算属性把全选状态传递给Footer子组件实现全选功能 二 导入Footer子组件 2.1 App.vue中导入Footer组件 import Footer from "/components/Footer/Footer.vue";2.2 App.vue中注册Footer子组件 components: {Header,Goods,F…...
HTML基本概述
文章目录网站和网页浏览器的作用HTML标签元素注释乱码问题web系统是以网站形式呈现的,而前端是以网页形式呈现的。 网站和网页 网站(web site):互联网上用于展示特定内容的相关网页的集合。也就是说,一个网站包含多个…...
Vue 3.0 响应式 计算和侦听 【Vue3 从零开始】
本节使用单文件组件语法作为代码示例 #计算值 有时我们需要依赖于其他状态的状态——在 Vue 中,这是用组件计算属性处理的,以直接创建计算值,我们可以使用 computed 方法:它接受 getter 函数并为 getter 返回的值返回一个不可变的…...
1.mbedtls移植到STM32
mbedtls学习笔记 1.关于mbedtls2.STM32移植方法2.1STM32cubemx移植2.2手动移植12.3移植总结2.4手动移植22.4.1移植方式22.4.2测试SHA1加密1.关于mbedtls 1.主要提供了的 SSL/TLS 支持(在传输层对网络进行加密),各种加密算法,各种哈希算法,随机数生成以及 X.509(密码学里…...
模块、包和异常
目录1.模块import 导入from...import 导入2. 模块的搜索顺序3. __name__属性的使用4. 包包的使用步骤5. 发布模块6. 安装模块7. 卸载模块8. pip 安装第三方模块9. 异常处理异常捕获异常的传递抛出 raise 异常1.模块 模块是 Python 程序架构的一个核心概念 每一个以扩展名 py …...
RocketMQ控制台的安装与启动
RocketMQ控制台的安装与启动下载修改配置开放端口号重启防火墙添加依赖编译 rocketmq-dashboard运行 rocketmq-dashboard本地访问rocketmq无法发送消息失败问题。connect to <公网ip:10911> failed下载 下载地址 修改配置 修改其src/main/resources中…...
pytorch安装的超级详细教程(没有之一)
一、发展历程 (简单介绍) (15年)caffe --> (16年)tensorflow1.x --> (17年)keras --> (18年)Tensorflow2.x --> (19年)pytorch。 面向gihub开源项目编程。 向下支持比较好,各个版本之间支持比较好,兼容性强。 版本…...
leetcode两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...
断点调试(debug)
目录 F8案例 编辑 debug过程中报错 编辑用debug查看方法源码 一层一层查看 Arrays.sort()方法 F9 DebugExercise 介绍:断点调试是指在程序的某一行设置一个断电,调试时,程序运行到这一行就会停住,然后可以一步步往下调试…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
