matplotlib 使用颜色条制作散点图动画

ql3eal8s  于 2023-05-23  发布在  其他
关注(0)|答案(1)|浏览(147)

我花了大量的时间尝试动画散点图,其中标记的颜色由数字定义。
下面是我的尝试,这是一种工作,但不是真的按计划进行:

  • 在每个动画步骤之后,应删除旧点。相反,新点只是简单地添加到图上已有的点。
  • 颜色条也应该根据值在每一步更新(就像时间文本一样)。

然而,无论我做什么,都会产生一个空白的图表。这真的是最好的我可以用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)
f1tvaqid

f1tvaqid1#

我不确定你是否从你的帖子中指出了这一点,但我无法让你的代码按原样运行。然而,我认为主要问题与你提到的第一点有关:“* 在每个动画步骤之后,旧的点应该被删除。*”在绘制动画时,您确实需要明确这一点。目前,您的代码正在为同一个Axes重复创建scatter。就像在动画之外执行此操作一样,这将导致多个数据集相互重叠绘制。
我看到人们这样做的两种主要方式:或者使用绘图的一些set_...方法来 * 更新 * 数据(参见here for scatter plotshere in general每次迭代清除AxesFigure以便绘制新数据。我发现后者更容易/更普遍(如果更懒惰)。下面是一种方法,可以让你的例子做到这一点(我已经编辑了这段代码,删除了对plt.gridplt.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的步骤。
但是,还有另一种方法可以做到这一点,遵循here。如果您有颜色条Axes的句柄,您可以只清除它们(而不是清除整个Figure),类似于散点图轴:

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')

产生相同的图形。

相关问题