为啥我不能在 pyqt5 gui 中嵌入的 matplotlib 颜色图中成功绘制感兴趣区域?

Posted

技术标签:

【中文标题】为啥我不能在 pyqt5 gui 中嵌入的 matplotlib 颜色图中成功绘制感兴趣区域?【英文标题】:Why can't I successfully draw the region of interest in a matplotlib color map embedded in a pyqt5 gui?为什么我不能在 pyqt5 gui 中嵌入的 matplotlib 颜色图中成功绘制感兴趣区域? 【发布时间】:2021-07-19 20:16:08 【问题描述】:

我正在尝试在嵌入在 pyqt5 gui 中的颜色图上绘制感兴趣的区域。这是我想要的一个例子。

import sys
from PyQt5.QtWidgets import (QWidget, QPushButton,
                             QHBoxLayout, QVBoxLayout, QApplication)
from PyQt5 import QtCore
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

import ROI_class as roi # ROI_class.py

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()
        self.drawButton.clicked.connect(self.draw_map_Callback)
        self.roiButton.clicked.connect(self.choose_roi)

    def initUI(self):
        self.drawButton = QPushButton("draw map")
        self.roiButton = QPushButton("roi")

        self.hbox = QHBoxLayout()
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.drawButton)
        self.hbox.addWidget(self.roiButton)

        self.vbox = QVBoxLayout()
        self.vbox.addStretch(1)
        self.vbox.addLayout(self.hbox)

        self.setLayout(self.vbox)
        self.setGeometry(500, 500, 500, 500)
        self.setWindowTitle('ROI')
        self.show()
        
    def draw_map_Callback(self):        
        img = np.ones((100, 100)) * range(0, 100)
        fig, ax1 = plt.subplots()
        
        self.con_canvas = FigureCanvas(plt.figure(tight_layout=True))
        self.con_canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.con_canvas.setFocus()
        self.con_toolbar = NavigationToolbar(self.con_canvas, self)
        self.vbox.addWidget(self.con_toolbar)
        self.vbox.addWidget(self.con_canvas)
        self._con_ax = self.con_canvas.figure.subplots()
        self.con_img = self._con_ax.imshow(img, cmap ='jet')
        self._con_ax.set_xlabel('xlabel')
        self._con_ax.set_ylabel('ylabel')
        self.con_cbar = self.con_canvas.figure.colorbar(self.con_img)
        self._con_ax.set_aspect('equal')
        
        
    def choose_roi(self):
        y = roi.new_ROI(self.con_img)

        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

当我点击“绘制地图”时它会绘制一个颜色图。然后我希望它允许我用鼠标绘制感兴趣区域并使用下面此链接上的代码获取蒙版。

https://github.com/martindurant/misc/blob/master/ROI.py

导入的“ROI_class”只是上面链接中代码的复制粘贴。

我可以在 GUI 上成功绘制绘图,但是当我单击“roi”时,它不允许我绘制感兴趣的区域。

当我创建一个新文件并将代码粘贴到上面的链接中时

fig, ax1 = plt.subplots()
s = ax1.imshow(img, cmap ='jet')
ax1.set_xlabel('subcolor')
ax1.set_ylabel('ylabel')
y = new_ROI(s)

在代码的最后,它工作得很好,我能够绘制感兴趣的区域并获得它的掩码。

但是当我尝试在 GUI 中执行此操作时,它不会让我绘制感兴趣的区域。我很困惑为什么这不起作用。

【问题讨论】:

【参考方案1】:

问题在于选择器(变量“y”)是一个局部变量,它会立即被破坏,导致所需的行为无法执行。解决方法是让它成为类的属性:

self.y = roi.new_ROI(self.con_img)

【讨论】:

天哪,它有效!非常感谢!您介意多解释一下为什么不适合使用局部变量吗?我的计划是简单地从“choose_roi 函数”中获取 ROI 的掩码,然后调用 self.掩码或类似的东西,以便我可以在其他功能中处理它。我想我很难理解为什么有一个局部变量甚至不会让函数在它是唯一使用它的地方工作。

以上是关于为啥我不能在 pyqt5 gui 中嵌入的 matplotlib 颜色图中成功绘制感兴趣区域?的主要内容,如果未能解决你的问题,请参考以下文章

当我在 PyQt5 窗口中嵌入 Matplotlib 图形时,为啥有两个重复的轴标签?

Pyqt5--为啥 QApplication.processEvents() 更新 GUI 失败

为啥当我单击提交按钮时,此 PyQt5 发票 GUI 应用程序的“Python 停止工作”? [复制]

从 Matplotlib 图中提取信息并将其显示在 PyQt5 GUI 中

在 PyQT5 窗口中嵌入 VTK 对象

将 Matplotlib 图形嵌入到小部件中 - PyQt5