【问题标题】:Scrollbar on Matplotlib showing pageMatplotlib 显示页面上的滚动条
【发布时间】:2017-07-26 02:49:12
【问题描述】:

我想知道是否有办法将滚动条(水平或垂直)放在 matplotlib 显示页面(plt.show)上,该页面包含多个子批次(sublot2grid)。目前,我找到的唯一解决方案是使子图非常小,这根本不是很优雅。

【问题讨论】:

    标签: python python-2.7 matplotlib anaconda


    【解决方案1】:

    因为代码对我来说有点复杂和困惑,所以我将其重构为更具可读性和可重构性,如下所示。我希望这会有所帮助。谢谢!

    import sys
    import random
    import matplotlib
    import matplotlib.pyplot as plt
    
    from PyQt5.QtWidgets import (
                            QWidget,
                            QApplication,
                            QMainWindow,
                            QVBoxLayout,
                            QScrollArea,
                        )
    
    from matplotlib.backends.backend_qt5agg import (
                            FigureCanvasQTAgg as FigCanvas,
                            NavigationToolbar2QT as NabToolbar,
                        )
    
    # Make sure that we are using QT5
    matplotlib.use('Qt5Agg')
    
    # create a figure and some subplots
    FIG, AXES = plt.subplots(ncols=4, nrows=5, figsize=(16,16))
    
    for AX in AXES.flatten():
        random_array = [random.randint(1, 30) for i in range(10)]
        AX.plot(random_array)
    
    def main():
        app = QApplication(sys.argv)
        window = MyApp(FIG)
        sys.exit(app.exec_())
    
    class MyApp(QWidget):
        def __init__(self, fig):
            super().__init__()
            self.title = 'VERTICAL, HORIZONTAL SCROLLABLE WINDOW : HERE!'
            self.posXY = (700, 40)
            self.windowSize = (1200, 800)
            self.fig = fig
            self.initUI()
    
        def initUI(self):
            QMainWindow().setCentralWidget(QWidget())
    
            self.setLayout(QVBoxLayout())
            self.layout().setContentsMargins(0, 0, 0, 0)
            self.layout().setSpacing(0)
    
            canvas = FigCanvas(self.fig)
            canvas.draw()
    
            scroll = QScrollArea(self)
            scroll.setWidget(canvas)
    
            nav = NabToolbar(canvas, self)
            self.layout().addWidget(nav)
            self.layout().addWidget(scroll)
    
            self.show_basic()
    
        def show_basic(self):
            self.setWindowTitle(self.title)
            self.setGeometry(*self.posXY, *self.windowSize)
            self.show()
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      【解决方案2】:

      显示 matplotlib 图的窗口没有添加滚动条的选项。它会自动将自己调整为图形大小。相反,如果调整大小,图形也会调整大小。

      一个选项是构建一个具有此功能的自定义窗口。为此,可以使用 PyQt。下面给出了一个示例,其中没有调用plt.show(),而是调用了一个自定义类,并将要绘制的图形作为参数。图形大小应事先设置为图形fig,并且该自定义类不会更改它。相反,它将图形放入带有滚动条的画布中,以使图形保持其原始大小并且可以在 Qt 窗口中滚动。您不必处理类中的细节,而只需处理脚本末尾的调用。

      此示例适用于 PyQt4,请参阅下面的 PyQt5 示例。

      import matplotlib.pyplot as plt
      from PyQt4 import QtGui
      from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
      from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
      
      class ScrollableWindow(QtGui.QMainWindow):
          def __init__(self, fig):
              self.qapp = QtGui.QApplication([])
      
              QtGui.QMainWindow.__init__(self)
              self.widget = QtGui.QWidget()
              self.setCentralWidget(self.widget)
              self.widget.setLayout(QtGui.QVBoxLayout())
              self.widget.layout().setContentsMargins(0,0,0,0)
              self.widget.layout().setSpacing(0)
      
              self.fig = fig
              self.canvas = FigureCanvas(self.fig)
              self.canvas.draw()
              self.scroll = QtGui.QScrollArea(self.widget)
              self.scroll.setWidget(self.canvas)
      
              self.nav = NavigationToolbar(self.canvas, self.widget)
              self.widget.layout().addWidget(self.nav)
              self.widget.layout().addWidget(self.scroll)
      
              self.show()
              exit(self.qapp.exec_()) 
      
      
      # create a figure and some subplots
      fig, axes = plt.subplots(ncols=4, nrows=5, figsize=(16,16))
      for ax in axes.flatten():
          ax.plot([2,3,5,1])
      
      # pass the figure to the custom window
      a = ScrollableWindow(fig)
      


      这是 PyQt5 的版本。
      import matplotlib
      # Make sure that we are using QT5
      matplotlib.use('Qt5Agg')
      import matplotlib.pyplot as plt
      from PyQt5 import QtWidgets
      from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
      from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
      
      
      class ScrollableWindow(QtWidgets.QMainWindow):
          def __init__(self, fig):
              self.qapp = QtWidgets.QApplication([])
      
              QtWidgets.QMainWindow.__init__(self)
              self.widget = QtWidgets.QWidget()
              self.setCentralWidget(self.widget)
              self.widget.setLayout(QtWidgets.QVBoxLayout())
              self.widget.layout().setContentsMargins(0,0,0,0)
              self.widget.layout().setSpacing(0)
      
              self.fig = fig
              self.canvas = FigureCanvas(self.fig)
              self.canvas.draw()
              self.scroll = QtWidgets.QScrollArea(self.widget)
              self.scroll.setWidget(self.canvas)
      
              self.nav = NavigationToolbar(self.canvas, self.widget)
              self.widget.layout().addWidget(self.nav)
              self.widget.layout().addWidget(self.scroll)
      
              self.show()
              exit(self.qapp.exec_()) 
      
      
      # create a figure and some subplots
      fig, axes = plt.subplots(ncols=4, nrows=5, figsize=(16,16))
      for ax in axes.flatten():
          ax.plot([2,3,5,1])
      
      # pass the figure to the custom window
      a = ScrollableWindow(fig)
      


      虽然此答案显示了一种滚动完整图形的方法,但如果您有兴趣滚动轴的内容,请查看this answer

      【讨论】:

      • 非常感谢,这正是我要找的 ^^
      • 我有一个问题,当我关闭Qt窗口回到Tkinter界面时,应用崩溃了,
      • “回到Tkinter界面”是什么意思?
      • 对不起,我的英语不好,所以,当我关闭 Pyqt 窗口时,我的应用程序崩溃了。 Pyqt 界面上显示的是仪表板,并且有一个 Tkinter 接口调用仪表板,该仪表板应该保持挂起;
      • 例如,如果你在上面的脚本后面加上一个 print("hello world"),你会得到 (Process finished with exit code -1073741819 (0xC0000005))
      猜你喜欢
      • 2011-07-12
      • 2019-02-27
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 2014-11-08
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多