在PyQt5中绘制多图时添加滚动条以保留matplotlib图表原始尺寸的咨询
要实现带滚动条的多图表展示,你需要借助QScrollArea控件承载所有画布,同时修正原代码中多画布共用同个figure的问题,完整可运行代码如下:
import sys import pandas as pd import numpy as np from PyQt5.QtWidgets import ( QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QScrollArea # 新增滚动区域控件 ) from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 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__() # 每个画布绑定独立figure,避免内容互相覆盖 self.figure1 = plt.figure(figsize=(45,15)) self.canvas = FigureCanvas(self.figure1) self.figure2 = plt.figure(figsize=(45,15)) self.canvas2 = FigureCanvas(self.figure2) self.figure3 = plt.figure(figsize=(45,15)) self.canvas3 = FigureCanvas(self.figure3) # 外层主布局 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) # 构建滚动区域 scroll_area = QScrollArea() scroll_area.setWidgetResizable(False) # 关闭自动缩放,保留画布原始尺寸 # 滚动区域内部承载所有画布的容器部件 content_widget = QWidget() content_layout = QVBoxLayout(content_widget) # 把所有画布添加到内部容器布局 content_layout.addWidget(self.canvas) content_layout.addWidget(self.canvas2) content_layout.addWidget(self.canvas3) # 绑定容器到滚动区域 scroll_area.setWidget(content_widget) # 滚动区域添加到主布局 layout.addWidget(scroll_area) self.setLayout(layout) def close_window(self): self.close() def plot(self): # 每个独立figure分别绘图 self.figure1.clear() ax1 = self.figure1.add_subplot(111) data = pd.DataFrame(np.random.rand(5)) data.plot(ax=ax1) self.canvas.draw() self.figure2.clear() ax2 = self.figure2.add_subplot(111) data = pd.DataFrame(np.random.rand(5)) data.plot(ax=ax2) self.canvas2.draw() self.figure3.clear() ax3 = self.figure3.add_subplot(111) data = pd.DataFrame(np.random.rand(5)) data.plot(ax=ax3) 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()
核心改动说明
- 新增
QScrollArea作为滚动容器:所有图表画布放在滚动区域内部的子部件中,当画布总高度超出窗口显示范围时自动出现滚动条,不会压缩画布尺寸。 - 每个画布绑定独立figure:原代码中3个画布共用同一个figure会导致绘图内容互相覆盖,修改后每个画布对应独立的figure,完全保留设置的
figsize原始尺寸。 - 布局结构调整:按钮固定在窗口顶部不随滚动条移动,滚动区域占满剩余窗口空间,符合常规使用习惯。
内容的提问来源于stack exchange,提问作者wwj123
相关产品推荐
相关产品推荐

