"NavigationToolbar2Tk"对象没有属性"_active"



我收到与此处相同的错误:https://github.com/matplotlib/matplotlib/issues/18148,我无法解决问题。从本质上讲,我正在使用的这个遗留代码在这个 python 文件中使用了很多_active,但简单地将self._active更改为 self.ax.get_navigate_mode() 是行不通的。不仅如此,此处显示的get_navigate_mode()https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.get_navigate_mode.html#matplotlib-axes-axes-get-navigate-mode 仅提供PAN,ZOOM或None 选项,而旧代码还具有SELECT,SELECT2和SELECT3选项。有人有解决方案的想法吗?任何见解都非常感谢。为了完整起见,我已将代码添加到下面的文件中。只需搜索_active,您将看到此项目的 18 个调用。

from __future__ import division
from builtins import range
from past.utils import old_div
import os
import os.path as osp
import matplotlib as mpl
# Python Qt4 bindings for GUI objects
from .tools.qt import QtGui
from .tools.qt import QtCore
from .tools import qt
# import the Qt4Agg FigureCanvas object, that binds Figure to
# Qt4Agg backend. It also inherits from QWidget
from matplotlib.backend_bases import cursors as mplCursors
# Matplotlib Figure object
from matplotlib.figure import Figure
import matplotlib
# care about axes creation kwargs
from distutils.version import StrictVersion
if StrictVersion(matplotlib.__version__) >= StrictVersion("2.0.0"):
axescreationdict = dict(frameon=True, facecolor="w")
else:
axescreationdict = dict(frameon=True, axisbg="w")
if qt.API == "pyqt5":
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
else:
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
try:
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
except ImportError:
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar

class MplCanvas(FigureCanvas):
"""Class to represent the FigureCanvas widget"""
def __init__(self):
self.fig = Figure()
self.fig.set_facecolor("w")
self.image_layout()
# initialization of the canvas
FigureCanvas.__init__(self, self.fig)
# we define the widget as expandable
FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
# notify the system of updated policy
FigureCanvas.updateGeometry(self)
def image_layout(self):
"""prepare the layout for displaying a single pic only
"""
# setup Matplotlib Figure and Axis
self.fig.clf()
# the image
self.ax1 = self.fig.add_axes((0.05, 0.05, 0.75, 0.75), **axescreationdict)
# vertical profile
self.ax2 = self.fig.add_axes((0.05, 0.81, 0.75, 0.16), sharex=self.ax1, **axescreationdict)
for label_i in self.ax2.get_xticklabels():
label_i.set_fontsize(0.0)
label_i.set_visible(False)

# horizontal profile
self.ax3 = self.fig.add_axes((0.81, 0.05, 0.16, 0.75), sharey=self.ax1, **axescreationdict)
for label in self.ax3.get_yticklabels():
label.set_visible(False)
label.set_fontsize(0.0)
# space for the colorbar
self.ax4 = self.fig.add_axes((0.88, 0.84, 0.03, 0.13), **axescreationdict)
for label in self.ax4.get_xticklabels():
label.set_visible(False)
label.set_fontsize(0.0)

class MplWidget(QtGui.QWidget):
"""Widget defined in Qt Designer"""
def __init__(self, parent=None):
# initialization of Qt MainWindow widget
QtGui.QWidget.__init__(self, parent)
# set the canvas to the Matplotlib widget
self.figCanvas = MplCanvas()
# create a vertical box layout
self.vbl = QtGui.QVBoxLayout()
# add mpl widget to vertical box
self.vbl.addWidget(self.figCanvas)
# set the layout to the vertical box
self.setLayout(self.vbl)
# self.mpl_toolbar = NavigationToolbar(self.canvas, self)
self.mpl_toolbar = Toolbar(self.figCanvas, self)
self.vbl.addWidget(self.mpl_toolbar)

class SignalEmitter(QtCore.QObject):
"""This is the Pyside way to define custom signals"""
pickEvent = QtCore.Signal(float, float, float, float)
pickEvent2 = QtCore.Signal(float, float, float, float)
pickEvent3 = QtCore.Signal(float, float)

