Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
344 views
in Technique[技术] by (71.8m points)

python - Maintaining one colorbar for maptlotlib FuncAnimation

I've made a script which uses matplotlib's FuncAnimation function to animate a series of contour plots for paraboloid surface functions. I'd like to add a colorbar for which the range does not change throughout the entire animation. I really have no idea how to do this. The script is shown below:

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

Line 42 was my attempt at including said colorbar. The issue here is that because FuncAnimation calls the plotting function multiple times (once for each frame), the colorbar gets plotted multiple times thus messing up the animation. I also can't think of any way to move the colorbar instantiation outside of the animate function since the ax object appears to be local to it.

How can I put one colorbar for the whole animation?

Please note the above is fully working code. It should work on the appropriate python interpreter.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I guess the idea would be to create a contour plot outside the updating function once and give it a colorbar. The contour plot would then need to have defined levels and the colorrange needs to be defined.

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

where zmin and zmax are the minimum and maximum data to be shown, and levels is the list or array of levels to use.

Then, inside the animating function, you would only create a new contour plot with those same parameters without touching the colorbar at all.

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...