【发布时间】:2019-07-25 02:30:42
【问题描述】:
我正在尝试将 MatPlotLib 图形插入到 QWidget 类型的小部件中,以便绘制来自传感器库的实时数据。这个想法是异步提取数据,将其转储到 numpy,然后使用 MatPlotLib 绘制它。
我的问题是 MatPlotLib 不想绘制成我构建的表格。我尝试将小部件分离到它自己的类中,但这也不起作用。所有在线教程似乎都是从一个空白表单开始,然后从代码构建它,而不是引用一个现成的 .ui 文件。
下面的代码被精简以简化事情:
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())
MainForm.ui 代码为:
<?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>
使用此代码,我通常会收到错误代码“AttributeError: 'function' object has no attribute 'set_canvas'”,并且图形会在它自己的 MatPlotLib 生成窗口中弹出,而不是在较大的表单中。
任何帮助将不胜感激。
【问题讨论】:
-
用
self.plotWidget = FigureCanvas(fig)替换self.plotWidget = FigureCanvas(plt.subplot) -
另外,根本不要使用pylab或pyplot。删除该导入,这样您就不会想使用它。而是创建一个
matplotlib.figure.Figure(),如您在该问题上找到的所有教程或示例中所示。
标签: python matplotlib pyqt pyqt5