使用matplotlib使用Colorbar对散点图进行动画处理 [英] Animate scatter plot with colorbar using matplotlib

查看:81
本文介绍了使用matplotlib使用Colorbar对散点图进行动画处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了大量时间尝试动画散点图,其中标记的颜色由数字定义.

下面是我的尝试,是哪种工作,但并非按计划进行:

  • 在每个动画步骤之后,都应删除旧的点.取而代之的是,将新点简单地添加到已经在图上的点上.
  • 颜色栏也应根据值在每个步骤中进行更新(就像时间文本一样).

但是,无论我做什么,都会产生一个空白图表.在动画散布方面,这真的是我能用python做的最好的事情吗?

 将matplotlib.pyplot导入为plt导入matplotlib.animation作为动画将numpy导入为nptime_steps = 50N_nodes = 100职位= []解决方案= []对于我在范围内(time_steps):position.append(np.random.rand(2,N_nodes))solutions.append(np.random.random(N_nodes))无花果= plt.figure()marker_size = 1ax = 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():"初始化动画."scat = ax.scatter(positions [0] [0],positions [0] [1],s = marker_size,c = solutions [0],cmap ="RdBu_r",marker =.",edgecolor =没有任何)fig.colorbar(scat)time_text.set_text('时间步长=%d'%0)返回scat,time_textdef animate(i):"执行动画步骤."scat = ax.scatter(positions [i] [0],positions [i] [1],s = marker_size,c = solutions [i],cmap ="RdBu_r",marker =.",edgecolor =没有任何)time_text.set_text('时间步长=%d'%i)返回scat,time_textplt.xlabel('x [m]')plt.ylabel('y [m]')plt.grid(b =无)plt.show()ani = animation.FuncAnimation(图,动画,间隔= 100,blit =真,repeat = True,init_func = init)ani.save('animation.gif',writer ='imagemagick',fps = 8) 

解决方案

我不确定您是否从帖子中指出了这一点,但是我无法按原样运行您的代码.但是,我认为主要问题与您提到的第一点有关:"在每个动画步骤之后,都应删除旧的点.".在绘制动画时,您确实需要对此进行明确说明.当前,您的代码正在为相同的 Axes 重复创建 scatter .就像您要在动画之外执行此操作一样,这将导致多组数据相互绘制.

我已经看到人们这样做的两种主要方法:要么使用绘图的某些 set _... 方法来更新数据(见

我使用 fig.clear()清除每个帧中的 colorbar ;否则,将吸引许多人.这意味着您每次都必须重新添加 Axes 和格式.在其他情况下,可以使用 ax.clear()并保存 add_subplot 的步骤.

I have spent a serious amount of time trying to animate scatter plot where the colour of the marker is defined by a number.

Below is my attempt, which sort of works but not really as planned:

  • After each animation step, the old points should be removed. Instead, the new points are simply added to the points already on plot.
  • The colorbar should also be updated at each step according to the values (just like time text is).

However, whatever I seem to do, produces a blank chart. Is this really the best I can do with python when it comes to animating scatter?

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)

解决方案

I'm not sure if you were indicating this from your post, but I couldn't get your code to run as is. However, I believe the main issue relates to the first point you mention: "After each animation step, the old points should be removed." You do need to be explicit about this when drawing the animation. Currently, your code is repeatedly creating a scatter for the same Axes. Just as if you were to do this outside of an animation, this will result in multiple sets of data being drawn over each other.

I have seen 2 major ways people do this: either using some set_... methods of the plot to update the data (seen here for scatter plots or here in general) or clearing the Axes or Figure each iteration in order to plot new data. I find the latter easier/more universal (if lazier). Here is an approach for your example doing so:

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

plt.xlabel('x [m]')
plt.ylabel('y [m]')
plt.grid(b=None)
ani = animation.FuncAnimation(fig, animate, interval=100, frames=range(time_steps))

ani.save('animation.gif', writer='pillow')

Producing the following GIF:

I use fig.clear() to clear the colorbar each frame; otherwise, many of them will be drawn. This means you have to re-add the Axes and the formatting each time. In other cases, using ax.clear() can be fine and save the step of add_subplot.

这篇关于使用matplotlib使用Colorbar对散点图进行动画处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