我试图在Qt5应用程序中使用matplotlib来做一些实时图。根据Basti在博客上写的内容(http://bastibe.de/2013-05-30-speeding-up-matplotlib.html),专注于加快绘制图形。 该示例基于matplotlib示例:embedding_in_qt5.py 我是ggplot的忠实粉丝,问题是当我更新图表时网格消失了。如果使用ggplot则无关紧要。这就是存在代码问题的地方:
#### FAST UPDATE VERSION - MISSING GRID ####
# Basti version
# self.axes.draw_artist(self.axes.patch)
# self.axes.draw_artist(lines[0])
# My version
# redraw_in_frame seems to do the same, but not much on the documentation
# https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.redraw_in_frame.html
self.axes.redraw_in_frame()
self.figure.canvas.update()
self.figure.canvas.flush_events()
#### SLOW VERSION - EVERYTHING (else) LOOKS GOOD ####
# self.draw()
问题的整个代码是
# embedding_in_qt5.py --- Simple Qt5 application embedding matplotlib canvases
#
# Copyright (C) 2005 Florent Rougon
# 2006 Darren Dale
# 2015 Jens H Nielsen
#
# This file is an example program for matplotlib. It may be used and
# modified with no restriction; raw copies as well as modified versions
# may be distributed without limitation.
import sys
import os
import matplotlib as plt
import matplotlib.pyplot as plty
import numpy as np
import time
plty.style.use('ggplot')
# Make sure that we are using QT5
plt.use('Qt5Agg')
from PyQt5 import QtCore, QtWidgets
# from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
progname = os.path.basename(sys.argv[0])
progversion = "0.1"
class MyMplCanvas(FigureCanvas):
"""Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
self.step = 0.05
self.xaxis = np.arange(0, np.pi*2, self.step)
self.yaxis = self.xaxis
self.compute_initial_figure()
# Time skip variable
self.time_skip = 0
FigureCanvas.__init__(self, self.fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self,
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def compute_initial_figure(self):
pass
class MyStaticMplCanvas(MyMplCanvas):
"""Simple canvas with a sine plot."""
def compute_initial_figure(self):
self.yaxis = np.sin(self.xaxis)
self.axes.plot(self.xaxis, self.yaxis)
self.axes.grid(True)
class MyDynamicMplCanvas(MyMplCanvas):
"""A canvas that updates itself every second with a new plot."""
def __init__(self, *args, **kwargs):
MyMplCanvas.__init__(self, *args, **kwargs)
timer = QtCore.QTimer(self)
timer.timeout.connect(self.update_figure)
timer.start(25)
def compute_initial_figure(self):
self.axes.plot(self.xaxis, np.sin(self.yaxis))
self.axes.grid(True)
def update_figure(self):
# skip a few timer events
self.time_skip += 1
if self.time_skip > 10:
# Update the axis parameters to generate the sine
self.yaxis += self.step
# get the line
lines = self.axes.get_lines()
# and update it
lines[0].set_ydata(np.sin(self.yaxis))
#### FAST UPDATE VERSION - MISSING GRID ####
# Basti version
# self.axes.draw_artist(self.axes.patch)
# self.axes.draw_artist(lines[0])
# redraw_in_frame seems to do the same, but not much on the documentation
# https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.redraw_in_frame.html
self.axes.redraw_in_frame()
self.figure.canvas.update()
self.figure.canvas.flush_events()
#### SLOW VERSION - EVERYTHING (else) LOOKS GOOD ####
# self.draw()
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setWindowTitle("application main window")
self.file_menu = QtWidgets.QMenu('&File', self)
self.file_menu.addAction('&Quit', self.fileQuit,
QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
self.menuBar().addMenu(self.file_menu)
self.help_menu = QtWidgets.QMenu('&Help', self)
self.menuBar().addSeparator()
self.menuBar().addMenu(self.help_menu)
self.help_menu.addAction('&About', self.about)
self.main_widget = QtWidgets.QWidget(self)
l = QtWidgets.QVBoxLayout(self.main_widget)
sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100)
l.addWidget(sc)
l.addWidget(dc)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
self.statusBar().showMessage("All hail matplotlib!", 2000)
def fileQuit(self):
self.close()
def closeEvent(self, ce):
self.fileQuit()
def about(self):
QtWidgets.QMessageBox.about(self, "About",
"""embedding_in_qt5.py example
Copyright 2005 Florent Rougon, 2006 Darren Dale, 2015 Jens H Nielsen
This program is a simple example of a Qt5 application embedding matplotlib
canvases.
It may be used and modified with no restriction; raw copies as well as
modified versions may be distributed without limitation.
This is modified from the embedding in qt4 example to show the difference
between qt4 and qt5"""
)
qApp = QtWidgets.QApplication(sys.argv)
aw = ApplicationWindow()
aw.setWindowTitle("%s" % progname)
aw.show()
sys.exit(qApp.exec_())
#qApp.exec_()
使用pyqtgraph
对我来说不是一个简单的解决方案,因为我对它的样式不是很有信心 - 所以除非有use('ggplot')
我正在寻求这个解决方案。