【问题标题】:add scrollbar to preserve figure size in PyQt5 when plotting multiple figures绘制多个图形时添加滚动条以在 PyQt5 中保留图形大小
【发布时间】:2021-08-01 22:26:29
【问题描述】:

我正在尝试在 pyqt5 窗口小部件中绘制多个图形。我能够做到这一点,但如果我在窗口中添加更多图形,图形的大小只会被“压缩”。通过运行下面的代码并单击 Push for Window 1Push for Window 2 来查看比较。

我想在canvas 中添加一个滚动条,这样我就可以保留图形的大小,就像将多个图形放在一个 word 文件中并使用滚动条上下移动来查看图形一样。我该怎么做?

import sys
import pandas as pd
import numpy as np

from PyQt5.QtWidgets import (
    QApplication,
    QLabel,
    QMainWindow,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt

class AnotherWindow1(QWidget):


    def __init__(self):
        super().__init__()
        self.figure = plt.figure(figsize=(45,15))    
        self.canvas = FigureCanvas(self.figure)  
        layout = QVBoxLayout()
        button1 = QPushButton("Plot")
        button1.clicked.connect(self.plot)
        button2 = QPushButton("Back")
        button2.clicked.connect(self.close_window)
        layout.addWidget(button1)
        layout.addWidget(button2)
        layout.addWidget(self.canvas)
        self.setLayout(layout)

    def close_window(self):
        self.close()

    def plot(self):
        self.figure.clear()
        ax1 =  self.figure.add_subplot(111) 
        data = pd.DataFrame(np.random.rand(5))
        data.plot(ax=ax1)
        self.canvas.draw()

class AnotherWindow2(QWidget):


    def __init__(self):
        super().__init__()
        self.figure = plt.figure(figsize=(45,15))    
        self.canvas = FigureCanvas(self.figure)  
        self.canvas2 = FigureCanvas(self.figure) 
        self.canvas3 = FigureCanvas(self.figure)  
        layout = QVBoxLayout()
        button1 = QPushButton("Plot")
        button1.clicked.connect(self.plot)
        button2 = QPushButton("Back")
        button2.clicked.connect(self.close_window)
        layout.addWidget(button1)
        layout.addWidget(button2)
        layout.addWidget(self.canvas)
        layout.addWidget(self.canvas2)
        layout.addWidget(self.canvas3)
        self.setLayout(layout)

    def close_window(self):
        self.close()

    def plot(self):
        self.figure.clear()
        ax1 =  self.figure.add_subplot(111) 
        data = pd.DataFrame(np.random.rand(5))
        data.plot(ax=ax1)
        self.canvas.draw()
        ax2 =  self.figure.add_subplot(111) 
        data = pd.DataFrame(np.random.rand(5))
        data.plot(ax=ax2)
        self.canvas2.draw()
        ax2 =  self.figure.add_subplot(111) 
        data = pd.DataFrame(np.random.rand(5))
        data.plot(ax=ax2)
        self.canvas3.draw()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.window1 = AnotherWindow1()
        self.window2 = AnotherWindow2()

        l = QVBoxLayout()
        button1 = QPushButton("Push for Window 1")
        button1.clicked.connect(self.show_window1)
        l.addWidget(button1)

        button2 = QPushButton("Push for Window 2")
        button2.clicked.connect(self.show_window2)
        l.addWidget(button2)

        w = QWidget()
        w.setLayout(l)
        self.setCentralWidget(w)

    def show_window1(self):
        self.window1.show()

    def show_window2(self):
        self.window2.show()


app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()

【问题讨论】:

    标签: matplotlib plot pyqt5 scrollbar


    【解决方案1】:

    您必须使用包含 QWidget 的 QScrollArea 作为画布的容器

    import sys
    import pandas as pd
    import numpy as np
    
    from PyQt5.QtWidgets import (
        QApplication,
        QLabel,
        QMainWindow,
        QPushButton,
        QScrollArea,
        QVBoxLayout,
        QWidget,
    )
    
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.figure import Figure
    
    
    class AnotherWindow1(QWidget):
        def __init__(self):
            super().__init__()
    
            self.figure = Figure(figsize=(45, 15))
            self.canvas = FigureCanvas(self.figure)
    
            button1 = QPushButton("Plot")
            button1.clicked.connect(self.plot)
            button2 = QPushButton("Back")
            button2.clicked.connect(self.close_window)
    
            layout = QVBoxLayout(self)
            layout.addWidget(button1)
            layout.addWidget(button2)
            layout.addWidget(self.canvas)
    
        def close_window(self):
            self.close()
    
        def plot(self):
            self.figure.clear()
            ax1 = self.figure.add_subplot(111)
            data = pd.DataFrame(np.random.rand(5))
            data.plot(ax=ax1)
            self.canvas.draw()
    
    
    class AnotherWindow2(QWidget):
        def __init__(self):
            super().__init__()
            self.figure = Figure(figsize=(45, 15))
    
            self.canvas = FigureCanvas(self.figure)
            self.canvas.setMinimumSize(640, 480)
            self.canvas2 = FigureCanvas(self.figure)
            self.canvas2.setMinimumSize(640, 480)
            self.canvas3 = FigureCanvas(self.figure)
            self.canvas3.setMinimumSize(640, 480)
    
            canvas_scrollarea = QScrollArea(widgetResizable=True)
            canvas_container = QWidget()
            canvas_scrollarea.setWidget(canvas_container)
            canvas_layout = QVBoxLayout(canvas_container)
            canvas_layout.addWidget(self.canvas)
            canvas_layout.addWidget(self.canvas2)
            canvas_layout.addWidget(self.canvas3)
    
            button1 = QPushButton("Plot")
            button1.clicked.connect(self.plot)
            button2 = QPushButton("Back")
            button2.clicked.connect(self.close_window)
    
            layout = QVBoxLayout(self)
    
            layout.addWidget(button1)
            layout.addWidget(button2)
            layout.addWidget(canvas_scrollarea)
    
        def close_window(self):
            self.close()
    
        def plot(self):
            self.figure.clear()
            ax1 = self.figure.add_subplot(111)
            data = pd.DataFrame(np.random.rand(5))
            data.plot(ax=ax1)
            self.canvas.draw()
            ax2 = self.figure.add_subplot(111)
            data = pd.DataFrame(np.random.rand(5))
            data.plot(ax=ax2)
            self.canvas2.draw()
            ax2 = self.figure.add_subplot(111)
            data = pd.DataFrame(np.random.rand(5))
            data.plot(ax=ax2)
            self.canvas3.draw()
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.window1 = AnotherWindow1()
            self.window2 = AnotherWindow2()
    
            button1 = QPushButton("Push for Window 1")
            button1.clicked.connect(self.show_window1)
    
            button2 = QPushButton("Push for Window 2")
            button2.clicked.connect(self.show_window2)
    
            w = QWidget()
            l = QVBoxLayout(w)
            l.addWidget(button1)
            l.addWidget(button2)
            self.setCentralWidget(w)
    
        def show_window1(self):
            self.window1.show()
    
        def show_window2(self):
            self.window2.show()
    
    
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec()
    

    【讨论】:

    • 谢谢。我认为这是一个非常有用且有效的答案。
    猜你喜欢
    • 2017-01-29
    • 1970-01-01
    • 2021-02-24
    • 2020-07-22
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2020-09-15
    相关资源
    最近更新 更多