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)