I have been looking for a working example how to embed a matplotlib plot in pyside that is created with the QT designer while keeping the logic in a separate file. I know that there are numerous examples on the web but none of them actually uses the QT designer and then creates a separate file to add the logic where the matplitlib plot is added to a widget. I found an example that 'almost' works http://blog.rcnelson.com/building-a-matplotlib-gui-with-qt-designer-part-1/ but but in my version it's not possible to "Change the layoutName property from “verticalLayout” to “mplvl”".
So I have the following specific questions: I'm not clear into what item that plot can be embedded to in Pyside Qt designer. Is it a simple "widget" (as there is no matplotlib widget available in pyside). If so, how can I then add the plot to that widget? Or do I have to create a 'FigureCanvas' with Qt Designer? Is this possible at all? If so, how?
Here is the simplest possible design I can make with the Pyside Qt designer in embedding a widget (is this correct?). How can I now add a matplotlib plot on top of it?
As suggested in one of the answers I have now promoted the Qwidget to MyStaticMplCanvas and edited the name of Qwidget to mplvl.
Automatically generated file with Pyside Qt designer and compiled with pyside-uic ui.ui -o ui.py -x
ui.py looks like this:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'gui.ui'
#
# Created: Wed Apr 20 14:00:02 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2
#
# WARNING! All changes made in this file will be lost!
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(444, 530)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.mplvl = MyStaticMplCanvas(self.centralwidget)
self.mplvl.setGeometry(QtCore.QRect(120, 190, 221, 161))
self.mplvl.setObjectName("mplvl")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 444, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
from mystaticmplcanvas import MyStaticMplCanvas
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
how can I now add a plot into the mplvl object from a separate .py file?
PySide2 Tutorial — Creating applications with Qt Designer The good news is that Qt comes with a graphical editor — Qt Designer — which contains a drag-and-drop UI editor. Using Qt Designer you can define your UIs visually and then simply hook up the application logic later.
matplotlib: For plotting, pyqtgraph is not nearly as complete/mature as matplotlib, but runs much faster. Matplotlib is more aimed toward making publication-quality graphics, whereas pyqtgraph is intended for use in data acquisition and analysis applications.
Simple Qt application embedding Matplotlib canvases. This program will work equally well using any Qt binding (PyQt6, PySide6, PyQt5, PySide2). The binding can be selected by setting the QT_API environment variable to the binding name, or by first importing it.
PySide2 is the official Python module from the Qt for Python project, which provides access to the complete Qt 5.12+ framework. The Qt for Python project is developed in the open, with all facilities you'd expect from any modern OSS project such as all code in a git repository and an open design process.
I'm not an expert on that matter so it might not be the cleanest way of doing this, but here is some working code to get you started:
QxxxxLayout
Plotter
inherit from FigureCanvas
matplotlib
to work with PySide
ui.py:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(533, 497)
self.mplvl = QtGui.QWidget(Form)
self.mplvl.setGeometry(QtCore.QRect(150, 150, 251, 231))
self.mplvl.setObjectName("mplvl")
self.vLayout = QtGui.QVBoxLayout()
self.mplvl.setLayout(self.vLayout)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
For this you just have to add the canvas to mplvl
in QtDesigner
main.py:
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide'
from matplotlib.backends.backend_qt4agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from PySide import QtGui, QtCore
import random
from weakref import proxy
from ui import Ui_Form
class Plotter(FigureCanvas):
def __init__(self, parent):
''' plot some random stuff '''
self.parent = proxy(parent)
# random data
data = [random.random() for i in range(10)]
fig = Figure()
super(Plotter,self).__init__(fig)
# create an axis
self.axes = fig.add_subplot(111)
# discards the old graph
self.axes.hold(False)
# plot data
self.axes.plot(data, '*-')
def binding_plotter_with_ui(self):
self.parent.vLayout.insertWidget(1, self)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
# plotter logic and binding needs to be added here
plotter = Plotter(ui)
plotter.binding_plotter_with_ui()
plotter2 = Plotter(ui)
plotter2.binding_plotter_with_ui()
Form.show()
sys.exit(app.exec_())
Now what's left is probably to tweak the FigureCanvas
to make it the right size and proportions, so you should be able to get what you want looking at this example or the other.
Good luck!
Have a look at the matplotlib example of embedding in QT4: http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html
Here they define a couple of classes implementing a matplotlib widget in a QT4 application, e.g. the class MyStaticMplCanvas
. The trick to use this class inside QT Designer is to use a standard QWidget, right-click it and select Promote to ...
Fill in the class name MyStaticMplCanvas
under Promoted class name
, and the filename where this class is found under header file
(the extention .h is added, but ignored in the python code). Click Add
and Promote
.
Now after compilation by uic the python code should look similar to:
from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
...
self.mplvl = MyStaticMplCanvas(Form)
...
from mystaticmplcanvas import MyStaticMplCanvas
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With