How to embed matplotlib.pyplot.colorbar in the PyQt user interface

Viewed 33

I'm new to python, so I need some advice with the project.

There is a window for displaying an image, there is a function for reading and displaying colors on it in the console, there is a function for creating a colorbar based on the received list of colors. Please tell me what needs to be done to output the colorbar to QMainWindow.

This is how it looks now:

enter image description here

So I would like it to look like:

enter image description here

Project code:

import sys
import coordCatch
import matplotlib as mpl

from PIL import Image
from PyQt5 import QtWidgets, QtCore

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from matplotlib.pyplot import *

class graphicsScene(QtWidgets.QGraphicsScene):
    clicked = pyqtSignal()

    def __init__(self, parent=None):

        super(graphicsScene, self).__init__(parent)


class ExampleApp(QtWidgets.QMainWindow, coordCatch.Ui_MainWindow):
    def __init__(self):
        super(ExampleApp, self).__init__()
        self.setupUi(self)
        self.resize(640, 640)  

        self.gscene = graphicsScene()        
        self.graphicsView.setScene(self.gscene)
        self.graphicsView.show()

        pic = 'image.png'
        self.image = QImage(pic)
        pixmap = QGraphicsPixmapItem(QPixmap.fromImage(self.image))
        self.graphicsView.scene().addItem(pixmap)

        self.selection = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, 
                                               self)
#-----Блок обработки изображения и создание списка цветов
        collorsList = []
        imag = Image.open(pic)
        collors = imag.getcolors()
        for cl in collors:
            if cl[0] > 30000:
                collorsList += [self.rgb_to_hex(cl[1])]
        collorsList.sort()
        print(collorsList)
#-------------------------

        self.radioButton.toggled.connect(lambda: self.colourBar(collorsList))

#----- Функция создания colorbar
    def colourBar(self, colLst):
        
        i = 0
        bins = []
        for clr in colLst:
            bins += [i]
            i += 0.5

        cmap = mpl.colors.ListedColormap(colLst)
        norm = mpl.colors.BoundaryNorm(boundaries=bins, 
                                       ncolors=len(cmap.colors)-1 )

        fig, ax = subplots(figsize=(6, 1))
        fig.subplots_adjust(bottom=0.5)
        cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
        norm=norm,
        boundaries= [-.1] + bins + [2.1],
        ticks=bins,
        spacing='uniform',
        orientation='horizontal')
        cb2.set_label('Custom colour bar')
        show()
#-------------

    def rgb_to_hex(self, rgb):
            return '#%02x%02x%02x' % rgb



def main():
    app = QtWidgets.QApplication(sys.argv) 

    window = ExampleApp()
    window.show() 
    app.exec_()  

if __name__ == '__main__': 
    app = QtWidgets.QApplication(sys.argv) 
    main() 

UI code:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow): 
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(642, 491)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 10, 441, 331))
        self.graphicsView.setObjectName("graphicsView")
        self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
        self.radioButton.setGeometry(QtCore.QRect(490, 30, 131, 41))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.radioButton.setFont(font)
        self.radioButton.setObjectName("radioButton")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 390, 441, 80))
        self.widget.setObjectName("widget")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.radioButton.setText(_translate("MainWindow", "Линейка"))

The expected result is displayed in the question itself.

1 Answers

I would create a widget that has a figure and add this widget to my template

Something similar to this should work

class Grapth(QWidget):
    def __init__(self, figure, parent=None, toolbar=True, **kwargs):
        super().__init__(parent)
        self.figure = figure
        self.canvas = FigureCanvas(self.figure)
        layout = QVBoxLayout()
        self.toolbar = NavigationToolbar(self.canvas, self)
        if toolbar:
            layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        self.canvas.draw()
Related