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

导 读

我最近从事一个项目,需要在 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.rhkb.cn/news/274753.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp—day02

个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:给自己一个梦想,给世界一个惊喜。 🎅**学习目标: 坚持每一次的学习打卡 文章目录 WXML 和HTML区…

C语言——简易版扫雷

目录 前言 ​编辑 游戏规则 游戏结构的分析 游戏的设计 使用多文件的好处有以下几点: 游戏代码实现 框架(test.c) game函数(test.c) InitBoard初始化(game.c) Print打印棋盘(g…

掘根宝典之C++迭代器简介

在C中,容器是一种用于存储和管理数据的数据结构。C标准库提供了多种容器,每种容器都有其独特的特点和适用场景。 我们知道啊,我们可以通过下标运算符来对容器内的元素进行访问,但是只有少数几种容器才同时支持下标运算符&#xf…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要:在零售行业的技术进步中,开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统,并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法,同时对YOLOv7、YOLOv6、YOLOv5等…

Linux操作系统与Windows文件互传(FTP)

一、开启Ubuntu下的FTP服务 打开Ubuntu的终端窗口,然后执行如下命令来安装 FTP服务。 sudo apt-get install vsftpd等待软件安装完成后,用输入以下命令打开vsftpd.conf文件 sudo vim /etc/vsftpd.conf 找到下图的两个使能语句改成如图即可(记住保存后再…

Beans模块之工厂模块BeanFactoryAware

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

专题二 - 滑动窗口 - leetcode 904. 水果成篮 | 中等难度

leetcode 904. 水果成篮 leetcode 904. 水果成篮 | 中等难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 904. 水果成篮 | 中等难度 1. 题目详情 你正在探访一家农场,农场从左到右种植…

比特币普通地址、隔离见证(兼容)、隔离见证(原生)、Taproot 地址傻傻分不清楚

我们在使用比特币钱包的时候,可以看到各种地址类型:普通地址、隔离见证(兼容)、隔离见证(原生)、Taproot 地址。 看得我们一脸懵逼,为什么会有这么多种类型的地址? 它们之间都有什么…

C语言 指针(4) qsort函数

目录 前言 一、回调函数 二、qsort函数 2.1 使用qsort函数排序整型数据 2.2 使用qsort排序结构数据 三、qsort函数的模拟实现 总结 前言 今天我们主要来学习一下C语言中的qsort排序函数。 一、回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&a…

spring启动时如何自定义日志实现

一、现象 最近在编写传统的springmvc项目时,遇到了一个问题:虽然在项目的web.xml中指定了log4j的日志启动监听器Log4jServletContextListener,且开启了日志写入文件,但是日志文件中只记录业务代码中我们声明了日志记录器的日志&a…

力扣98、530、501-java刷题笔记

一、98. 验证二叉搜索树 - 力扣(LeetCode) 1.1题目 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点…

[leetcode~dfs]1261. 在受污染的二叉树中查找元素

给出一个满足下述规则的二叉树: root.val 0 如果 treeNode.val x 且 treeNode.left ! null,那么 treeNode.left.val 2 * x 1 如果 treeNode.val x 且 treeNode.right ! null,那么 treeNode.right.val 2 * x 2 现在这个二叉树受到「污…

C#四部曲(知识补充)

Unity跨平台原理 .Net相关 只要编写的时候遵循.NET的这些规则,就能在.NET平台下通用 各种源码→根据.NET规范编写→(虚拟机)生成CIL中间码(保存在程序集中)→转成操作系统原代码 跨语言← 跨平台↓ Unity跨平台原理(Mono) c#脚本→MonoC#编…

MySQL 事务的原理以及长事务的预防和处置

transaction_isolation 隔离级别 读未提交 读提交 视图是在每个 SQL 语句开始执行的时候创建的 可重复读 视图是在事务启动时创建的,整个事务存在期间都用这个视图 串行化…

安装OneNote for Win10 | Win10/Win11

前言 PC端的OneNote分为2个版本,分别是Microsoft Store版本和Office版本,Microsoft Store版本即为OneNote for Win10,此版的OneNote有最近笔记功能,但检索功能不如Office版本,个人认为2个版本各有优劣。 但OneNote f…

【硬件基础】电容的选型

1、电容的理论基础 电容器的本质就是储能,充放电 根据作用可分为:滤波电容,旁路电容,耦合电容,退耦电容,自举电容 2、电容的取值 计算取值,查手册,经验取值 3、电容的选取 分为铝…

“删边“的并查集------反向并查集

目录 1.题目2.思路3.代码 默认大家都会并查集了 1.题目 小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢慢变淡的,最终朋友关系就淡忘了。 现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们…

AssetBundle打包与加载

官方文档 参照视频 1.AssetBundle打包 1.1设置资源的命名和后缀 命名只支持小写 1.2创建Editor文件夹,在里面创建编辑器打包AssetBundle的脚本 using UnityEditor; using System.IO;public class CreateAssetBundles {[MenuItem("Assets/Build AssetBun…

旅游景区公共广播 园区广播 公路服务区广播

旅游景区公共广播 园区广播 公路服务区广播 旅游景区公共广播 旅游景区公共广播(又称背景音乐)简称BGM,它的主要作用是掩盖噪声并创造一种轻松和谐的气氛,是一种创造轻松愉快环境气氛的音乐。掩盖环境噪声,创造与旅游景区相适应的气氛&#…

遥感云计算的一个拐点

GeoForge,一个值得关注的遥感大数据应用 简介 GeoForge是由Ageospatial公司开发的一个基于大语言模型(GeoLLMs)的地理空间分析平台。GeoForg的目的是使每个人都可以轻松进行地图绘制和地理空间分析,无论您是外行还是专家。 Geo for ChatGPT 作者团队已…