Matplotlib子图在QLabel中配色异常,如何匹配文件显示效果?
解决Matplotlib子图在QLabel中配色与保存文件不一致的问题
问题原因
核心问题是Matplotlib的RGBA像素顺序和QImage的ARGB32格式通道顺序不匹配:
canvas.buffer_rgba()返回的是RGBA顺序的像素数据- 而你使用的
QImage.Format_ARGB32要求的是ARGB顺序,通道顺序错位直接导致颜色显示异常
解决方案
有两种简单的修复方式,推荐使用第二种更简洁的方案:
方案一:手动转换通道顺序
将Matplotlib输出的RGBA数据调整为ARGB顺序,适配QImage的格式要求:
# 替换原QImage创建代码 buf = canvas.buffer_rgba() argb_buf = np.frombuffer(buf, dtype=np.uint8).reshape((int(height), int(width), 4)) argb_buf = np.roll(argb_buf, 1, axis=2) # 将RGBA转为ARGB img = QImage(argb_buf.tobytes(), int(width), int(height), QImage.Format_ARGB32)
方案二:使用匹配的QImage格式
直接使用与Matplotlib输出匹配的Format_RGBA8888格式,无需通道转换:
# 替换原QImage创建代码 img = QImage(canvas.buffer_rgba(), int(width), int(height), QImage.Format_RGBA8888)
完整修复代码
以下是使用方案二的完整可运行代码:
import sys import numpy as np import matplotlib.pyplot as plt from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel from PyQt5.QtGui import QImage, QPixmap class Window(QMainWindow): def __init__(self): # window design super().__init__() self.setFixedSize(1000, 400) # create QT element self.wid_labelGraph = QLabel(self) self.wid_labelGraph.setStyleSheet("background-color : white;") self.setCentralWidget(self.wid_labelGraph) self.make_graphs() def make_graphs(self): # generate graph heatmaps = [ np.ones((50, 50)), np.zeros((50, 50)), -1 * np.ones((50, 50)) ] fig, axs = plt.subplots(1, 3, figsize = (10, 4)) for i in range(3): im = axs[i].imshow(heatmaps[i], cmap = 'RdBu_r', clim = (-1, 1)) axs[i].set_axis_off() fig.colorbar(im, ax = axs.ravel().tolist()) fig.savefig('temp.png') canvas = FigureCanvas(fig) canvas.draw() width, height = fig.figbbox.width, fig.figbbox.height # 使用匹配的RGBA8888格式 img = QImage(canvas.buffer_rgba(), int(width), int(height), QImage.Format_RGBA8888) self.wid_labelGraph.setPixmap(QPixmap.fromImage(img)) # free memory plt.close() if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() app.exec()
注意事项
- 必须将
width和height转为整数,因为fig.figbbox.width返回的是浮点数,QImage要求传入整数尺寸 - 方案二无需额外数组操作,性能更优,优先推荐使用
内容的提问来源于stack exchange,提问作者Tartempion
相关产品推荐
相关产品推荐

