I'm new to PyQt and pyqtgraph and have a heatplot, which I'd like to place on a widget (if that's the right term), adjacent to which a slider will eventually appear. The code I have thus far, which is a modification of something I've shamelessly copied from an online tutorial, is as follows:
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, mkQApp
from PyQt5.QtWidgets import QHBoxLayout
from pyqtgraph.Qt import QtGui, QtCore
pg.setConfigOption('background', 'lightgray')
pg.setConfigOption('foreground','black')
font = QtGui.QFont("Times", 18)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
layout = QHBoxLayout()
graph_widget = pg.GraphicsLayoutWidget(show=True)
self.setCentralWidget(graph_widget)
self.setWindowTitle('pyqtgraph example: heatmap display')
self.setStyleSheet("background-color: lightgray;")
self.resize(1000,1000)
#layout.addWidget(graph_widget) # Where my error occurs
self.show()
corrMatrix = np.array([
[ 1. , 0.5184571 , -0.70188642],
[ 0.5184571 , 1. , -0.86094096],
[-0.70188642, -0.86094096, 1. ]
])
columns = ["A", "B", "C"]
pg.setConfigOption('imageAxisOrder', 'row-major')
correlogram = pg.ImageItem()
tr = QtGui.QTransform().translate(-0.5, -0.5)
correlogram.setTransform(tr)
correlogram.setImage(corrMatrix)
plotItem = graph_widget.addPlot()
plotItem.invertY(True)
plotItem.setDefaultPadding(0.0)
plotItem.addItem(correlogram)
plotItem.showAxes( True, showValues=(True, True, False, False), size=40 )
ticks = [ (idx, label) for idx, label in enumerate( columns ) ]
for side in ('left','top','right','bottom'):
plotItem.getAxis(side).setTicks( (ticks, []) )
plotItem.getAxis(side).setTickFont(font)
plotItem.getAxis('bottom').setHeight(10)
colorMap = pg.colormap.get("CET-D1")
bar = pg.ColorBarItem( interactive=False,values=(0,1), colorMap=colorMap)
bar.setImageItem(correlogram, insert_in=plotItem)
mkQApp("Correlation matrix display")
main_window = MainWindow()
if __name__ == '__main__':
pg.exec()
The result is shown below:
Eventually I would like to place the above in a layout, in which a row contains my plot, a slider (and a few other widgets). A TypeError message results when I un-comment the line layout.addWidget(graph_widget)
. The message states
TypeError: addWidget(self, QWidget, stretch: int = 0, alignment: Union[Qt.Alignment,
Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type
'GraphicsLayoutWidget'
Is it not possible to place a GraphicsLayoutWidget
on a QHBoxLayout()
? If so, what's the correct way to organize things so I have my graph adjacent to which I can place sliders, line edits, etc.
One issue is that you are setting your graph_widget
as the central widget for your QMainWindow
instance and then later adding it to a layout with the intention of adding more widgets.
I think you are more likely to achieve the results you are looking for if you set a generic QWidget
as the window's central widget, set a layout, and then add the graph_widget
and any other widgets to the layout.
Here is an example using your code and the solution from @musicmante in the comments, and adding a vertical slider:
from PyQt5.QtWidgets import QHBoxLayout, QWidget, QSlider # Import PyQt5 first before pyqtgraph
from pyqtgraph.Qt import QtWidgets, mkQApp
import pyqtgraph as pg
import numpy as np
from pyqtgraph.Qt import QtGui, QtCore
pg.setConfigOption('background', 'lightgray')
pg.setConfigOption('foreground','black')
font = QtGui.QFont("Times", 18)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.central = QWidget() # create a QWidget
slider = QSlider(orientation=QtCore.Qt.Vertical) # Vertical Slider
graph_widget = pg.GraphicsLayoutWidget(show=True)
self.setWindowTitle('pyqtgraph example: heatmap display')
self.setStyleSheet("background-color: lightgray;")
self.resize(1000,1000)
self.setCentralWidget(self.central) # set the QWidget as centralWidget
layout = QHBoxLayout(self.central) # assign layout to central widget
layout.addWidget(graph_widget) # No More error
layout.addWidget(slider) # add a slider
self.show()
corrMatrix = np.array([
[ 1. , 0.5184571 , -0.70188642],
[ 0.5184571 , 1. , -0.86094096],
[-0.70188642, -0.86094096, 1. ]
])
columns = ["A", "B", "C"]
pg.setConfigOption('imageAxisOrder', 'row-major')
correlogram = pg.ImageItem()
tr = QtGui.QTransform().translate(-0.5, -0.5)
correlogram.setTransform(tr)
correlogram.setImage(corrMatrix)
plotItem = graph_widget.addPlot()
plotItem.invertY(True)
plotItem.setDefaultPadding(0.0)
plotItem.addItem(correlogram)
plotItem.showAxes( True, showValues=(True, True, False, False), size=40 )
ticks = [ (idx, label) for idx, label in enumerate( columns ) ]
for side in ('left','top','right','bottom'):
plotItem.getAxis(side).setTicks( (ticks, []) )
plotItem.getAxis(side).setTickFont(font)
plotItem.getAxis('bottom').setHeight(10)
colorMap = pg.colormap.get("CET-D1")
bar = pg.ColorBarItem( interactive=False,values=(0,1), colorMap=colorMap)
bar.setImageItem(correlogram, insert_in=plotItem)
mkQApp("Correlation matrix display")
main_window = MainWindow()
if __name__ == '__main__':
pg.exec()