Search code examples
pythonmatplotlibpyqt5qt-designer

Resizing MatPlotLib chart with QT5 python


I'm trying to make my matplotlib plot fit the size of qt5 widget that it is in. In order to do that I made a resize event handler but I'm not sure how to change matplotlib's already plotted chart. Any suggestions? Here is my code:

# Form implementation generated from reading ui file 'untitled1.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from PyQt5.QtWidgets import QApplication, QWidget


class Canvas(FigureCanvas):
    def __init__(self, parent):

        self.fig, self.ax = plt.subplots(figsize=(4, 4), dpi=100)
        super().__init__(self.fig)
        self.setParent(parent)
        """
        Matplotlib Script
        """
        t = np.arange(0.0, 2.0, 0.01)
        s = 1 + np.sin(2 * np.pi * t)

        self.ax.plot(t, s)

        self.ax.set(xlabel='time (s)', ylabel='voltage (mV)',
                    title='About as simple as it gets, folks')
        self.ax.grid()

        self.ax.plot(t, s+2)

        self.ax.set(xlabel='time (s)', ylabel='voltage (mV)',
                    title='About as simple as it gets, folks')
        self.ax.grid()

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(749, 444)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.MplWidget = QtWidgets.QWidget(self.centralwidget)
        self.chart = Canvas(self.MplWidget)
        self.MplWidget.setGeometry(QtCore.QRect(0, 0, 700, 440))
        self.MplWidget.setObjectName("MplWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 749, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


class Window(QtWidgets.QMainWindow):
    resized = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(Window, self).__init__(parent=parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.resized.connect(self.resizeFunction)

    def resizeEvent(self, event):
        self.resized.emit()
        return super(Window, self).resizeEvent(event)

    def resizeFunction(self):
        self.ui.frame.move(self.width()-171, 0)
        self.ui.MplWidget.setGeometry(0, 0, self.width()-171, self.width()-171)
        # I would like to resize chart here <-----
        print("someFunction")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    screen = app.screens()[0]
    _dpi = screen.physicalDotsPerInch()
    print(_dpi)
    w = Window()
    w.show()
    sys.exit(app.exec_())

Also I have integrated matplotlib into QT5 thanks to this guide: https://learndataanalysis.org/embed-matplotlib-graph-in-a-pyqt5-application/


Solution

  • Replace your resizeFunction function with this code

    def resizeFunction(self):
            # self.ui.MplWidget.setGeometry(0, 0, self.width()-171, self.width()-171)
            self.ui.MplWidget.setGeometry(QtCore.QRect(0, 0, self.width(), self.height()-20))
            self.ui.chart.setGeometry(QtCore.QRect(0, 0, self.width(), self.height()-30))
    
            # I would like to resize chart here <-----
            print("someFunction")
    

    Feel free to replace the '-30' or '-20' with any amount of padding you want.