![](/img/trans.png)
[英]Using matplotlib.animate to animate a contour plot in python
[英]matplotlib.animate in python using multiprocessing
我正在嘗試使用 python 進程為 plot 設置動畫,如下所示:
from multiprocessing import Process
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
process_enabled = 1;
print("Process enabled: ", process_enabled)
x = []
y = []
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
def start_animation():
# Set up plot to call animate() function periodically
ani = animation.FuncAnimation(fig, animate, fargs=(x, y), interval=1000)
print("Called animate function")
plt.show()
# This function is called periodically from FuncAnimation
def animate(i, xs, ys):
fx=[0.045,0.02,0.0,0.04,0.015,-0.01,0.015,0.045,0.035,0.01,
0.055,0.04,0.02,0.025,0.0,-0.005,-0.005,-0.02,-0.05,-0.03] # fx values
# Add x and y to lists
xs.append(dt.datetime.now().strftime('%H:%M:%S.%f'))
if(i<len(fx)):
ys.append(fx[i])
# Draw x and y lists
ax.clear()
if(i<len(fx)):
ys_stacked = np.stack((np.array(ys),0.1+np.array(ys)),axis=1)
ax.plot(xs, ys_stacked)
print("Animating")
# Format plot
if(i<len(fx)):
plt.xticks(rotation=45, ha='right')
plt.subplots_adjust(bottom=0.30)
plt.title('Force/Torque Sensor Data')
plt.ylabel('Fx (N)')
if(process_enabled):
p_graph = Process(name='Graph', target=start_animation)
print("Created graph process")
p_graph.start()
print("Started graph process")
else:
start_animation()
當我禁用該過程時, start_animation() function 工作正常,並顯示 plot 並開始 animation。 但是,當啟用該進程時,該進程將啟動,然后代碼在 print("Called animate function") 處中斷。 沒有 plot window 並且終端中沒有錯誤消息)。
我對 python 和 matplotlib 中的多處理都是新手。 任何方向將不勝感激。
干杯,托尼
我正在嘗試解決同樣的問題,但還沒有完全弄清楚。 但是,我想我可以就您的問題提供一些有用的評論。
首先,您有什么理由要在單獨的進程中處理 animation 嗎? 您的方法似乎在單個過程中運行良好。 為此,您需要解決許多問題。 如果您確實需要一個單獨的過程,那么以下可能會有用。
首先,您將無法在'graph'
進程中使用全局變量,因為該進程不共享這些變量的相同實例(請參閱全局變量和 Python 多處理)。
您可以在進程之間共享 state,但這對於您想要共享的復雜對象(即plt.figure()
)來說是困難的。 有關更多信息,請參閱multiprocessing
參考 ( https://docs.python.org/3/library/multiprocessing.html#sharing-state-between-processes )
最后一個建議是pyplot
界面。 這對於簡單的腳本和交互式數據分析很方便,但它混淆了很多重要的事情——比如在調用plt
方法時知道你正在處理的圖形、軸等。
我使用自定義 class 提供了另一種面向對象的方法,它可以運行您的 animation(無需單獨的進程):
import sys
from multiprocessing import Process, Queue
import datetime as dt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.backends.qt_compat import QtWidgets
import matplotlib.animation as animation
class StripChart(FigureCanvasQTAgg):
def __init__(self):
self.fig = Figure(figsize=(8,5), dpi=100)
self.ax = self.fig.add_subplot(111)
# hold a copy of our torque data
self.fx = [0.045,0.02,0.0,0.04,0.015,-0.01,0.015,0.045,0.035,0.01,
0.055,0.04,0.02,0.025,0.0,-0.005,-0.005,-0.02,-0.05,-0.03]
super().__init__(self.fig)
# instantiate the data arrays
self.xs = []
self.ys = []
def start_animation(self):
print("starting animation")
# set up the animation
self.ani = animation.FuncAnimation(self.fig, self.animate, init_func=self.clear_frame,
frames=100, interval=500, blit=False)
def clear_frame(self):
self.ax.clear()
self.ax.plot([], [])
def animate(self, i):
print("animate frame")
# get the current time
t_now = dt.datetime.now()
# update trace values
self.xs.append(t_now.strftime("%H:%M:%S.%f"))
self.ys.append(self.fx[i % len(self.fx)])
# keep max len(self.fx) points
if len(self.xs) > len(self.fx):
self.xs.pop(0)
self.ys.pop(0)
self.ax.clear()
self.ax.plot(self.xs, self.ys)
# need to reapply format after clearing axes
self.fig.autofmt_xdate(rotation=45)
self.fig.subplots_adjust(bottom=0.30)
self.ax.set_title('Force/Torque Sensor Data')
self.ax.set_ylabel('Fx (N)')
if __name__=='__main__':
# start a new qapplication
qapp = QtWidgets.QApplication(sys.argv)
# create our figure in the main process
strip_chart = StripChart()
strip_chart.show()
strip_chart.start_animation()
# start qt main loop
qapp.exec()
本例中的注意事項:
pip install pyqt5
)init_func
,您並不需要它,因為您可以在animate
方法中調用self.ax.clear()
。blit=True
但您需要修改clear_frame
和animate
方法以返回要更新的藝術家(請參閱https://jakevdp.ZBF21518181B514/B753243BIO4/blog/B75243 2012/08/18/matplotlib-animation-tutorial/了解更多信息)。 一個缺點是您將無法使用該方法更新軸標簽。我假設您想在單獨的進程中運行 animation 的原因是更新圖形數據或繪制所有點涉及一些耗時/CPU 密集型任務。 也許您已將其嵌入到其他 UI 中?
我嘗試在單獨的進程中執行 animation,但您需要傳遞顯示的圖形實例。 正如我所提到的,這並不簡單,盡管似乎有辦法做到這一點( https://stackoverflow.com/a/57793267/13752965 )。 如果我找到可行的解決方案,我會更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.