PyQt集成Matplotlib时使用patchworklib无法显示多图求助
PyQt集成Matplotlib+patchworklib仅显示单个图形的问题解决
开发PyQt项目时,计划用patchworklib合并多个Matplotlib图形,但GUI中始终只显示一个图形。相关代码如下:
import sys from matplotlib.figure import Figure from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas import matplotlib.pyplot as plt import patchworklib as pw class MainWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('Matplotlib in PyQt5 Example') self.setGeometry(100, 100, 800, 600) central_widget = QWidget() self.setCentralWidget(central_widget) # 创建 Matplotlib 的画布 self.canvas = PlotCanvas(self, width=5, height=4) layout = QVBoxLayout(central_widget) layout.addWidget(self.canvas) class PlotCanvas(FigureCanvas): def __init__(self, parent=None, width=5, height=4, dpi=100): # fig, self.ax = plt.subplots(figsize=(width, height), dpi=dpi) # fig = Figure() self.ax1 = pw.Brick() self.ax2 = pw.Brick() ax1 = self.plot(self.ax1) ax2 = self.bar(self.ax2) # Concatenate axes ax12 = ax1 | ax2 fig = ax12.savefig() super().__init__(fig) self.setParent(parent) self.draw() def plot(self, ax_): x = [1, 2, 3, 4, 5] y = [10, 20, 25, 30, 35] ax_.plot(x, y) ax_.set_title('Matplotlib Plot in PyQt5') ax_.set_xlabel('X Label') ax_.set_ylabel('Y Label') return ax_ def bar(self, ax_): categories = ['A', 'B', 'C', 'D', 'E'] values = [7, 10, 15, 5, 9] ax_.bar(categories, values, color='skyblue') ax_.set_title('Matplotlib Bar Chart in PyQt5') ax_.set_xlabel('Categories') ax_.set_ylabel('Values') return ax_ if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
当前效果:
问题原因
代码中使用ax12.savefig()获取Figure是错误的,savefig()方法的作用是将合并后的图形保存为临时图片文件,并返回图片路径,而非返回Matplotlib的Figure对象。把路径传给FigureCanvas会导致无法正确渲染合并后的图形,仅显示单个子图。
解决方案
替换fig = ax12.savefig()为fig = ax12.figure,直接获取合并后的Figure对象,再传给FigureCanvas初始化。
修改后的完整代码
import sys from matplotlib.figure import Figure from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas import matplotlib.pyplot as plt import patchworklib as pw class MainWindow(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('Matplotlib in PyQt5 Example') self.setGeometry(100, 100, 800, 600) central_widget = QWidget() self.setCentralWidget(central_widget) # 创建 Matplotlib 的画布 self.canvas = PlotCanvas(self, width=5, height=4) layout = QVBoxLayout(central_widget) layout.addWidget(self.canvas) class PlotCanvas(FigureCanvas): def __init__(self, parent=None, width=5, height=4, dpi=100): self.ax1 = pw.Brick() self.ax2 = pw.Brick() ax1 = self.plot(self.ax1) ax2 = self.bar(self.ax2) # Concatenate axes ax12 = ax1 | ax2 # 获取合并后的Figure对象,替代savefig() fig = ax12.figure super().__init__(fig) self.setParent(parent) self.draw() def plot(self, ax_): x = [1, 2, 3, 4, 5] y = [10, 20, 25, 30, 35] ax_.plot(x, y) ax_.set_title('Matplotlib Plot in PyQt5') ax_.set_xlabel('X Label') ax_.set_ylabel('Y Label') return ax_ def bar(self, ax_): categories = ['A', 'B', 'C', 'D', 'E'] values = [7, 10, 15, 5, 9] ax_.bar(categories, values, color='skyblue') ax_.set_title('Matplotlib Bar Chart in PyQt5') ax_.set_xlabel('Categories') ax_.set_ylabel('Values') return ax_ if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
修改后,两个图形会在PyQt的GUI中并排正常显示。
内容的提问来源于stack exchange,提问作者Dong Zhang
相关产品推荐
相关产品推荐

