Home > Software design >  QT5 and Matplotlib - set geometry of an embedded graph
QT5 and Matplotlib - set geometry of an embedded graph

Time:05-18

I try to have a little GUI with some buttons and embedded space to plot graphs from data inside the GUI. This is the code:

from PyQt5 import QtCore, QtGui, QtWidgets 
from PyQt5.QtWidgets import QMessageBox, QFileDialog, QMainWindow, QVBoxLayout

import sys
import os
import glob

import numpy as np

import matplotlib
matplotlib.use('Qt5Agg')

import matplotlib.pyplot as plt

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class MplWidget(QtWidgets.QWidget):
    def __init__(self,parent = None, width = 5, height = 4, dpi = 100):
        

        self.fig = Figure(figsize=(width, height), dpi = dpi)
        super().__init__(parent)
        self.canvas = FigureCanvas(self.fig)
        self.toolbar = NavigationToolbar(self.canvas, self)
        
        layout = QtWidgets.QVBoxLayout(self)
        layout.setGeometry(QtCore.QRect(340, 50, 451, 411))
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
                         
        self.ax = self.canvas.figure.add_subplot(111)
        
    def plot_basic_line(self, X, Y, label):
        self.ax.cla() # clears the axis
        self.ax.plot(X, Y, label=label)
        self.ax.grid(True)
        self.ax.legend()
        self.canvas.figure.tight_layout()
        self.canvas.draw()


class Ui_MainWindow(QMainWindow): 
    #def __init__(self):
    def setupUi(self, MainWindow):
        super().__init__()    
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(900, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = QtWidgets.QVBoxLayout(self.centralwidget)       
        self.mpl_canvas = MplWidget(self)
        self.graphicsView.setGeometry(QtCore.QRect(340, 50, 451, 411))
        self.graphicsView.addWidget(self.mpl_canvas)
        
        self.B_Plot = QtWidgets.QPushButton(self.centralwidget)
        self.B_Plot.setGeometry(QtCore.QRect(40, 280, 75, 23))
        self.B_Plot.setObjectName("B_Plot")

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

        self.B_Plot.clicked.connect(self.plot)

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

    def plot(self):
        x = np.linspace(0,10)
        y = np.linspace(0,10)
        self.mpl_canvas.plot_basic_line(x, y, label='plot1')

        

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Right now, the plot assumes the whole space of the main window, and I have no clue how to properly keep it in a confied space in the GUI. The picture below illustrates the problem (I left most buttons out for the example here). I would like to specify the area where my plot is generated on the UI, but right now i have to place everything around the plot...

Embedded plot takes whole window space

CodePudding user response:

All you need is to have some frame laid out in grid (gridded_outer_frame). Inside the grid place another frame (inner_frame). The inner_frame will fit automatically in the gridded_outer_frame.

Then in the code define canvas handler, chart_layout handler for inner_frame and place the canvas in the layout:

chart = MplCanvas(self)
chart_layout = inner_frame # inner frame serves as a target for chart
chart_layout.addWidget(chart)

Result image

  • Related