Как встроить matplotlib.colorbar в пользовательский интерфейс PyQt5
Есть окно для вывода изображения, есть функция считывания и вывода в консоли цветов на нем, есть функция создания colorbar на основе полученного списка цветов.
Подскажите, пожалуйста, что нужно сделать, чтобы вывести colorbar на QMainWindow.
Так это выглядит сейчас:
Так хотелось бы, что бы выглядело:
main.py:
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()
coordCatch.py:
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", "Линейка"))
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Как вариант.
Обратите внимание, что я изменил некоторые строки, для того чтобы ваш пример заработал с моим изображением.
import sys
from PIL import Image
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
import matplotlib as mpl
from matplotlib.pyplot import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
# from coordCatch import Ui_MainWindow
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", "Линейка"))
class GraphicsScene(QtWidgets.QGraphicsScene):
clicked = pyqtSignal()
def __init__(self, parent=None):
super(GraphicsScene, self).__init__(parent)
class ExampleApp(QtWidgets.QMainWindow, 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()
# -----------> vvvvvv <-----------------------------------------------------------------
pic = 'Ok.png' # '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()
collors = imag.getcolors(333) # +++
# -----------------------------> ^^^ <-------------------------------------------
for cl in collors:
if cl[0] > 300: # 30000:
# -------------------> ^^^ <------------------------------------------------------
collorsList += [self.rgb_to_hex(cl[1])]
collorsList.sort()
print(collorsList)
#-------------------------
self.radioButton.toggled.connect(lambda: self.colourBar(collorsList))
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.fig, self.ax = subplots(figsize=(6, 1))
self.fig.subplots_adjust(bottom=0.5)
self.plotWidget = FigureCanvas(self.fig)
self.layout = QtWidgets.QGridLayout(self.centralwidget)
self.layout.addWidget(self.graphicsView, 0, 0)
self.layout.addWidget(self.radioButton, 0, 1, 2, 1, alignment=Qt.AlignTop)
self.layout.addWidget(self.plotWidget, 1, 0)
self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self))
self.layout.setRowStretch(0, 3)
self.layout.setRowStretch(1, 1)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#----- Функция создания 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)
self.cb2 = mpl.colorbar.ColorbarBase(
# ax,
self.ax, # +++
cmap=cmap,
norm=norm,
boundaries=[-.1] + bins + [2.1],
ticks=bins,
spacing='uniform',
orientation='horizontal'
)
self.cb2.set_label('Custom colour bar')
self.plotWidget.draw() # +++
def rgb_to_hex(self, rgb):
# return '#%02x%02x%02x' % rgb
return '#%02x%02x%02x%02x' % rgb # +++
# -------------------------> ^^^^ <-----------------------------------------------------
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = ExampleApp()
window.show()
sys.exit(app.exec_())




