Matplotlib 导航工具栏重置 legendstyle
Matplotlib navigation toolbar resets legendstyle
目前我正在开发一个小部件,其中包含来自 matplotlib 的绘图。对于我的用例,我自定义了 matplotlib 的默认导航工具栏(请参见下面的代码)。
import os
import sys
import matplotlib; matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.figure import Figure
from matplotlib.lines import Line2D
from PyQt5 import QtCore, QtGui, QtWidgets
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.figure=Figure(figsize=(width, height), dpi=dpi)
super(MplCanvas, self).__init__(self.figure)
def initAxes(self):
self.axes=self.figure.add_subplot(111)
self.axes.get_xaxis().set_minor_locator(matplotlib.ticker.AutoMinorLocator())
self.axes.get_yaxis().set_minor_locator(matplotlib.ticker.AutoMinorLocator())
self.axes.grid(b=True, which='major', color='black', linewidth=1.0)
self.axes.grid(b=True, which='minor', color='black', linewidth=0.25)
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__setupCanvas()
self.__setupWidget()
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
def __setupCanvas(self):
self.canvas=MplCanvas(self, width=5, height=4, dpi=100)
self.canvas.initAxes()
self.canvas.mpl_connect('pick_event', self.remove_graph)
self.toolbar=MyNavigationToolbar(self, self.canvas)
self.toolbar.setIconSize(QtCore.QSize(20, 20))
def __setupWidget(self):
self.resize(500, 500)
self.layout=QtWidgets.QVBoxLayout()
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.toolbar)
self.setLayout(self.layout)
def plot(self, x, y, label):
newLine=Line2D(x, y, label=label)
newLine.set_picker(5)
self.canvas.axes.plot(x, newLine.get_ydata(), label=label, picker=5)
self.__generateLegend()
def __generateLegend(self):
self.canvas.axes.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left", mode="expand", borderaxespad=0, ncol=3)
def remove_graph(self, event):
if self.toolbar.removeGraph:
self.canvas.axes.lines.remove(event.artist)
self.__generateLegend()
self.canvas.draw()
class MyNavigationToolbar(NavigationToolbar2QT):
def __init__(self, parent, canvas):
workingPaht=str(os.getcwd())
self.toolitems=(('Home', 'Reset View', workingPaht+'/Icons/home', 'home'),
('Pan', 'Pan View', workingPaht+'/Icons/pan', 'pan'),
('Zoom', 'Zoom', workingPaht+'/Icons/zoom', 'zoom'),
('Subplots_a', 'Edit View', workingPaht+'/Icons/slider', 'configure_subplots'),
('Subplots_b', 'Edit axis, curve and image parameters', workingPaht+'/Icons/graph', 'edit_parameters'),
('Save', 'sollemnes in futurum', workingPaht+'/Icons/save', 'save_figure'),
('Remove', 'Remove Graph', workingPaht+'/Icons/cut', 'remove_graph'))
NavigationToolbar2QT.__init__(self, canvas, parent)
self._actions['remove_graph'].setCheckable(True)
self.removeGraph=False
def remove_graph(self):
self.__reset_NavigationToolbar2()
self.mode='delete selected graph'
self.set_message(self.mode)
self.removeGraph=True
def __reset_NavigationToolbar2(self):
self._active=None
self._idPress=self.canvas.mpl_disconnect(self._idPress)
self._idRelease=self.canvas.mpl_disconnect(self._idRelease)
self.mode=''
self.canvas.widgetlock.release(self)
self._update_buttons_checked()
def pan(self, *args):
self._actions['remove_graph'].setChecked(False)
super().pan(*args)
def zoom(self, *args):
self._actions['remove_graph'].setChecked(False)
super().zoom(*args)
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
window=MainWindow()
window.plot([0,1,2,3,4], [10,1,20,3,40], 'test_1')
window.plot([0,1,2,3,4], [10,10,10,10,10], 'test_2')
app.exec_()
我的问题是,如果我使用(见图片):导航工具栏-图形选项-(重新)生成图例
我的图例设置/样式已删除。我该如何解决?
在最后一张图片中,您可以看到图例样式已设置为默认样式。
希望你们中的任何人都知道答案。
谢谢。
问题是当您选中“(重新)生成图例”时,代码 运行 会删除您拥有的任何图例,并使用发现的艺术家将其替换为默认图例。
相关代码在
if generate_legend:
draggable = None
ncol = 1
if axes.legend_ is not None:
old_legend = axes.get_legend()
draggable = old_legend._draggable is not None
ncol = old_legend._ncol
new_legend = axes.legend(ncol=ncol)
if new_legend:
new_legend.set_draggable(draggable)
这看起来只从现有图例(列数和是否可拖动)中拉出 一些 状态,而不是您正在使用的其他设置。
我将在 github 上创建一个问题,我认为扩展它以更好地克隆配置是一个很好的第一个问题。
目前我正在开发一个小部件,其中包含来自 matplotlib 的绘图。对于我的用例,我自定义了 matplotlib 的默认导航工具栏(请参见下面的代码)。
import os
import sys
import matplotlib; matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.figure import Figure
from matplotlib.lines import Line2D
from PyQt5 import QtCore, QtGui, QtWidgets
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.figure=Figure(figsize=(width, height), dpi=dpi)
super(MplCanvas, self).__init__(self.figure)
def initAxes(self):
self.axes=self.figure.add_subplot(111)
self.axes.get_xaxis().set_minor_locator(matplotlib.ticker.AutoMinorLocator())
self.axes.get_yaxis().set_minor_locator(matplotlib.ticker.AutoMinorLocator())
self.axes.grid(b=True, which='major', color='black', linewidth=1.0)
self.axes.grid(b=True, which='minor', color='black', linewidth=0.25)
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__setupCanvas()
self.__setupWidget()
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
def __setupCanvas(self):
self.canvas=MplCanvas(self, width=5, height=4, dpi=100)
self.canvas.initAxes()
self.canvas.mpl_connect('pick_event', self.remove_graph)
self.toolbar=MyNavigationToolbar(self, self.canvas)
self.toolbar.setIconSize(QtCore.QSize(20, 20))
def __setupWidget(self):
self.resize(500, 500)
self.layout=QtWidgets.QVBoxLayout()
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.toolbar)
self.setLayout(self.layout)
def plot(self, x, y, label):
newLine=Line2D(x, y, label=label)
newLine.set_picker(5)
self.canvas.axes.plot(x, newLine.get_ydata(), label=label, picker=5)
self.__generateLegend()
def __generateLegend(self):
self.canvas.axes.legend(bbox_to_anchor=(0,1.02,1,0.2), loc="lower left", mode="expand", borderaxespad=0, ncol=3)
def remove_graph(self, event):
if self.toolbar.removeGraph:
self.canvas.axes.lines.remove(event.artist)
self.__generateLegend()
self.canvas.draw()
class MyNavigationToolbar(NavigationToolbar2QT):
def __init__(self, parent, canvas):
workingPaht=str(os.getcwd())
self.toolitems=(('Home', 'Reset View', workingPaht+'/Icons/home', 'home'),
('Pan', 'Pan View', workingPaht+'/Icons/pan', 'pan'),
('Zoom', 'Zoom', workingPaht+'/Icons/zoom', 'zoom'),
('Subplots_a', 'Edit View', workingPaht+'/Icons/slider', 'configure_subplots'),
('Subplots_b', 'Edit axis, curve and image parameters', workingPaht+'/Icons/graph', 'edit_parameters'),
('Save', 'sollemnes in futurum', workingPaht+'/Icons/save', 'save_figure'),
('Remove', 'Remove Graph', workingPaht+'/Icons/cut', 'remove_graph'))
NavigationToolbar2QT.__init__(self, canvas, parent)
self._actions['remove_graph'].setCheckable(True)
self.removeGraph=False
def remove_graph(self):
self.__reset_NavigationToolbar2()
self.mode='delete selected graph'
self.set_message(self.mode)
self.removeGraph=True
def __reset_NavigationToolbar2(self):
self._active=None
self._idPress=self.canvas.mpl_disconnect(self._idPress)
self._idRelease=self.canvas.mpl_disconnect(self._idRelease)
self.mode=''
self.canvas.widgetlock.release(self)
self._update_buttons_checked()
def pan(self, *args):
self._actions['remove_graph'].setChecked(False)
super().pan(*args)
def zoom(self, *args):
self._actions['remove_graph'].setChecked(False)
super().zoom(*args)
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
window=MainWindow()
window.plot([0,1,2,3,4], [10,1,20,3,40], 'test_1')
window.plot([0,1,2,3,4], [10,10,10,10,10], 'test_2')
app.exec_()
我的问题是,如果我使用(见图片):导航工具栏-图形选项-(重新)生成图例
我的图例设置/样式已删除。我该如何解决?
在最后一张图片中,您可以看到图例样式已设置为默认样式。
希望你们中的任何人都知道答案。
谢谢。
问题是当您选中“(重新)生成图例”时,代码 运行 会删除您拥有的任何图例,并使用发现的艺术家将其替换为默认图例。
相关代码在
if generate_legend:
draggable = None
ncol = 1
if axes.legend_ is not None:
old_legend = axes.get_legend()
draggable = old_legend._draggable is not None
ncol = old_legend._ncol
new_legend = axes.legend(ncol=ncol)
if new_legend:
new_legend.set_draggable(draggable)
这看起来只从现有图例(列数和是否可拖动)中拉出 一些 状态,而不是您正在使用的其他设置。
我将在 github 上创建一个问题,我认为扩展它以更好地克隆配置是一个很好的第一个问题。