我正在尝试使用实时数据可视化创建GUI-app。
我想出的解决方案是使用众所周知的技巧进行部分重绘:
fig, axes = plt.subplots(nrows=2, ncols=1)
axes[0].set_{labels, limits}
axes[1].set_{labels, limits}
fig.show()
fig.canvas.draw()
N = 2
graph_0 = axes[0].scatter([] * N, [] * N, s=[np.pi*5**2] * N, animated=True)
graph_1 = axes[1].scatter([] * N, [] * N, s=[np.pi*5**2] * N, animated=True)
bg_0 = fig.canvas.copy_from_bbox(axes[0].bbox)
bg_1 = fig.canvas.copy_from_bbox(axes[1].bbox)
while True:
# Acquire new data
tmp = [1, 2] # *For example*
# Clear plots
fig.canvas.restore_region(bg_0)
fig.canvas.restore_region(bg_1)
# Set data to be visualized
graph_0.set_offsets([(i+1, d) for i, d in enumerate(tmp)])
graph_1.set_offsets([(i+1, d) for i, d in enumerate(tmp)])
# Redraw
axes[0].draw_artist(graph_0)
axes[1].draw_artist(graph_1)
fig.canvas.blit(axes[0].bbox)
fig.canvas.blit(axes[1].bbox)
这个解决方案没问题,一切正常。
之后我尝试使用相同的方法但使用PyQt后端(还添加一些控制元素)。
以下是代码:
import sys
from PyQt4 import QtGui
from PyQt4.uic import loadUiType
import numpy as np
import matplotlib
import matplotlib.style
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import (
FigureCanvasQTAgg as FigureCanvas)
Ui_MainWindow, QMainWindow = loadUiType('dialog.ui')
class Main(QMainWindow, Ui_MainWindow):
def __init__(self, ):
super(Main, self).__init__()
self.setupUi(self)
self.layout_mpl = QtGui.QVBoxLayout()
self.widget_mpl.setLayout(self.layout_mpl)
# Assign callbacks
self.button.clicked.connect(self.update_figure)
self.prepare_figure()
def prepare_figure(self):
self.fig, self.axes = plt.subplots(nrows=2, ncols=1)
self.canvas = FigureCanvas(self.fig)
self.layout_mpl.addWidget(self.canvas)
# self.canvas.draw()
self.axes[0].set_{labels, limits}
self.axes[1].set_{labels, limits}
self.graph = [None] * 2
N = 5
self.graph[0] = self.axes[0].scatter(
[] * N, [] * N, s=[np.pi*5**2] * N, animated=True)
self.graph[1] = self.axes[1].scatter(
[] * N, [] * N, s=[np.pi*5**2] * N, animated=True)
self.canvas.draw()
self.bg = self.canvas.copy_from_bbox(self.fig.bbox)
# self.bg = [None] * 2
# self.bg[0] = self.canvas.copy_from_bbox(self.fig.axes[0].bbox)
# self.bg[1] = self.canvas.copy_from_bbox(self.fig.axes[1].bbox)
def update_figure(self):
# self.canvas.restore_region(self.bg[0])
# self.canvas.restore_region(self.bg[1])
self.canvas.restore_region(self.bg)
# Set data to be visualized
self.graph[0].set_offsets([(i+1, d) for i, d in
enumerate(np.random.rand(5)*100+100)])
self.graph[1].set_offsets([(i+1, d) for i, d in
enumerate(np.random.rand(5)*100+100)])
# Redraw
self.axes[0].draw_artist(self.graph[0])
self.axes[1].draw_artist(self.graph[1])
self.canvas.blit(self.axes[0].bbox)
self.canvas.blit(self.axes[1].bbox)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Main()
main.show()
sys.exit(app.exec_())
您可能会看到我在评论行下使用的不同调用组合。
因此,我希望每次点击button
时都会更新这些图。它实际上有效,除了一个阻塞问题:
a)申请刚刚开始
b)按钮已被点击一次
c)将焦点切换到另一个窗口并返回(此图是带偏移的图,但点放在旧坐标中)
有人可以给出任何指示吗?
提前致谢!
使用的版本:Python 3.4.3,matplotlib 1.4.3,PyQt 4.10.4。
答案 0 :(得分:2)
问题是你在完全重新调整尺寸之前的某个时刻抓住背景,以便最终在屏幕上结束。你需要做的是
draw_idle
让Qt决定何时实际触发完整重绘只是相关的方法:
def prepare_figure(self):
self.fig = Figure()
self.axes = self.fig.add_subplot(111)
self.axes.set_xlim((0, 6))
self.axes.set_xlabel('seq.index')
self.axes.set_ylim((0, 100))
self.axes.set_ylabel('observation')
N = 5
self.graph = self.axes.scatter(
[] * N, [] * N, s=[np.pi*5**2] * N,
color='seagreen', animated=True)
self.canvas = FigureCanvas(self.fig)
# w = self.widget_mpl.width()
# h = self.widget_mpl.height()
# self.canvas.setFixedSize(w, h)
self.layout_mpl.addWidget(self.canvas)
# hook up to mpls event handling framework for draw events
# this is emitted after the canvas has finished a full redraw
self.canvas.mpl_connect('draw_event', self._draw_event)
# ask the canvas to kindly draw it self some time in the future
# when Qt thinks it is convenient
self.canvas.draw_idle()
def _draw_event(self, evt):
# after drawing, grab the new background
self.bg = self.canvas.copy_from_bbox(self.axes.bbox)
查看animation
模块中的blitting代码,了解完成此项工作所需的全部功能(还有一个重新调整大小的事件),并且在重新绘制力之后,您将需要重新启动最后的数据。
答案 1 :(得分:0)
解决方案是不断检查和更新axes.bbox
尺寸:
http://matplotlib.org/1.3.1/examples/old_animation/animation_blit_qt4.html