我创建了一个qt应用程序,可用于在多个选项卡中显示matplotlib图形。现在我正在尝试使用标准的matplotlib导航工具栏来处理各个选项卡中的所有数字。到目前为止,我只是设法让它在其中一个数字中工作,但不是全部。
以下是代码:
from PyQt4 import QtCore
from PyQt4 import QtGui as qt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure
import itertools
class MultiTabNavTool(NavigationToolbar):
#====================================================================================================
def __init__(self, canvases, tabs, parent=None):
self.canvases = canvases
self.tabs = tabs
NavigationToolbar.__init__(self, canvases[0], parent)
#====================================================================================================
def get_canvas(self):
return self.canvases[self.tabs.currentIndex()]
def set_canvas(self, canvas):
self._canvas = canvas
canvas = property(get_canvas, set_canvas)
class MplMultiTab(qt.QMainWindow):
#====================================================================================================
def __init__(self, parent=None, figures=None, labels=None):
qt.QMainWindow.__init__(self, parent)
self.main_frame = qt.QWidget()
self.tabWidget = qt.QTabWidget( self.main_frame )
self.create_tabs( figures, labels )
# Create the navigation toolbar, tied to the canvas
self.mpl_toolbar = MultiTabNavTool(self.canvases, self.tabWidget, self.main_frame)
self.vbox = vbox = qt.QVBoxLayout()
vbox.addWidget(self.mpl_toolbar)
vbox.addWidget(self.tabWidget)
self.main_frame.setLayout(vbox)
self.setCentralWidget(self.main_frame)
#====================================================================================================
def create_tabs(self, figures, labels ):
if labels is None: labels = []
figures = [Figure()] if figures is None else figures #initialise with empty figure in first tab if no figures provided
self.canvases = [self.add_tab(fig, lbl)
for (fig, lbl) in itertools.zip_longest(figures, labels) ]
#====================================================================================================
def add_tab(self, fig=None, name=None):
'''dynamically add tabs with embedded matplotlib canvas with this function.'''
# Create the mpl Figure and FigCanvas objects.
if fig is None:
fig = Figure()
ax = fig.add_subplot(111)
canvas = fig.canvas if fig.canvas else FigureCanvas(fig)
canvas.setParent(self.tabWidget)
canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
#self.tabs.append( tab )
name = 'Tab %i'%(self.tabWidget.count()+1) if name is None else name
self.tabWidget.addTab(canvas, name)
return canvas
基本用法示例如下:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1, 2*np.pi, 100)
figures = []
for i in range(1,3):
fig, ax = plt.subplots()
y = np.sin(np.pi*i*x)+0.1*np.random.randn(100)
ax.plot(x,y)
figures.append( fig )
app = qt.QApplication(sys.argv)
ui = MplMultiTab( figures=figures )
ui.show()
app.exec_()
是否有任何matplotlib忍者可能知道如何让导航工具栏与多个数字画布一起玩?
答案 0 :(得分:4)
我认为您可以为每个画布创建工具栏,并在tabs.currentTab
更改时显示/隐藏它们:
class MultiTabNavTool(qt.QWidget):
def __init__(self, canvases, tabs, parent=None):
qt.QWidget.__init__(self, parent)
self.canvases = canvases
self.tabs = tabs
self.toolbars = [NavigationToolbar(canvas, parent) for canvas in self.canvases]
vbox = qt.QVBoxLayout()
for toolbar in self.toolbars:
vbox.addWidget(toolbar)
self.setLayout(vbox)
self.switch_toolbar()
self.tabs.currentChanged.connect(self.switch_toolbar)
def switch_toolbar(self):
for toolbar in self.toolbars:
toolbar.setVisible(False)
self.toolbars[self.tabs.currentIndex()].setVisible(True)