首页 > 其他分享 >Matplotlib中的子图:规划绘图的指南和工具

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

时间:2024-03-13 17:33:41浏览次数:22  
标签:指南 subplot center subplot2grid 0.5 子图 Matplotlib add 绘图

导 读

我最近从事一个项目,需要在 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()

再次得到视觉效果:

标签:指南,subplot,center,subplot2grid,0.5,子图,Matplotlib,add,绘图
From: https://blog.csdn.net/weixin_46287760/article/details/136671579

相关文章

  • 洛谷题单指南-二叉树-P4715 【深基16.例1】淘汰赛
    原题链接:https://www.luogu.com.cn/problem/P4715题意解读:计算亚军得主,注意能力值最高的肯定是冠军,但能力值第二高的不一定是亚军,因为有可能中途就遭遇冠军。解题思路:根据题意,两两比赛,一轮后再按顺序两两比赛,形如一棵二叉树,但解题其实用不到二叉树的数据结构可以看出,最后参与......
  • 如何恢复丢失未保存的 Word 文档指南
    在广阔的数字领域,对丢失未保存的Word文档的恐惧对于用户来说是再熟悉不过的焦虑了。本指南旨在对用户可能发现自己迫切需要恢复未保存文档的各种场景进行详尽的探索。无论是由于保存失败、意外的系统崩溃还是令人心碎的意外删除,请放心,我们都会为您提供详细的见解和可行的解决......
  • 【3月13日-云服务器推荐】京东云新上1年福利机型 阿里云活动页大改 选购指南 最新价格
     本文纯原创,侵权必究 《最新对比表》已更新在文章头部—腾讯云文档,文章具有时效性,请以腾讯文档为准!【腾讯文档实时更新】云服务器1分钟教会你如何选择教程https://docs.qq.com/document/DV0RCS0lGeHdMTFFV?tab=000003视频解读最新活动:【云服务器推荐】价格对比!阿里云......
  • GitHub推荐使用指南
    GitHub是什么?做代码仓库,代码托管的仓库,类似功能的还有CSDN、GitLab等使用步骤创建账号创建仓库第一步第二步将本地代码推送到远程仓库gitbranch-Mmain表示将主线命名为main实际使用提交直接执行以下即可推送master分支gitremoteaddoriginhttps://github.com/G......
  • 洛谷题单指南-线性表-P2234 [HNOI2002] 营业额统计
    原题链接:https://www.luogu.com.cn/problem/P2234题意解读:要计算每一天最小波动值的和,需要对每一天求最小波动值,再求和,如果暴力法,时间复杂度在1+2+3+......+32767≈5*10^8,可能会超时。解题思路:1、暴力法:由于本题测试数据比较水,实测暴力求解直接可以AC,由于没有技术含量,不做具体......
  • Git推荐使用指南
    Git是什么?分布式版本控制的软件软件:安装到电脑上的工具版本控制:文件拷贝:论文->版本通过文件来控制,多个文件,不同的标注来确定各个阶段的版本本地版本控制:只有一个文件,但是通过本地控制软件可以追溯以前的所有版本(类似游戏存档),相比文件拷贝,视觉上不会存在多个文件过......
  • WPF绘图指南:用XAML轻松实现圆、线、矩形、文字、图片创意元素
     概述:在WPF中,通过使用不同的元素如Ellipse、Line、Rectangle等,可以轻松绘制各种图形,包括圆、线条、椭圆、矩形、多边形等。同时,通过TextBlock展示文字,Image展示图片,以及Path创建路径和曲线,使得图形的绘制变得灵活多样。通过简单的XAML代码,开发者可以快速构建各种图形和界面元......
  • 洛谷题单指南-线性表-P4387 【深基15.习9】验证栈序列
    原题链接:https://www.luogu.com.cn/problem/P4387题意解读:判断一组序列入栈后,出栈序列的合法性。解题思路:数据长度100000,直接模拟堆栈的入栈和出栈即可遍历每一个入栈元素,依次入栈,每一个元素入栈后,比较栈顶元素和出栈序列第一个,如果相等,则出栈,持续进行比较、出栈直到不相等......
  • SQL中如何添加数据:基础指南
    简介在数据库管理系统中,添加数据是一项常见的任务。无论是向现有表中添加新行,还是创建新表并插入数据,都需要使用SQL(StructuredQueryLanguage)语句来执行。本文将介绍SQL中如何添加数据的基本方法,以及一些常用的技巧和最佳实践。向现有表中添加数据要向现有的表中添加新数据,可......
  • 深入理解 ELK 中 Logstash 的底层原理 + 填坑指南
    深入理解ELK中Logstash的底层原理+填坑指南<imgsrc="https://pic4.zhimg.com/v2-3afecd9bcad8087524ef7db1f8f51abf_b.jpg"data-rawwidth="722"data-caption=""data-size="normal"data-rawheight="500"class="origi......