Matplotlib中的子图:规划绘图的指南和工具

news2024/11/23 22:21:42

导 读

我最近从事一个项目,需要在 matplotlib 中进行一些微调的子图和叠加。虽然我对制作基本的可视化感到很舒服,但我很快发现我对子图系统的理解没有达到标准。于是回到基础知识,并花了一些时间阅读文档并在 Stack Overflow 上搜索相关示例和解释。

当我开始了解 mateplotlib 的子图系统如何工作时,我意识到,如果有UI 工具,可以在其中测试代码并准确查看图中的样子学习起来会容易得多。

于是Github找到了相关的工具。

地址:

Matplotlib Plot Plannericon-default.png?t=N7T8https://qed0711.github.io/plot-planner/

有需要的朋友关注公众号【小Z的科研日常】,获取更多内容

01.add_subplot()

figure.add_subplot() 方法是将现有图形对象划分为不同大小的不同区域的最简单方法之一。

它返回一个轴对象,并接受三个整数。如果这些整数中的每一个都是单个数字,则它们可以简化为单个三位数整数。

例如,.add_subplot(1, 2, 3) 可以简化为 .add_subplot(123)。但这些数字到底意味着什么?

关键是要理解前两个整数定义了图形的划分,最后一个数字实际上说明了子图应该在该划分中的位置。因此,如果将子图定义为 (2,3,1),则意味着将子图分解为 2 x 3 网格,并将新子图放置在该网格的第一个单元格中。

我们工具中尝试一下。将使用 5 个不同大小的子图来制作如下所示的示例。

我们将从标记为ax1(红色)的开始。只要看一下图像,就会发现 ax1 占据了图形区域的左半部分。首先,我们将定义图形并将其设为 8x8 正方形(图形大小是任意的,但对于本例来说效果很好)。然后,忽略所有其他子图,让我们将图形分成左右两部分。

fig = plt.figure(figsize=(8,8))
fig.add_subplot(1, 2, 1)

在这种情况下,这些数字的意思是——将我的图形划分为 1 行和 2 列。最后一个数字表示要使用哪个单元格。

这里奇怪的是,子图的索引从 1 开始,而不是您想象的那样从 0 开始。因此,当我们说使用子图 1 时,我们是在告诉图形进入第一个子图的空间。

这是一个非常简单的情节,但更复杂的情节可能会变得难以记住。这是因为每个子图都是独立的,并且我们不会显示未选择的子图。但这里有一张来自情节规划应用程序的图像,可能会让整个事情变得更加明确。

我发现这个可视化比我看到的任何解释都清晰得多。我们可以看到 1 行和 2 列。然后,以绿色突出显示,我们可以看到索引号为 1 的单元格是我们选择的子图。

可能会认为,既然刚刚将图形分为左右两部分,那么现在唯一的其他选择就是将右半部分留空或在该子图中绘制一些内容。不是这种情况。

我们定义的每个新子图并不关心我们已经制作的任何其他子图。本质上,每个新的子图都会很高兴地准确地到达你告诉它去的地方,无论已经存在什么其他子图。

考虑到这一点,让我们创建ax2子图(蓝色)。再次查看该图像,ax2 似乎占据了该图的右上象限。再次强调,我们将忘记所有其他子图(甚至是我们已经制作的子图),我们将只专注于在右上角制作一个新的子图。

为此,我们要将图形空间分成 4 个象限并选择右上象限。让我们再看一下,看看它是如何工作的。

由此看来,我们想要一个 2x2 网格,并且想要第二个子图。绘图索引首先按行编号,然后按列编号。所以我们的代码是:

fig.add_subplot(2,2,2)

对于ax3(黄色),它看起来大约是 ax2 插槽垂直尺寸的一半,并且出现在它的正下方。基本上,我们正在寻找这个:

这将是 4 行 x 2 列,是第 6 个子图。或者:

fig.add_subplot(4,2,6)

最后两个子图看起来大小相同。在这里看到确切的比例有点困难,所以我只是表达,我们正在寻找 8 行 x 2 列的图形除法。它应该看起来像这样,我们想要为我们的两个新轴获取第 14 和 16 个子图。

fig.add_subplot(8,2,14)
fig.add_subplot(8,2,16)

