Python之使用Matplotlib绘图小记——使用迭代器形式的子图对象

Python之使用Matplotlib绘图小记——使用迭代器形式的子图对象

原始文档:https://www.yuque.com/lart/ppqg89/wst35d

前言

在使用 opencv 构建计算机视觉程序的时候,常会使用 matplotlib 来可视化中间的结果。因为直接为每一个中间结果进行一次单独的输出并不现实,因为如果窗口积累多了,关起来非常麻烦,最好的还是使用子图的形式,每个输出作为一个子图。

创建子图

fig, axes = plt.subplots(ncols=4, nrows=2)

子图索引的坑

实际操作中,这里会涉及到对于子图的索引。matplotlib 本身对子图的索引是按照行列来区分的。当然,这里有个坑,那就是如果使用一行或者一列,那就应该使用一维索引就行,而若涉及到多行多列,那就是二维索引了。

fig, axes = plt.subplots(nrows=1, ncols=1)
print(type(axes), axes)
fig, axes = plt.subplots(nrows=2, ncols=1)
print(type(axes), axes.shape)
fig, axes = plt.subplots(nrows=1, ncols=2)
print(type(axes), axes.shape)
fig, axes = plt.subplots(nrows=2, ncols=2)
print(type(axes), axes.shape)

"""
<class 'matplotlib.axes._subplots.AxesSubplot'> AxesSubplot(0.125,0.11;0.775x0.77)
<class 'numpy.ndarray'> (2,)
<class 'numpy.ndarray'> (2,)
<class 'numpy.ndarray'> (2, 2)
"""

更方便的形式——迭代器

如果代码流程本身是确定的,那么直接使用固定递增的序号来索引子图自然是最直接和直观的,但是如果代码前后顺序随时可能会调整或者中间可能会插入额外的操作和可视化的时候,就不太方便了。这个时候,其实最适合使用迭代器来处理。每次按照顺序“弹出”一个对象,并不需要指定索引。

考虑到 fig, axes = plt.subplots(...) 返回的 axes 是一个 ndarray 对象,我们直接将其展平成一维后使用内建方法 iter() 构建迭代器就可以很好的应对这个问题。直接对构建的迭代器对象使用 next() 函数就可以获得一个新的 axis 对象,且同时可以保证前后的 axis 对象对应的子图序号是按照行主序与整体子图一一对应的。由此可以得到以下代码:

axis = next(axes)
axis.set_title(title)
axis.imshow(image, cmap="gray", vmin=0, vmax=255)

这里要注意 cmap 的设定,因为 matplotlib 默认的 cmap 并不是灰度图的形式所以为了正常展示灰度图,我们需要重新设定其为 gray

更简洁的形式——包装成独立函数

甚至我们可以进一步简化调用的方式,将其包装成一个函数。由于其中需要用到一个共享的 axes,这里可以使用全局变量或者参数的形式进行传递。

python 中仅支持共享传参(指函数的各个形式参数获得实参中各个引用的副本,也就是说,函数内部的形参是实参的别名)。对于这里传入的迭代器,每次 next 都是在修改同一个对象的内部状态,也可以将迭代器看作是一个可变对象:

def imshow_on_axis(image, title, axes):
    axis = next(axes)
    axis.set_title(title)
    axis.imshow(image, cmap="gray", vmin=0, vmax=255)

其他参考

关于 python 的可变对象与不可变对象可以简单看看下面这篇文章。虽然细节可能有所欠缺,但是胜在介绍的比较丰富:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值