Issue
I have a matplotlib image embedded in PyQt:
But am now having trouble updating it.
The UI and the initial embedding is set up as follows:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# Ui_MainWindow is a python class converted from .ui file
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
self.imageDisp = ImageDisplay() # Class definition below
layoutImage = self.Image_Area.layout() # Image_Area is a Qt Group Box
if layoutImage is None:
layoutImage = QVBoxLayout(self.Image_Area)
ax_img = self.imageDisp.displayImage()
canvas_image = FigureCanvas(ax_img.figure)
layoutImage.addWidget(canvas_image)
self.NextImageButton.clicked.connect(self.inc)
def inc(self):
self.imageDisp.nextImage()
layoutImage = self.Image_Area.layout()
if layoutImage is None:
layoutImage = QVBoxLayout(self.Image_Area)
ax_img = self.imageDisp.UpdateImage()
canvas_image = FigureCanvas(ax_img.figure)
self.imageDisp.draw()
layoutImage.addWidget(canvas_image)
And the ImageDisplay
class is defined as follows:
class ImageDisplay(FigureCanvas): # FigureCanvas is matplotlib.backends.backend_qt5agg.FigureCanvasQTAgg
def __init__(self):
# Other attributes
fig = Figure()
self.fig = fig
self.axes = fig.add_subplot(111)
def nextImage(self):
# Do something here
self.UpdateImage()
def UpdateImage(self):
self.axes.imshow(np.asarray(IMAGE))
return self.axes
def displayImage(self):
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
self.axes.imshow(np.asarray(IMAGE))
return self.axes
This does not update the image, but addWidget
would create a new widget on top of it, resulting in a stacked plot:
I tried to find ways to remove the widget but to no avail so far. Is there a way I can properly remove this widget and make a new one for the updated image? Or is there another way to display and update an image embedded in PyQt?
Solution
try this instead
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
import sys
import matplotlib
matplotlib.use('Qt5Agg')
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
import numpy as np
from matplotlib import image
import matplotlib.pyplot as plt
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.imageDisp = ImageDisplay(self, width=5, height=4, dpi=100)
self.imageDisp.displayImage()
self.NextImageButton=QtWidgets.QPushButton('next image',self)
self.NextImageButton.clicked.connect(self.inc)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.imageDisp)
layout.addWidget(self.NextImageButton)
widget = QtWidgets.QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.show()
def inc(self):
self.imageDisp.nextImage()
class ImageDisplay(FigureCanvas): # FigureCanvas is matplotlib.backends.backend_qt5agg.FigureCanvasQTAgg
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.start=0
self.files=['ball.png','image.jpg']
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.fig.clear()
self.axes = self.fig.add_subplot(111)
self.axes.clear()
self.axes.axis('off')
plt.draw()
super(ImageDisplay, self).__init__(self.fig)
def nextImage(self):
# Do something here
self.IMAGE = image.imread(self.files[self.start%2])
self.UpdateImage()
def UpdateImage(self):
self.start+=1
self.axes.clear()
self.axes.axis('off')
self.axes.imshow(np.asarray(self.IMAGE))
self.draw()
def displayImage(self):
self.IMAGE = image.imread(self.files[self.start%2])
self.start+=1
self.axes.clear()
self.axes.axis('off')
self.axes.imshow(np.asarray(self.IMAGE))
self.draw()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
Answered By - virxen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.