我有一个动画,其中数据范围变化很大。我想有一个colorbar跟踪数据的最大值和最小值(即我希望它不固定)。问题是如何做到这一点。
colorbar
理想情况下,我希望colorbar该轴独立。
我尝试了以下四件事
问题:每帧都有一个新的彩条
#!/usr/bin/env python """ An animated image """ import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation fig = plt.figure() ax = fig.add_subplot(111) def f(x, y): return np.exp(x) + np.sin(y) x = np.linspace(0, 1, 120) y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) frames = [] for i in range(10): x += 1 curVals = f(x, y) vmax = np.max(curVals) vmin = np.min(curVals) levels = np.linspace(vmin, vmax, 200, endpoint = True) frame = ax.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels) cbar = fig.colorbar(frame) frames.append(frame.collections) ani = animation.ArtistAnimation(fig, frames, blit=False) plt.show()
将上面的for循环更改为
initFrame = ax.contourf(f(x,y)) cbar = fig.colorbar(initFrame) for i in range(10): x += 1 curVals = f(x, y) vmax = np.max(curVals) vmin = np.min(curVals) levels = np.linspace(vmin, vmax, 200, endpoint = True) frame = ax.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels) cbar.set_clim(vmin = vmin, vmax = vmax) cbar.draw_all() frames.append(frame.collections + [cbar])
问题:这引起了
AttributeError: 'Colorbar' object has no attribute 'set_visible'
问题:colorbar尚未更新。
#!/usr/bin/env python """ An animated image """ import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation fig = plt.figure() ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) def f(x, y): return np.exp(x) + np.sin(y) x = np.linspace(0, 1, 120) y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) frames = [] for i in range(10): x += 1 curVals = f(x, y) vmax = np.max(curVals) vmin = np.min(curVals) levels = np.linspace(vmin, vmax, 200, endpoint = True) frame = ax1.contourf(curVals, vmax=vmax, vmin=vmin, levels=levels) cbar = fig.colorbar(frame, cax=ax2) # Colorbar does not update frames.append(frame.collections) ani = animation.ArtistAnimation(fig, frames, blit=False) plt.show()
问题:colorbar常数。
虽然我不确定如何使用来具体实现ArtistAnimation,但使用还是FuncAnimation很简单的。如果我对您的“原始”版本1进行了以下修改,则可以正常工作。
ArtistAnimation
FuncAnimation
修改版本1
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from mpl_toolkits.axes_grid1 import make_axes_locatable fig = plt.figure() ax = fig.add_subplot(111) # I like to position my colorbars this way, but you don't have to div = make_axes_locatable(ax) cax = div.append_axes('right', '5%', '5%') def f(x, y): return np.exp(x) + np.sin(y) x = np.linspace(0, 1, 120) y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) frames = [] for i in range(10): x += 1 curVals = f(x, y) frames.append(curVals) cv0 = frames[0] cf = ax.contourf(cv0, 200) cb = fig.colorbar(cf, cax=cax) tx = ax.set_title('Frame 0') def animate(i): arr = frames[i] vmax = np.max(arr) vmin = np.min(arr) levels = np.linspace(vmin, vmax, 200, endpoint = True) cf = ax.contourf(arr, vmax=vmax, vmin=vmin, levels=levels) cax.cla() fig.colorbar(cf, cax=cax) tx.set_text('Frame {0}'.format(i)) ani = animation.FuncAnimation(fig, animate, frames=10) plt.show()
主要区别在于,我在函数中执行关卡计算和轮廓绘制,而不是创建艺术家列表。由于您可以清除上一帧中的轴并在每帧中重做轴,因此色条起作用。
使用contour或时contourf,必须重做,因为您不能只是动态地更改数据。但是,当您绘制了许多轮廓线并且结果看起来很平滑时,我认为最好imshow改用它- 这意味着您实际上可以只使用同一位艺术家并更改数据,并且颜色栏会自动更新。它也快得多!
contour
contourf
imshow
更好的版本
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from mpl_toolkits.axes_grid1 import make_axes_locatable fig = plt.figure() ax = fig.add_subplot(111) # I like to position my colorbars this way, but you don't have to div = make_axes_locatable(ax) cax = div.append_axes('right', '5%', '5%') def f(x, y): return np.exp(x) + np.sin(y) x = np.linspace(0, 1, 120) y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1) # This is now a list of arrays rather than a list of artists frames = [] for i in range(10): x += 1 curVals = f(x, y) frames.append(curVals) cv0 = frames[0] im = ax.imshow(cv0, origin='lower') # Here make an AxesImage rather than contour cb = fig.colorbar(im, cax=cax) tx = ax.set_title('Frame 0') def animate(i): arr = frames[i] vmax = np.max(arr) vmin = np.min(arr) im.set_data(arr) im.set_clim(vmin, vmax) tx.set_text('Frame {0}'.format(i)) # In this version you don't have to do anything to the colorbar, # it updates itself when the mappable it watches (im) changes ani = animation.FuncAnimation(fig, animate, frames=10) plt.show()