为maptlotlib FuncAnimation维护一个颜色条

时间:2018-01-12 14:53:14

标签: python animation matplotlib

我制作了一个脚本,它使用matplotlib的{​​{1}}函数为抛物面曲面函数制作一系列等值线图。我想添加一个颜色条,其范围在整个动画中不会改变。我真的不知道该怎么做。脚本如下所示:

FuncAnimation

第42行是我尝试包含所述颜色条。这里的问题是因为import numpy as np import itertools import matplotlib.pyplot as plt import matplotlib.mlab as ml import matplotlib.animation as animation #Generate some lists def f(x,y,a): return a*(x**2+y**2) avals = list(np.linspace(0,1,10)) xaxis = list(np.linspace(-2,2,9)) yaxis = list(np.linspace(-2,2,9)) xy = list(itertools.product(xaxis,yaxis)) xy = list(map(list,xy)) xy = np.array(xy) x = xy[:,0] y = xy[:,1] x = list(x) y = list(y) zlist = [] for a in avals: z = [] for i, xval in enumerate(x): z.append(f(x[i],y[i],a)) zlist.append(z) xi = np.linspace(min(x),max(x),len(x)) yi = np.linspace(min(y), max(y), len(y)) fig,ax = plt.subplots() def animate(index): zi = ml.griddata(x, y, zlist[index], xi, yi, interp='linear') ax.clear() contourplot = ax.contourf(xi, yi, zi, cmap=plt.cm.hsv,origin='lower') #cbar = plt.colorbar(contourplot) ax.set_title('%03d'%(index)) return ax ani = animation.FuncAnimation(fig,animate,np.array([0,1,2,3,4,5,6,7,8,9]),interval=200,blit=False) plt.show() 多次调用绘图函数(每帧一次),彩色条会被多次绘制,从而弄乱动画。我也想不出任何方法可以在动画函数之外移动colorbar实例化,因为FuncAnimation对象看起来是本地的。

如何为整个动画添加一个颜色条?

请注意以上是完全正常的代码。它应该适用于适当的python解释器。

3 个答案:

答案 0 :(得分:4)

我想这个想法是在更新功能之外创建一个等高线图并给它一个颜色条。然后,轮廓图需要具有定义的级别,并且需要定义颜色范围。

ax.contourf(..., levels=levels, vmin=zmin, vmax=zmax)

其中zminzmax是要显示的最小和最大数据,levels是要使用的列表或数组。

然后,在动画功能中,您只需创建一个具有相同参数的新轮廓图,而不会触及任何颜色条。

import numpy as np
import itertools
import matplotlib.pyplot as plt
import matplotlib.mlab as ml
import matplotlib.animation as animation

def f(x,y,a):
    return a*(x**2+y**2)

avals = list(np.linspace(0,1,10))
xaxis = list(np.linspace(-2,2,9))
yaxis = list(np.linspace(-2,2,9))

xy = list(itertools.product(xaxis,yaxis))
xy = np.array(list(map(list,xy)))

x = xy[:,0]
y = xy[:,1]

zlist = []

for a in avals:
    z = []
    for i, xval in enumerate(x):
        z.append(f(x[i],y[i],a))
    zlist.append(z)

xi = np.linspace(min(x),max(x),len(x))
yi = np.linspace(min(y), max(y), len(y))

zmin = min([min(zl) for zl in zlist])
zmax = max([max(zl) for zl in zlist])
levels = np.linspace(zmin, zmax,41)
kw = dict(levels=levels, cmap=plt.cm.hsv, vmin=zmin, vmax=zmax, origin='lower')

fig,ax = plt.subplots()
zi = ml.griddata(x, y, zlist[0], xi, yi, interp='linear')
contourplot = ax.contourf(xi, yi, zi, **kw)
cbar = plt.colorbar(contourplot)

def animate(index):
    zi = ml.griddata(x, y, zlist[index], xi, yi, interp='linear')
    ax.clear()
    ax.contourf(xi, yi, zi, **kw)
    ax.set_title('%03d'%(index))


ani = animation.FuncAnimation(fig,animate,10,interval=200,blit=False)
plt.show()

enter image description here

答案 1 :(得分:4)

像往常一样,我被@ImportanceOfBeingErnest击败,但我的方法略有不同,我认为也适用。

我为颜色条创建了一个单独的ax,我使用示例from matplotlib's documentation创建了一个独立的颜色条。这需要事先了解色标的扩展。

然后我只使用相同的颜色条和标准化在动画中绘制contourf

#Generate some lists
def f(x,y,a):
    return a*(x**2+y**2)

avals = list(np.linspace(0,1,10))
xaxis = list(np.linspace(-2,2,9))
yaxis = list(np.linspace(-2,2,9))

xy = list(itertools.product(xaxis,yaxis))
xy = list(map(list,xy))
xy = np.array(xy)

x = xy[:,0]
y = xy[:,1]
x = list(x)
y = list(y)

zlist = []

for a in avals:
    z = []
    for i, xval in enumerate(x):
        z.append(f(x[i],y[i],a))
    zlist.append(z)

xi = np.linspace(min(x),max(x),len(x))
yi = np.linspace(min(y), max(y), len(y))

fig,[ax,cax] = plt.subplots(1,2, gridspec_kw={"width_ratios":[10,1]})


# Set the colormap and norm to correspond to the data for which
# the colorbar will be used.
cmap = mpl.cm.hsv
norm = mpl.colors.Normalize(vmin=0, vmax=10)

cb1 = mpl.colorbar.ColorbarBase(cax, cmap=cmap,
                                norm=norm,
                                orientation='vertical')

def animate(index):
    zi = ml.griddata(x, y, zlist[index], xi, yi, interp='linear')
    ax.clear()
    contourplot = ax.contourf(xi, yi, zi, cmap=cmap, norm=norm, origin='lower')
    #cbar = plt.colorbar(contourplot)
    ax.set_title('%03d'%(index))
    return ax

ani = animation.FuncAnimation(fig,animate,np.array([0,1,2,3,4,5,6,7,8,9]),interval=200,blit=False)

enter image description here

答案 2 :(得分:1)

这是添加colorbar的一种懒惰方式。此代码不是更新colorbar对象,而是删除并创建fig中的所有对象。

N = 10 # number of color steps
vmin, vmax = 0, 10 # this should be min and max of z
V = np.linspace(vmin, vmax, N) 

fig = plt.figure()
def animate(index):
    fig.clear()
    ax = plt.subplot(1,1,1)
    zi = ml.griddata(x, y, zlist[index], xi, yi, interp='linear')
    contourplot = ax.contourf(xi, yi, zi, V, cmap=plt.cm.hsv,origin='lower')
    cbar = plt.colorbar(contourplot)
    ax.set_title('%03d'%(index))
    return ax