I am attempting to insert a MatPlotLib graph into a QWidget type widget in order to graph real-time data from a sensor bank. The idea is to pull data asynchronously, dump it into numpy, then graph it using MatPlotLib.
My issue is that MatPlotLib doesn't want to graph into the form I've built. I've tried separating the widget out into it's own class, but that did not work either. All tutorials online seem to begin with a blank form and then built it from code instead of referencing a ready built .ui file.
The code below is stripped down to simplify things:
from PyQt5 import uic, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QAction
import matplotlib.pylab as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
# importing ui that is made in Qt Designer
uic.loadUi('MainForm.ui', self)
# linking Exit option from File menu to exit action
exitButton = QAction('Exit', self)
exitButton.setShortcut('Ctrl+Q')
exitButton.setStatusTip('Exit the program.')
self.actionExit.triggered.connect(QApplication.quit)
# add data
data = np.array([0.7, 0.7, 0.7, 0.8, 0.9, 0.9, 1.5, 1.5, 1.5, 1.5])
fig, ax1 = plt.subplots()
bins = np.arange(0.6, 1.62, 0.02)
n1, bins1, patches1 = ax1.hist(data, bins, alpha=0.6, density=False, cumulative=False)
# plot
self.plotWidget = FigureCanvas(plt.subplot)
lay = QVBoxLayout(self.plotWidget)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self.plotWidget)
# add toolbar
self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.plotWidget, self))
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec())
The MainForm.ui code is:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>736</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="plotWidgetHolder" native="true">
<property name="geometry">
<rect>
<x>11</x>
<y>11</y>
<width>771</width>
<height>484</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>320</x>
<y>570</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuData">
<property name="title">
<string>Data</string>
</property>
<addaction name="actionOpen_Data_Folder"/>
<addaction name="actionOpen_in_Excel"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuData"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionNew">
<property name="text">
<string>New</string>
</property>
</action>
<action name="actionOpen">
<property name="text">
<string>Open</string>
</property>
</action>
<action name="actionOpen_in_Excel">
<property name="text">
<string>Open in Excel</string>
</property>
</action>
<action name="actionOpen_Data_Folder">
<property name="text">
<string>Open Data Folder</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
With this code, I typically get an error code "AttributeError: 'function' object has no attribute 'set_canvas'", and the graph pops up in it's own MatPlotLib generated window instead of inside the larger form.
Any help would be greatly appreciated.
self.plotWidget = FigureCanvas(plt.subplot)withself.plotWidget = FigureCanvas(fig)matplotlib.figure.Figure()as shown in all the tutorials or examples you find on that matter.