现在我们的图形应该完全充满了子图。下面是完整的代码,其中添加了一些代码,以使其他一些视觉元素(颜色、标签等)正常工作。

import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_subplot(1, 2, 1, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="red",)
ax2 = fig.add_subplot(2, 2, 2, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="blue")
ax3 = fig.add_subplot(4, 2, 6, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="yellow")
ax4 = fig.add_subplot(8, 2, 14, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="green")
ax5 = fig.add_subplot(8, 2, 16, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="orange")
ax1.text(0.5, 0.5, "ax1", horizontalalignment='center', verticalalignment='center')
ax2.text(0.5, 0.5, "ax2", horizontalalignment='center', verticalalignment='center')
ax3.text(0.5, 0.5, "ax3", horizontalalignment='center', verticalalignment='center')
ax4.text(0.5, 0.5, "ax4", horizontalalignment='center', verticalalignment='center')
ax5.text(0.5, 0.5, "ax5", horizontalalignment='center', verticalalignment='center')
plt.show()

.add_subplot() 方法是一个强大的工具,但它有其局限性。例如,创建的每个子图只能占用一个单元格。

这意味着 .add_subplot() 不可能实现如下所示的操作(尽管它看起来更简单)

这里的问题是红色子图占据了图表左侧的 2/3。不幸的是,.add_subplot() 无法处理选择图形区域的 2/3。

为此,我们可以使用 .subplot2grid()。

02.subplot2grid

与 .add_subplot() 一样,.subplot2grid() 返回一个轴对象,其中包含有关新子图应放置在何处的信息。

它接受两个必需的位置参数:shape 和 loc。

shape 参数作为两个数字的列表或元组传入,其功能类似于 .add_subplot() 方法中的前两个数字。它们指定网格布局,第一个数字是行数,第二个数字是列数。

第二个参数 loc 代表位置,也是两个数字的列表或元组。与 .add_subplot() 不同,不需要通过在网格上指示单个索引来指定放置子图的位置。相反,可以通过指定要放置子图的行号和列号来选择网格索引。同样不同的是, .subplot2grid() 索引从 0 开始。因此 (0,0) 将是第一行和第一个单元格网格的列。

除了这两个参数之外,还有两个可选的关键字参数,rowspancolspan。这就是我们真正发挥 .subplot2grid() 作用的地方。

一旦有了网格布局(形状)和起始索引(loc),就可以使用这两个参数扩展选择以占用更多行或列。默认情况下,rowspan 和 colspan 都设置为 1,这意味着 — 占用 1 行 1 列的单元格。当增加这些数字时,可以告诉轴对象占用当前网格布局中可用的尽可能多的相邻行和列。

让我们仔细看看上面的例子,其中只有 3 个子图。虽然其中一些子图可以(并且可能应该)使用 .add_subplot() 创建,但我们将在此处对所有子图使用 .subplot2grid() 进行练习。

正如我已经说过的红色子图,我们需要它占据总高度的 2/3。那么我们如何使用 .subplot2grid() 来做到这一点呢?除了占据行的三分之二之外,它还绘制在两列的左列中。有了这些信息,我们将网格拆分为 3 行 x 2 列,并将起始索引设置为左上角的单元格。

最后,我们需要告诉子图占据三行中的两行。我们通过将 rowspan 参数设置为 2 来实现这一点。因此,我们的网格和子图应该如下所示。

plt.subplot2grid((3, 2), (0, 0), rowspan=2, colspan=1)

.subplot2grid() 还需要一些更多的东西。但它可以非常精确地设置可视化的空间!

接下来我们将处理蓝色网格框。就像我说的,你可以使用 .add_subplot() (fig.add_subplot(325))来做到这一点。但我们也可以使用 .subplot2grid() 来完成此任务。在我们的 3x2 网格中,我们希望该子图占据左下角的单元格。下面的绘图规划器的图像对此进行了描述。

我们的网格形状是相同的 (3,2)。由于我们只选择一个单元格,因此我们将 rowspan 和 colspan 设置为 1。我们只需要指出正确单元格的 loc 参数即可。方便的是,绘图规划器应用程序中的单元格标有该单元格在网格中的位置(尽管它们并不难找出)。从上图中,我们需要单元格 (2,0),因此我们只需将其插入到我们的 loc 参数中即可。代码将是:

