Home > Software engineering >  Matplotlib subplot on QLabel gives different colormap
Matplotlib subplot on QLabel gives different colormap

Time:02-03

When I draw a Matplotlib subplot on a QLabel, I get a different colormap than when I save it to file. How can I show the real colormap with QT? For example, in my code below, the image on disk has the good red-blue colormap, but the QT one is a blue-dark orange one. I tried other QImage formats but no good so far.

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
        img = QImage(canvas.buffer_rgba(), width, height, QImage.Format_ARGB32)
        self.wid_labelGraph.setPixmap(QPixmap(img))

        # free memory
        plt.close()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec()

CodePudding user response:

The format is wrong.
You're using Format_ARGB32:

The image is stored using a 32-bit ARGB format (0xAARRGGBB).

But, as the function name buffer_rgba() suggests, the format is rgba, so Format_RGBA8888:

The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8). Unlike ARGB32 this is a byte-ordered format, which means the 32bit encoding differs between big endian and little endian architectures, being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA.

You got the wrong colors because the bits referring to the components are shifted: the red was interpreted as alpha, the green as red, the blue as green, and the alpha as blue.

  • Related