You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

matplotlib子图标记连通域最大值异常问题求助

问题:Matplotlib 4×4子图散点全部集中在最后一张图

原代码与问题现象

plt.show()

输入图片描述

完整原代码:

CC = []

fig, ax = plt.subplots(4,4,figsize=(8,8))
tau = 130

for n,img in enumerate(ls2):
    sel = img <= tau
    img[sel] = 0
    visited = img==0.0
    i_1 = n % 4
    j_1 = n//4
    if i_1<4 and j_1<4:
        img = ls2[i_1+ax.shape[0]*j_1]
        ax[i_1,j_1].imshow(img,cmap='gray')
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if visited[i,j]:
                continue # 跳过已访问像素
            ## 对于灰度图像,此处应为 img[i,j,0]
            todo = set()
            todo.add((i,j))
            visited[i,j]=True
            # 在(i,j)处添加新的连通分量,初始最大值为0
            CC.append( (i,j,img[i,j]) )
            # 内层循环:遍历邻域
            while len(todo)>0:
                r,c = todo.pop() # 从集合中取出一个元素
                # 计算邻域的有效范围(图像边界)
                rl, rr = max(0,r-1), min(img.shape[0],r+2)
                cl, cr = max(0,c-1), min(img.shape[1],c+2)
                for this_row in range(rl,rr):
                    for this_col in range(cl,cr):
                        if visited[this_row,this_col]:
                            continue
                        todo.add((this_row,this_col))
                        visited[this_row,this_col]=True
                        if img[this_row,this_col]>CC[-1][2]:
                            # 找到新的最大值
                            CC[-1] = (this_row,this_col,img[this_row,this_col])

x = [r for r,c,val in CC]
y = [c for r,c,val in CC]
vals = [val for r,c,val in CC]
plt.scatter(y,x)

plt.show()

用户求助描述

我使用matplotlib创建4×4子图,意图在每张子图的图像中识别连通域的最大值(白色斑点)并标记散点,但所有标记点均集中显示在最后一张子图上。尝试将以下散点绘制代码缩进至循环内部仍未解决问题,恳请帮忙排查:

x = [r for r,c,val in CC]
y = [c for r,c,val in CC]
vals = [val for r,c,val in CC]
plt.scatter(y,x)

问题原因

  1. 未指定子图绘制对象:plt.scatter()默认在当前活动子图绘制,循环中未切换子图上下文,所有点最终都会画到最后一个活动子图。
  2. 全局列表未重置:CC是全局变量,每次循环会累积所有子图的标记点,即使缩进散点代码,也会把之前所有点重复画到当前子图。
  3. 子图索引逻辑混乱:原代码中i_1 = n%4、j_1 = n//4,后续又通过i_1+ax.shape[0]*j_1重新获取图像,导致图像遍历顺序混乱,可能重复处理同一图像。

修正后的代码

fig, ax = plt.subplots(4,4,figsize=(8,8))
tau = 130

for n, img in enumerate(ls2):
    # 每次处理新图像时重置连通分量列表
    CC = []
    # 阈值化处理图像
    sel = img <= tau
    img[sel] = 0
    visited = img == 0.0
    
    # 计算当前子图的行列索引(行优先排列)
    row = n // 4
    col = n % 4
    # 超出4x4范围则跳过
    if row >=4 or col >=4:
        continue
    
    # 获取当前子图对象并显示图像
    current_ax = ax[row, col]
    current_ax.imshow(img, cmap='gray')
    
    # 遍历像素查找连通域最大值
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if visited[i,j]:
                continue
            todo = set()
            todo.add((i,j))
            visited[i,j] = True
            # 初始化当前连通域的最大值点
            max_point = (i,j,img[i,j])
            while len(todo) >0:
                r,c = todo.pop()
                # 计算邻域有效范围
                rl, rr = max(0,r-1), min(img.shape[0], r+2)
                cl, cr = max(0,c-1), min(img.shape[1], c+2)
                for this_row in range(rl, rr):
                    for this_col in range(cl, cr):
                        if visited[this_row, this_col]:
                            continue
                        todo.add((this_row, this_col))
                        visited[this_row, this_col] = True
                        # 更新连通域最大值点
                        if img[this_row, this_col] > max_point[2]:
                            max_point = (this_row, this_col, img[this_row, this_col])
            # 将当前连通域最大值点加入列表
            CC.append(max_point)
    
    # 在当前子图绘制散点,指定颜色方便区分
    x = [r for r,c,val in CC]
    y = [c for r,c,val in CC]
    current_ax.scatter(y, x, color='red', s=20)

# 调整子图间距避免重叠
plt.tight_layout()
plt.show()

修正说明

  • 将CC移至循环内部,每次处理新图像时清空,避免累积历史点。
  • 使用current_ax = ax[row, col]明确指定子图对象,通过current_ax.scatter()将点绘制到对应子图。
  • 修正子图索引逻辑,采用行优先的row = n//4、col = n%4,确保图像与子图一一对应。
  • 优化连通域最大值的存储逻辑,用max_point变量单独记录当前连通域的最大值点,代码更简洁。
  • 添加plt.tight_layout()自动调整子图间距,避免图像重叠。

内容的提问来源于stack exchange,提问作者fogwoodandfig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:37:56