Matplotlib 和 PyQt5 绘图图
Posted
技术标签:
【中文标题】Matplotlib 和 PyQt5 绘图图【英文标题】:Matplotlib and PyQt5 Plotting Figure 【发布时间】:2019-10-07 23:44:01 【问题描述】:尝试在 PyQt5 和 Matplotlib 中使用 python 绘制饼图,但遇到了一些问题。我可以有一个饼图和我想在其中显示的数据,但是如果我在调用某个函数时向它提供新数据,我会尝试更新图表。
mplvl 是我要添加图形的小部件名称。
每次我调用这个函数时,它都会添加另一个子图。我试过清除情节,清除图形,但我不能让它只删除并重绘图形。我想我对 Matplotlib 的真正工作原理感到困惑,但我们将不胜感激。
import datetime
import calendar as cal
import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QMessageBox, QTableWidgetItem
from PyQt5.uic import loadUi
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as FigureCanvas)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi('main.ui', self)
self.date_from.setDate(QtCore.QDate(c_date.year, c_date.month, 1))
self.date_to.setDate(QtCore.QDate(c_date.year, c_date.month, cal.monthrange(c_date.year, c_date.month)[1]))
self.date_from.dateChanged.connect(self.fcn_date_changed)
self.date_to.dateChanged.connect(self.fcn_date_changed)
def fcn_date_changed(self):
print("from: " + self.date_from.text() + " to: " + self.date_to.text())
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
fig = Figure()
ax1 = fig.add_subplot(111)
ax1.set_title('Percentage Spending by Category')
ax1.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=False, startangle=90)
main.canvas = FigureCanvas(fig)
main.mplvl.addWidget(main.canvas)
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
下面是main.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>861</width>
<height>611</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="btn_add_item">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>71</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Add Item</string>
</property>
</widget>
<widget class="QPushButton" name="btn_edit_item">
<property name="geometry">
<rect>
<x>190</x>
<y>540</y>
<width>81</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Edit Item</string>
</property>
</widget>
<widget class="QListWidget" name="recent_items">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>351</width>
<height>401</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="lbl_recent_items">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>251</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Recent Items</string>
</property>
</widget>
<widget class="QPushButton" name="btn_delete_item">
<property name="geometry">
<rect>
<x>280</x>
<y>540</y>
<width>81</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Delete Item</string>
</property>
</widget>
<widget class="QWidget" name="mplwindow" native="true">
<property name="geometry">
<rect>
<x>380</x>
<y>130</y>
<width>471</width>
<height>401</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="mplvl"/>
</widget>
<widget class="QPushButton" name="btn_view_items">
<property name="geometry">
<rect>
<x>280</x>
<y>100</y>
<width>81</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>View Items</string>
</property>
</widget>
<widget class="QDateEdit" name="date_from">
<property name="geometry">
<rect>
<x>110</x>
<y>60</y>
<width>110</width>
<height>21</height>
</rect>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
<widget class="QDateEdit" name="date_to">
<property name="geometry">
<rect>
<x>250</x>
<y>60</y>
<width>110</width>
<height>21</height>
</rect>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="lbl_showing_items1">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>101</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Showing items from: </string>
</property>
</widget>
<widget class="QLabel" name="lbl_showing_items1_2">
<property name="geometry">
<rect>
<x>230</x>
<y>60</y>
<width>21</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>to:</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>861</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
【问题讨论】:
我想我明白了。 【参考方案1】:逻辑是:
创建一个AxesSubplot
,
清理它,
调用实现绘图的函数(在您的情况下为pie(
))和
致电draw()
进行绘制。
# ...
self.date_to.dateChanged.connect(self.fcn_date_changed)
fig = Figure()
self.canvas = FigureCanvas(fig)
self.mplvl.addWidget(self.canvas)
self.ax1 = fig.add_subplot(111)
self.ax1.pie([])
def fcn_date_changed(self):
self.ax1.clear()
self.ax1.set_title("Percentage Spending by Category")
print("from: " + self.date_from.text() + " to: " + self.date_to.text())
labels = "Frogs", "Hogs", "Dogs", "Logs"
sizes = [15, 30, 45, 10]
self.ax1.pie(
sizes, labels=labels, autopct="%1.1f%%", shadow=False, startangle=90
)
self.ax1.figure.canvas.draw()
【讨论】:
感谢这工作!虽然我承认我不确定你的版本和我的版本有什么区别。是因为我每次都添加数字,而你的每次都清除/添加子图吗? @Robert 是的,查看官方示例:matplotlib.org/3.1.1/gallery/user_interfaces/…以上是关于Matplotlib 和 PyQt5 绘图图的主要内容,如果未能解决你的问题,请参考以下文章
我无法使用 MatplotLib 生成图表以在 PyQt5 App 上绘图