gpt4 book ai didi

Python、QT 和 matplotlib 散点图与 blitting

转载 作者:太空宇宙 更新时间:2023-11-04 05:22:23 29 4
gpt4 key购买 nike

我正在尝试制作散点图的动画(它必须是散点图,因为我想改变圆的大小)。我得到了 matplotlib 文档教程 matplotlib documentation tutorial 在我的 PyQT 应用程序中工作,但我想在等式中引入 blitting,因为我的应用程序可能会在速度较慢的机器上运行,动画可能不会那么流畅。

我看过很多带有 blitting 的动画示例,但没有一个使用散点图(他们使用图或线),所以我真的很难弄清楚如何初始化动画(不使用的位)不会每次都重新渲染)和那些会重新渲染的。我已经尝试了很多东西,但似乎一无所获(而且我相信它们造成的困惑多于帮助!)。我想我错过了一些相当基本的东西。有没有人这样做过?谁能帮我把这个图分成需要启动的部分和需要更新的部分?

下面的代码有效,但没有 blit。追加

blit=True

到动画调用结束时会产生以下错误:

RuntimeError: The animation function must return a sequence of Artist objects.

任何帮助都会很棒。

问候

计划书

import numpy as np
from PyQt4 import QtGui, uic
import sys
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()

self.setupAnim()

self.show()

def setupAnim(self):
self.fig = plt.figure(figsize=(7, 7))
self.ax = self.fig.add_axes([0, 0, 1, 1], frameon=False)
self.ax.set_xlim(0, 1), self.ax.set_xticks([])
self.ax.set_ylim(0, 1), self.ax.set_yticks([])

# Create rain data
self.n_drops = 50
self.rain_drops = np.zeros(self.n_drops, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)])

# Initialize the raindrops in random positions and with
# random growth rates.
self.rain_drops['position'] = np.random.uniform(0, 1, (self.n_drops, 2))
self.rain_drops['growth'] = np.random.uniform(50, 200, self.n_drops)

# Construct the scatter which we will update during animation
# as the raindrops develop.
self.scat = self.ax.scatter(self.rain_drops['position'][:, 0], self.rain_drops['position'][:, 1],
s=self.rain_drops['size'], lw=0.5, edgecolors=self.rain_drops['color'],
facecolors='none')

self.animation = FuncAnimation(self.fig, self.update, interval=10)
plt.show()

def update(self, frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
self.current_index = frame_number % self.n_drops

# Make all colors more transparent as time progresses.
self.rain_drops['color'][:, 3] -= 1.0/len(self.rain_drops)
self.rain_drops['color'][:, 3] = np.clip(self.rain_drops['color'][:, 3], 0, 1)

# Make all circles bigger.
self.rain_drops['size'] += self.rain_drops['growth']

# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
self.rain_drops['position'][self.current_index] = np.random.uniform(0, 1, 2)
self.rain_drops['size'][self.current_index] = 5
self.rain_drops['color'][self.current_index] = (0, 0, 0, 1)
self.rain_drops['growth'][self.current_index] = np.random.uniform(50, 200)

# Update the scatter collection, with the new colors, sizes and positions.
self.scat.set_edgecolors(self.rain_drops['color'])
self.scat.set_sizes(self.rain_drops['size'])
self.scat.set_offsets(self.rain_drops['position'])

if __name__== '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())

最佳答案

如果要在中使用FuncAnimation,需要在update方法末尾添加return self.scat, blit=真。又见这个不错StackOverflow post展示了一个使用 blit 的 matplotlib 散点图动画示例。

作为旁注,如果您希望在 Qt 应用程序中嵌入 mpl 图,最好避免使用 pyplot 接口(interface),而是使用 matplotlib documentation 中建议的面向对象的 mpl API。 .

这可以实现,例如,如下所示,其中 mplWidget 可以像任何其他 Qt 小部件一样嵌入到您的主应用程序中。请注意,我将 update 方法重命名为 update_plot 以避免与 FigureCanvasQTAgg 类的现有方法发生冲突。

import numpy as np
from PyQt4 import QtGui
import sys
import matplotlib as mpl
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt

class mplWidget(FigureCanvasQTAgg):
def __init__(self):
super(mplWidget, self).__init__(mpl.figure.Figure(figsize=(7, 7)))

self.setupAnim()
self.show()

def setupAnim(self):
ax = self.figure.add_axes([0, 0, 1, 1], frameon=False)
ax.axis([0, 1, 0, 1])
ax.axis('off')

# Create rain data
self.n_drops = 50
self.rain_drops = np.zeros(self.n_drops, dtype=[('position', float, 2),
('size', float, 1),
('growth', float, 1),
('color', float, 4)
])

# Initialize the raindrops in random positions and with
# random growth rates.
self.rain_drops['position'] = np.random.uniform(0, 1, (self.n_drops, 2))
self.rain_drops['growth'] = np.random.uniform(50, 200, self.n_drops)

# Construct the scatter which we will update during animation
# as the raindrops develop.
self.scat = ax.scatter(self.rain_drops['position'][:, 0],
self.rain_drops['position'][:, 1],
s=self.rain_drops['size'],
lw=0.5, facecolors='none',
edgecolors=self.rain_drops['color'])

self.animation = FuncAnimation(self.figure, self.update_plot,
interval=10, blit=True)

def update_plot(self, frame_number):
# Get an index which we can use to re-spawn the oldest raindrop.
indx = frame_number % self.n_drops

# Make all colors more transparent as time progresses.
self.rain_drops['color'][:, 3] -= 1./len(self.rain_drops)
self.rain_drops['color'][:, 3] = np.clip(self.rain_drops['color'][:, 3], 0, 1)

# Make all circles bigger.
self.rain_drops['size'] += self.rain_drops['growth']

# Pick a new position for oldest rain drop, resetting its size,
# color and growth factor.
self.rain_drops['position'][indx] = np.random.uniform(0, 1, 2)
self.rain_drops['size'][indx] = 5
self.rain_drops['color'][indx] = (0, 0, 0, 1)
self.rain_drops['growth'][indx] = np.random.uniform(50, 200)

# Update the scatter collection, with the new colors,
# sizes and positions.
self.scat.set_edgecolors(self.rain_drops['color'])
self.scat.set_sizes(self.rain_drops['size'])
self.scat.set_offsets(self.rain_drops['position'])

return self.scat,


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = mplWidget()
sys.exit(app.exec_())

关于Python、QT 和 matplotlib 散点图与 blitting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39835300/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com