class Toolbar(NavigationToolbar):
def __init__(self, *args, **kwargs):
super(Toolbar, self).__init__(*args, **kwargs)
print(self.__dict__)
pixmap = QtGui.QPixmap()
thisPath = osp.dirname(__file__)
pixmap.load(osp.join(thisPath, "crosshairs2.svg"))
mplCursors.SELECT_POINT = pixmap
pixmap = QtGui.QPixmap()
pixmap.load(osp.join(thisPath, "crosshairsgreen2.svg"))
mplCursors.SELECT_POINT2 = pixmap
pixmap = QtGui.QPixmap()
pixmap.load(osp.join(thisPath, "crosshairsbluethin.svg"))
mplCursors.SELECT_POINT3 = pixmap
self.sigMan = SignalEmitter()

# Everything below is from the method _init_toolbar method but is since deprecated
#print(os.path.join(mpl.get_data_path(), 'images'))
self.basedirr = os.path.join(mpl.get_data_path(), 'images')
a = self.addAction(self._icon(osp.join(self.basedirr, "home.png")), "Home", self.home)
a.setToolTip("Reset original view")
a = self.addAction(self._icon(osp.join(self.basedirr, "back.png")), "Back", self.back)
a.setToolTip("Back to previous view")
a = self.addAction(
self._icon(osp.join(self.basedirr, "forward.png")), "Forward", self.forward
)
a.setToolTip("Forward to next view")
self.addSeparator()
w = self.addAction(self._icon(osp.join(self.basedirr, "move.png")), "Pan", self.pan)
a.setToolTip("Pan axes with left mouse, zoom with right")
a = self.addAction(
self._icon(osp.join(self.basedirr, "zoom_to_rect.png")), "Zoom", self.zoom
)
a.setToolTip("Zoom to rectangle")
self.addSeparator()
thisPath = osp.dirname(__file__)
a = self.addAction(
QtGui.QIcon(osp.join(thisPath, "crosshairs.png")), "Select", self.selectPointMode
)
a.setToolTip("Select the roi")
a = self.addAction(
QtGui.QIcon(osp.join(thisPath, "crosshairsgreen.png")), "Select2", self.selectPointMode2
)
a.setToolTip("Select the area for normalization")
a = self.addAction(
QtGui.QIcon(osp.join(thisPath, "crosshairsblue.png")), "Select3", self.selectPointMode3
)
a.setToolTip("set a center for cross sections")
# self.addSeparator()
# a = self.addAction(self._icon('subplots.png'), 'Subplots', self.configure_subplots)
# a.setToolTip('Configure subplots')
a = self.addAction(
self._icon(osp.join(self.basedirr, "filesave.png")), "Save", self.save_figure
)
a.setToolTip("Save the figure")
self.buttons = {}
# Add the x,y location widget at the right side of the toolbar
# The stretch factor is 1 which means any resizing of the toolbar
# will resize this label instead of the buttons.
if self.coordinates:
self.locLabel = QtGui.QLabel("", self)
self.locLabel.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
self.locLabel.setSizePolicy(
QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Ignored)
)
labelAction = self.addWidget(self.locLabel)
labelAction.setVisible(True)
# reference holder for subplots_adjust window
self.adj_window = None

