Results 1 to 6 of 6

Thread: Mathplotlib chart not working in PyQt5 GUI without layouts

  1. #1
    Join Date
    Feb 2021
    Posts
    4
    Thanks
    4

    Default 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:

    Qt Code:
    1. import sys
    2. from random import randrange
    3. from PyQt5.QtWidgets import *
    4. from PyQt5.QtGui import *
    5. from PyQt5.QtCore import *
    6. from PyQt5 import QtCore
    7. import matplotlib
    8. import matplotlib.pyplot as plt
    9. from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    10. from matplotlib.figure import Figure
    11. from threading import Thread
    12. from PyQt5 import QtTest
    13.  
    14. xdata = []
    15. ydata = []
    16.  
    17. def background_task():
    18. while True:
    19. global xdata
    20. global ydata
    21.  
    22. cp = randrange(10)
    23. ct = randrange(10)
    24.  
    25. if len(xdata) > 21:
    26. xdata = xdata[-21:]
    27. ydata = ydata[-21:]
    28. else:
    29. pass
    30.  
    31. xdata.append(str(cp))
    32. ydata.append(str(ct))
    33.  
    34. QtTest.QTest.qWait(1000)
    35.  
    36.  
    37. bg = Thread(target=background_task, daemon = True)
    38. bg.start()
    39.  
    40. class MplCanvas(FigureCanvas):
    41.  
    42. def __init__(self, parent=None, width=7, height=3, dpi=80):
    43. fig = plt.figure(figsize=(width, height), dpi=dpi)
    44. self.axes = fig.add_subplot(111)
    45. super(MplCanvas, self).__init__(fig)
    46.  
    47.  
    48. class MainWindow(QMainWindow):
    49.  
    50. def __init__(self, *args, **kwargs):
    51. super(MainWindow, self).__init__(*args, **kwargs)
    52. self.setFixedSize(600, 400)
    53.  
    54. self.canvas = MplCanvas(self, dpi=80)
    55. self.canvas.setFixedSize(QSize(600, 250))
    56. self.update_plot()
    57. self.timer = QtCore.QTimer()
    58. self.timer.setInterval(1000)
    59. self.timer.timeout.connect(self.update_plot)
    60. self.timer.start()
    61.  
    62. central_widget = QWidget()
    63. self.setCentralWidget(central_widget)
    64.  
    65. layout = QVBoxLayout(central_widget)
    66. layout.addWidget(self.canvas)
    67.  
    68. def update_plot(self):
    69. self.canvas.axes.cla()
    70. self.canvas.axes.plot(xdata, ydata, 'r')
    71. plt.xticks(rotation = 45)
    72. plt.tight_layout()
    73. every_nth = 3
    74. for n, label in enumerate(plt.gca().xaxis.get_ticklabels()):
    75. if n % every_nth != 0:
    76. label.set_visible(False)
    77. plt.tight_layout()
    78. self.canvas.draw()
    79.  
    80.  
    81. app = QApplication(sys.argv)
    82. window = MainWindow()
    83. window.show()
    84. sys.exit(app.exec_())
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default 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.

    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.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    kiskivancsi (5th February 2021)

  4. #3
    Join Date
    Feb 2021
    Posts
    4
    Thanks
    4

    Default 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.

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default 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:

    Qt Code:
    1. def resizeEvent(self, event):
    2. # Resize the main widget
    3. self.centralWidget.resize(event.size())
    4. QMainWindow.resizeEvent(self, event)
    To copy to clipboard, switch view to plain text mode 

    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.
    Last edited by d_stranz; 5th February 2021 at 20:07.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. The following user says thank you to d_stranz for this useful post:

    kiskivancsi (5th February 2021)

  7. #5
    Join Date
    Feb 2021
    Posts
    4
    Thanks
    4

    Default 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?

  8. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default 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.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. The following user says thank you to d_stranz for this useful post:

    kiskivancsi (7th February 2021)

Similar Threads

  1. PyQt5 code not working
    By tchachkii in forum Newbie
    Replies: 1
    Last Post: 5th December 2018, 17:06
  2. PyQt5 chart
    By ecce in forum Newbie
    Replies: 2
    Last Post: 24th April 2016, 15:06
  3. text wrapword not working in Layouts
    By joko in forum Qt Quick
    Replies: 0
    Last Post: 16th November 2015, 19:09
  4. Layouts
    By Dumbledore in forum Qt Tools
    Replies: 1
    Last Post: 14th October 2007, 02:01
  5. Layouts - Name cant be set
    By manivannan_1984 in forum Qt Programming
    Replies: 1
    Last Post: 14th September 2006, 19:38

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.