plt.subplot2grid((3, 2), (2, 0), rowspan=1, colspan=1)

对于最后一个子图,我们只需要整个右列。同样,这可以通过 .add_subplot(122) 轻松完成。

我们也可以使用 plt.subplot2grid((3, 2), (0, 1), rowspan=3, colspan=1) 来完成。

我们还可以使用以下代码来完成这个正确的列。这只是为了展示可以做什么,而不是如何解决此问题的实际建议。

plt.subplot2grid((6, 6), (0, 3), rowspan=6, colspan=3)

将所有这些放在一起,我们得到以下内容(我再次添加了一些额外的代码来处理颜色和文本):

fig = plt.figure(figsize=(8,8))
ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=2, colspan=1, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="red",)
ax2 = plt.subplot2grid((3, 2), (2, 0), rowspan=1, colspan=1, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="blue",)
ax3 = plt.subplot2grid((3, 2), (0, 1), rowspan=3, colspan=1, xticklabels=[], yticklabels=[], xticks=[], yticks=[], fc="orange",)
ax1.text(0.5, 0.5, "ax1 \n(rows = 2/3)", horizontalalignment='center', verticalalignment='center')
ax2.text(0.5, 0.5, "ax2", horizontalalignment='center', verticalalignment='center')
ax3.text(0.5, 0.5, "ax3", horizontalalignment='center', verticalalignment='center')
plt.show()

再次得到视觉效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法-前缀和-562. 壁画

