Mathplotlib chart not working in PyQt5 GUI without layouts
I'm making small python app for myself, but I've been stuck for days.
So I have simple non-resizeable GUI (PyQt5) and there is a live matplotlib chart inside a QVBoxLayout. I would like to remove this last layout and declare my gui layout free, but once I do, the chart disappears. Any help or advice is appreciated.
Here is a greatly shortened (working) version of my code:
Code:
import sys
from random import randrange
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtCore
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from threading import Thread
from PyQt5 import QtTest
xdata = []
ydata = []
def background_task():
while True:
global xdata
global ydata
cp = randrange(10)
ct = randrange(10)
if len(xdata) > 21:
xdata = xdata[-21:]
ydata = ydata[-21:]
else:
pass
xdata.append(str(cp))
ydata.append(str(ct))
QtTest.QTest.qWait(1000)
bg = Thread(target=background_task, daemon = True)
bg.start()
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=7, height=3, dpi=80):
fig = plt.figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setFixedSize(600, 400)
self.canvas = MplCanvas(self, dpi=80)
self.
canvas.
setFixedSize(QSize(600,
250)) self.update_plot()
self.timer.setInterval(1000)
self.timer.timeout.connect(self.update_plot)
self.timer.start()
self.setCentralWidget(central_widget)
layout.addWidget(self.canvas)
def update_plot(self):
self.canvas.axes.cla()
self.canvas.axes.plot(xdata, ydata, 'r')
plt.xticks(rotation = 45)
plt.tight_layout()
every_nth = 3
for n, label in enumerate(plt.gca().xaxis.get_ticklabels()):
if n % every_nth != 0:
label.set_visible(False)
plt.tight_layout()
self.canvas.draw()
window = MainWindow()
window.show()
sys.exit(app.exec_())
Re: Mathplotlib chart not working in PyQt5 GUI without layouts
This post was initially marked as "Moderated", which made it invisible to Qt Centre members. I have removed that status.
Quote:
the chart disappears
Well, probably not really, The widget containing the plot is probably created with zero size. When you place it in a layout for the main window's central widget, the layout will resize the widget along with the main window. Without the layout, there is nothing to cause the widget to resize when the main window does.
The solution is to add a resizeEvent override for the main window. In that event, you set the size of the central widget to match the size passed in.
Re: Mathplotlib chart not working in PyQt5 GUI without layouts
Thank you for the reply.
How would you go about using the resizeEvent, tried googling it, but no matter what I try I get errors or just simply nothing happens. I'm sure it's not that complicated but I'm new to PyQt or Python for that matter. :(
Re: Mathplotlib chart not working in PyQt5 GUI without layouts
I am not PyQt expert, but you would add the event handler to your MainWindow class, something like this:
Code:
def resizeEvent(self, event):
# Resize the main widget
self.centralWidget.resize(event.size())
I don't know what type of object MplCanvas is. If it is a QWidget, then you may be able to replace the QWidget you now are setting as the central widget with the MplCanvas instance itself.
Re: Mathplotlib chart not working in PyQt5 GUI without layouts
I've managed to make it work, the solution was super simple: self.setCentralWidget(self.canvas)
Now my next problem is, I can't move this widget. For example self.canvas.move(50 ,50) does nothing. Do you have any suggestion for this?
Re: Mathplotlib chart not working in PyQt5 GUI without layouts
The whole point of the QMainWindow and the central widget is that the main window takes charge of whatever is inside it. And if you use layouts, then the layout is in charge of sizing and positioning the widgets inside it.