[英]Animate scatter plot with colorbar using matplotlib
我花了很多時間嘗試為散點圖 plot 設置動畫,其中標記的顏色由數字定義。
以下是我的嘗試,雖然效果不錯,但並沒有按計划進行:
但是,無論我做什么,都會產生一張空白圖表。 在動畫散布方面,這真的是我能用 python 做的最好的嗎?
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
time_steps = 50
N_nodes = 100
positions = []
solutions = []
for i in range(time_steps):
positions.append(np.random.rand(2, N_nodes))
solutions.append(np.random.random(N_nodes))
fig = plt.figure()
marker_size = 1
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0, 1), ylim=(0, 1))
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
def init():
""" Initialize animation. """
scat = ax.scatter(positions[0][0], positions[0][1], s = marker_size, c = solutions[0], cmap = "RdBu_r", marker = ".", edgecolor = None)
fig.colorbar(scat)
time_text.set_text('Time step = %d' % 0)
return scat, time_text
def animate(i):
""" Perform animation step. """
scat = ax.scatter(positions[i][0], positions[i][1], s = marker_size, c = solutions[i], cmap = "RdBu_r", marker = ".", edgecolor = None)
time_text.set_text('Time step = %d' % i)
return scat, time_text
plt.xlabel('x [m]')
plt.ylabel('y [m]')
plt.grid(b=None)
plt.show()
ani = animation.FuncAnimation(fig, animate, interval=100, blit=True, repeat=True, init_func=init)
ani.save('animation.gif', writer='imagemagick', fps = 8)
我不確定您是否在帖子中指出了這一點,但我無法讓您的代碼按原樣運行。 但是,我認為主要問題與您提到的第一點有關:“在每個 animation 步驟之后,應刪除舊點。 ”在繪制 animation 時,您確實需要明確說明這一點。 目前,您的代碼正在重復為相同的Axes
創建scatter
。 就像您要在 animation 之外執行此操作一樣,這將導致多組數據相互重疊。
我已經看到人們這樣做的兩種主要方式:要么使用 plot 的一些set_...
方法來更新數據(參見此處的散點圖或此處一般)或清除Axes
或Figure
每次迭代以 plot 新數據. 我發現后者更容易/更普遍(如果更懶惰)。 這是您的示例的一種方法(我已編輯此代碼以刪除對plt.grid
和plt.label
的調用,因為它們不起作用):
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
time_steps = 50
N_nodes = 100
positions = []
solutions = []
for i in range(time_steps):
positions.append(np.random.rand(2, N_nodes))
solutions.append(np.random.random(N_nodes))
fig, ax = plt.subplots()
marker_size = 5 #upped this to make points more visible
def animate(i):
""" Perform animation step. """
#important - the figure is cleared and new axes are added
fig.clear()
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0, 1), ylim=(0, 1))
#the new axes must be re-formatted
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax.grid(b=None)
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
# and the elements for this frame are added
ax.text(0.02, 0.95, 'Time step = %d' % i, transform=ax.transAxes)
s = ax.scatter(positions[i][0], positions[i][1], s = marker_size, c = solutions[i], cmap = "RdBu_r", marker = ".", edgecolor = None)
fig.colorbar(s)
ani = animation.FuncAnimation(fig, animate, interval=100, frames=range(time_steps))
ani.save('animation.gif', writer='pillow')
生成以下 GIF:
在這里,我使用fig.clear()
來清除每一幀的colorbar
條; 否則,其中許多將被繪制。 這意味着您每次都必須重新添加Axes
和格式。 在其他情況下,使用ax.clear()
可以很好並節省add_subplot
的步驟。
然而,還有另一種方法可以做到這一點,如下此處。 如果您有顏色條Axes
的句柄,則可以清除它們(而不是清除整個Figure
),類似於分散 plot 軸:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
time_steps = 50
N_nodes = 100
positions = []
solutions = []
for i in range(time_steps):
positions.append(np.random.rand(2, N_nodes))
solutions.append(np.random.random(N_nodes))
# init the figure, so the colorbar can be initially placed somewhere
marker_size = 5
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(0, 1), ylim=(0, 1))
s = ax.scatter(positions[0][0], positions[0][1], s = marker_size, c = solutions[0], cmap = "RdBu_r", marker = ".", edgecolor = None)
cb = fig.colorbar(s)
# get the axis for the colobar
cax = cb.ax
def animate(i):
""" Perform animation step. """
# clear both plotting axis and colorbar axis
ax.clear()
cax.cla()
#the new axes must be re-formatted
ax.set_xlim(0,1)
ax.set_ylim(0,1)
ax.grid(b=None)
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
# and the elements for this frame are added
ax.text(0.02, 0.95, 'Time step = %d' % i, transform=ax.transAxes)
s = ax.scatter(positions[i][0], positions[i][1], s = marker_size, c = solutions[i], cmap = "RdBu_r", marker = ".", edgecolor = None)
fig.colorbar(s, cax=cax)
ani = animation.FuncAnimation(fig, animate, interval=100, frames=range(time_steps))
ani.save('animation2.gif', writer='pillow')
產生相同的圖形。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.