题目 思路 被毁掉的墙段一定只与一段还未被毁掉的墙面相邻只能从两头坏,因为如果从中间坏的话,毁掉的墙就和两段未被毁掉的墙面相邻了,画了的墙是坏不了的,只能坏没有画的墙结果为n/2 向上取整,求取总和最大值 代码 T int(inp…

一台GTX1080显卡的怪兽,我可不能错过这个机会!

标题:我花了30块钱买了一台电脑主机。 这个配置能赚钱吗? 1. 收购惊喜 那是一个阳光明媚的下午,我在水管修理店里闲逛。 突然,一位老顾客手里拿着一台旧电脑主机匆匆走了进来。 他说:“小王,你能帮我看看…

【Kimi帮我看论文(四)】TransE:Translating Embeddings for Modeling Multi-relational Data

一、论文信息 1 标题 Translating Embeddings for Modeling Multi-relational Data 2 作者 Antoine Bordes, Nicolas Usunier, Alberto Garcia-Durn, Jason Weston, Oksana Yakhnenko 3 研究机构 Universit de Technologie de Compigne – CNRS Heudiasyc UMR 7253 Compi…

绝地求生:PUBG官方公布2024工作计划

大家好,我是闲游盒。 首先今天官方公布了2024工作计划,下面我们一起来了解一下2024工作重点,官方提到的2点:一是通过对PUBG的维护和优化来改善线上服务的质量,二是为玩家们提供更加多姿多彩的游戏体验。我个人看完了全…

EMQX+InfluxDB+Grafana 构建物联网可视化平台

EMQXInfluxDBGrafana 构建物联网可视化平台 本文以常见物联网使用场景为例,介绍了如何利用 EMQ X MQTT 服务器 InfluxDB Grafana 构建物联网数据可视化平台,将物联网设备上传的时序数据便捷地展现出来。 在物联网项目中接入平台的设备数据和数据存储…

第0章 学习包介绍

一、考试介绍 二、考点分析 白盒测试、黑盒测试、面向对象测试、web测试;下午题考的概率很大; 上午题考点: 三、资料包 四、如何学习

揭秘小红书口碑营销策略,品牌营销总结

口碑营销,是品牌方获得消费者的必修课之一,尤其是在小红书平台上,毕竟小红书是精准消费者扎堆的地方。但是,小红书营销该怎么做才能保证展示率!怎么才能树立品牌方的正面形象,作为品牌方对这个问题还是比较模糊&#x…

【Java设计模式】十七、状态模式

文章目录 1、背景案例2、状态模式3、案例4、总结 1、背景案例 现要按钮控制电梯的四种状态:开门、关门、启动、停止。但每种状态的改变,可能受其他状态影响,如运行状态下,不能进行开门。写个普通实现: 定义电梯接口 …

项目管理系统推荐:打造高效团队协作!教育科技公司管理利器揭秘

教育科技行业是指利用先进的技术手段和教育理论,为教育提供更加高效、便捷、个性化的解决方案。新东方、学而思、高顿都是耳熟能详的教育科技公司。项目管理、团队协作都离不开项目管理系统。适合教育科技公司的项目管理系统,项目管理系统推荐。 常见的项…

BUG:RuntimeError: input.size(-1) must be equal to input_size. Expected 1, got 3

出现的bug为:RuntimeError: input.size(-1) must be equal to input_size. Expected 1, got 3 出现问题的截图: 问题产生原因:题主使用pytorch调用的nn.LSTM里面的input_size和外面的数据维度大小不对。问题代码如下: self.lstm nn.LSTM(input_size, hidden_size, num_laye…

VS 调试Hololens 2工程报错 有未经处理的异常: Microsoft C++ 异常:

原因是unity 少安装了XR工具包 安装完后重新用unity打包,然后vs打开打包出来的工程,电脑和眼镜用usb连接,直接运行调试就可以了

全代码分享|R语言孟德尔随机化怎么做?TwoSampleMR包MR一套标准流程

文章目录 1.前言1.1 成立条件1.2 三大要素1.3 统计原理 2.demo2.1 加载R包2.2 主要MR分析2.3 MR补充分析、多态性、验证 2.4 结果可视化 1.前言 孟德尔随机化(Mendelian randomization,MR)是一种利用基因变异作为工具变量来评估暴露与结果之间因果关系的统计方法。…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的人群密度检测系统(深度学习模型+UI界面+训练数据集)

摘要:开发人群密度检测系统对于公共安全等领域具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个人群密度检测系统,并提供了完整的实现代码。该系统基于强大的YOLOv8算法,并对比了YOLOv7、YOLOv6、YOLOv5,展示了不同模型…

C# RAM Stable Diffusion 提示词反推 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 C# RAM Stable Diffusion 提示词反推 Onnx Demo 介绍 github地址:GitHub - xinyu1205/recognize-anything: Open-source and strong foundation image recognition models. Open-source and strong foundation ima…

Linux系统之ipcalc命令的基本使用

Linux系统之ipcalc命令的基本使用 一、ipcalc命令介绍二、ipcalc命令的使用帮助2.1 ipcalc命令的help帮助信息2.2 ipcalc命令的语法解释 三、ipcalc命令的基本使用3.1 计算子网掩码3.2 计算网络地址3.3 找出所对应的主机名3.4 计算子网详细信息 四、ipcalc命令使用注意事项 一、…

基于SpringBoot+MYSQL的社区团购系统

目录 1、前言介绍 2、主要技术 3、系统流程分析 3.1、注册流程 3.2、登录流程 3.3、购买流程 4、系统设计 4.1、系统结构设计 4.2、系统顺序图 4.2.1、登录模块顺序图 4.2.2、添加信息模块顺序图 4.3、数据库设计 4.3.1、数据库E-R图设计 4.3.2、数据库表设计 5、…

【论文阅读】ACM MM 2023 PatchBackdoor:不修改模型的深度神经网络后门攻击

文章目录 一.论文信息二.论文内容1.摘要2.引言3.作者贡献4.主要图表5.结论 一.论文信息 论文题目: PatchBackdoor: Backdoor Attack against Deep Neural Networks without Model Modification(PatchBackdoor:不修改模型的深度神经网络后门攻击&#xf…

P1765 手机

题目描述&#xff1a; AC代码&#xff1a; #include<iostream> #include<cstring>using namespace std;int main() {string str;getline(cin,str);int cnt 0;for(int i0;i<str.size();i){if(str[i] a || str[i] d || str[i] g || str[i] j || str[i] m…

SA3D:基于 NeRF 的三维场景分割方法

Paper: Cen J, Zhou Z, Fang J, et al. Segment anything in 3d with nerfs[J]. Advances in Neural Information Processing Systems, 2024, 36. Introduction: https://jumpat.github.io/SA3D/ Code: https://github.com/Jumpat/SegmentAnythingin3D SA3D 是一种用于 NeRF 表…

【C#】.net core 6.0 使用第三方日志插件Log4net,日志输出到控制台或者文本文档

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…