1

I want to display greyscale images with pyqt5 GUI and update the image display continuously, but the matplotlib creates a new colorbar every time updating the display.

Below are the codes.

from PyQt5.QtWidgets import*

from matplotlib.backends.backend_qt5agg import FigureCanvas

from matplotlib.figure import Figure

class MplWidget(QWidget):
    
    def __init__(self, parent = None):

        QWidget.__init__(self, parent)
        
        self.canvas = FigureCanvas(Figure())
        
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.canvas)
        
        self.canvas.axes = self.canvas.figure.add_subplot(111)
        self.setLayout(vertical_layout)

from PyQt5.QtWidgets import*
from PyQt5.uic import loadUi

from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)
import numpy as np
import random
     
class MatplotlibWidget(QMainWindow):
    
    def __init__(self):
        
        QMainWindow.__init__(self)

        loadUi("display_test.ui",self)

        self.pushButton_2.clicked.connect(self.update)
        self.addToolBar(NavigationToolbar(self.MplWidget.canvas, self))

        data = np.random.rand(512, 512)
        self.MplWidget.canvas.axes.clear()
        self.d = self.MplWidget.canvas.axes.imshow(data, cmap="gray", norm=None)#, vmin=-1.2, vmax=1.2, interpolation='none')
        self.MplWidget.canvas.figure.colorbar(self.d)
        self.MplWidget.canvas.draw()
        
    def update(self):
        data = np.random.randint(0,1024,(512,512))
        self.MplWidget.canvas.axes.clear()
        self.d = self.MplWidget.canvas.axes.imshow(data, cmap="gray", norm=None)
        self.MplWidget.canvas.figure.colorbar(self.d)
        self.MplWidget.canvas.draw()
        
app = QApplication([])
window = MatplotlibWidget()
window.show()
app.exec_()

If no self.MplWidget.canvas.axes.clear() in the update function, then the image display scale doesn't change when updating and the high-value images will look saturated, all white.

If I don't add self.MplWidget.canvas.figure.colorbar(self.d) in the update function, then the colorbar just stay unchanged.

The image shows the problem. enter image description here

3
  • self.MplWidget.canvas.figure.colorbar(self.d) returns the colorbar instance. So you could remove it before adding a new one if you keep a pointer to it. Or maybe there's a colorbar method that updates the existing instance when the data changes, such as update_normal()? Commented Aug 12, 2020 at 5:35
  • 2
    You need to explicitly create an ax for the colorbar and use that every time. Something like self.MplWidget.canvas.figure.colorbar(self.d, cax=my_cbar_ax). Default, if no cax is given, matplotlib "removes" space from the main ax and adds a new ax for the colorbar. Commented Aug 12, 2020 at 13:58
  • @JohanC Adding an ax works. Thanks! Commented Aug 26, 2020 at 19:04

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.