# qt5 navbar has this. disable!
def _update_buttons_checked(self):
pass
def mouse_move(self, event):
# print 'mouse_move', event.button
if not event.inaxes or not self._active:
if self._lastCursor != mplCursors.POINTER:
self.set_cursor(mplCursors.POINTER)
self._lastCursor = mplCursors.POINTER
else:
if self._active == "ZOOM":
if self._lastCursor != mplCursors.SELECT_REGION:
self.set_cursor(mplCursors.SELECT_REGION)
self._lastCursor = mplCursors.SELECT_REGION
if self._xypress and self._xypress is not None:
x, y = event.x, event.y
s = self._xypress[0]
if len(s) == 6:
lastx, lasty, a, ind, lim, trans = s
elif len(s) == 5:
lastx, lasty, a, ind, other = s
else:
lastx, lasty = x, y
self.draw_rubberband(event, x, y, lastx, lasty)
elif self._active == "PAN" and self._lastCursor != mplCursors.MOVE:
self.set_cursor(mplCursors.MOVE)
self._lastCursor = mplCursors.MOVE
elif self._active == "SELECT":
if self._lastCursor != mplCursors.SELECT_POINT:
QtGui.QApplication.restoreOverrideCursor()
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(mplCursors.SELECT_POINT))
self._lastCursor = mplCursors.SELECT_POINT
elif self._active == "SELECT2":
if self._lastCursor != mplCursors.SELECT_POINT2:
QtGui.QApplication.restoreOverrideCursor()
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(mplCursors.SELECT_POINT2))
self._lastCursor = mplCursors.SELECT_POINT2
elif self._active == "SELECT3":
if self._lastCursor != mplCursors.SELECT_POINT3:
QtGui.QApplication.restoreOverrideCursor()
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(mplCursors.SELECT_POINT3))
self._lastCursor = mplCursors.SELECT_POINT3
if event.inaxes and event.inaxes.get_navigate():
try:
s = event.inaxes.format_coord(event.xdata, event.ydata)
except ValueError:
pass
except OverflowError:
pass
else:
if len(self.mode):
self.set_message("%s : %s" % (self.mode, s))
else:
self.set_message(s)
else:
self.set_message(self.mode)
def selectPointMode(self, *args):
if self._active == "SELECT":
self._active = None
else:
self._active = "SELECT"
if self._idPress is not None:
self._idPress = self.canvas.mpl_disconnect(self._idPress)
self.mode = ""
if self._idRelease is not None:
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self.mode = ""
if self._active:
self._idRelease = self.canvas.mpl_connect("button_press_event", self.selectPoint)
self.mode = "roi select mode"
self.canvas.widgetlock(self)
else:
self.canvas.widgetlock.release(self)
self.set_message(self.mode)
def selectPoint(self, event):
if event.inaxes and event.inaxes.get_navigate():
self.xdatastart = event.xdata
self.ydatastart = event.ydata
self.xstart = event.x
self.ystart = event.y
self._banddraw = self.canvas.mpl_connect("motion_notify_event", self.drawband)
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self._idRelease = self.canvas.mpl_connect(
"button_release_event", self.selectSecondPoint
)
def selectSecondPoint(self, event):
if event.inaxes and event.inaxes.get_navigate():
self._banddraw = self.canvas.mpl_disconnect(self._banddraw)
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self._idRelease = self.canvas.mpl_connect("button_press_event", self.selectPoint)
self.draw_rubberband(event, 0, 0, 0, 0)
self.sigMan.pickEvent.emit(self.xdatastart, self.ydatastart, event.xdata, event.ydata)
def selectPointMode2(self, *args):
if self._active == "SELECT2":
self._active = None
else:
self._active = "SELECT2"
if self._idPress is not None:
self._idPress = self.canvas.mpl_disconnect(self._idPress)
self.mode = ""
if self._idRelease is not None:
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self.mode = ""
if self._active:
self._idRelease = self.canvas.mpl_connect("button_press_event", self.selectPoint2)
self.mode = "refernce roi select mode"
self.canvas.widgetlock(self)
else:
self.canvas.widgetlock.release(self)
self.set_message(self.mode)
def selectPointMode3(self, *args):
if self._active == "SELECT3":
self._active = None
else:
self._active = "SELECT3"
if self._idPress is not None:
self._idPress = self.canvas.mpl_disconnect(self._idPress)
self.mode = ""
if self._idRelease is not None:
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self.mode = ""
if self._active:
self._idRelease = self.canvas.mpl_connect("button_press_event", self.selectPoint3)
self.mode = "center select mode"
self.canvas.widgetlock(self)
else:
self.canvas.widgetlock.release(self)
self.set_message(self.mode)
def selectPoint2(self, event):
if event.inaxes and event.inaxes.get_navigate():
self.xdatastart = event.xdata
self.ydatastart = event.ydata
self.xstart = event.x
self.ystart = event.y
self._banddraw = self.canvas.mpl_connect("motion_notify_event", self.drawband)
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self._idRelease = self.canvas.mpl_connect(
"button_release_event", self.selectSecondPoint2
)
def selectSecondPoint2(self, event):
if event.inaxes and event.inaxes.get_navigate():
self._banddraw = self.canvas.mpl_disconnect(self._banddraw)
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self._idRelease = self.canvas.mpl_connect("button_press_event", self.selectPoint2)
self.draw_rubberband(event, 0, 0, 0, 0)
self.sigMan.pickEvent2.emit(self.xdatastart, self.ydatastart, event.xdata, event.ydata)
def selectPoint3(self, event):
if event.inaxes and event.inaxes.get_navigate():
self.xdatastart = event.xdata
self.ydatastart = event.ydata
self.xstart = event.x
self.ystart = event.y
# self._banddraw = self.canvas.mpl_connect('motion_notify_event',self.drawband)
#            self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self.sigMan.pickEvent3.emit(event.xdata, event.ydata)
def drawband(self, event):
self.draw_rubberband(event, self.xstart, self.ystart, event.x, event.y)

看起来_active以某种方式被删除了,阅读源代码后,我认为您可以使用 mode.name 代替。

最新更新