如何使用contourf()制作动画?

时间:2021-11-15 15:00:11

I'm trying to animate the wigner function of the spatial coordinates of some time-dependent data. The wigner function is 2 dimensional, so I'm using contourf() to plot it. I have the data stored in a HDF5 file and can make Wigner distributions on the fly, but I can't figure out how to animate it. All of the animation tutorials and examples I've been able to find (for example this one and this one) are strictly for line plots. Specifically, their animate(i) function uses line.set_data(), and I can't seem to find an equivalent for contourf().

我试图使维格纳函数的空间坐标的一些时间相关的数据动起来。wigner函数是二维的,所以我用contourf()来绘图。我将数据存储在HDF5文件中,可以动态地制作Wigner发行版,但我不知道如何对它进行动画处理。我能找到的所有动画教程和示例(例如这个和这个)都是严格地用于线条图。具体来说,他们的animate(i)函数使用line.set_data(),而我似乎找不到contourf()的等效项。

How can I animate images made with contourf()?

我如何用contourf()动画制作动画?

What's the contourf() equivalent of set_data()?

contourf()等价于set_data()是什么?

4 个解决方案

#1


6  

There's a simple way to do it with FuncAnimation: You must have a function that clears the axis and plot a new contour based on frame number. Don't forget to set blit as False.

用FuncAnimation有一种简单的方法:必须有一个函数清除轴,并根据帧数绘制新的轮廓。别忘了把blit设为False。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

DATA = np.random.randn(800).reshape(10,10,8)


fig,ax = plt.subplots()

def animate(i):
       ax.clear()
       ax.contourf(DATA[:,:,i])
       ax.set_title('%03d'%(i)) 

interval = 2#in seconds     
ani = animation.FuncAnimation(fig,animate,5,interval=interval*1e+3,blit=False)

plt.show()

#2


3  

Here is what I use to animate 2d contour plots, it was adapted from http://matplotlib.org/examples/animation/dynamic_image2.html

这里是我使用的动画2d等高线图,它是根据http://matplotlib.org/examples/animation/dynamic_image2.html改编的。

import pylab as pl
import numpy as np
import matplotlib.animation as animation
import types


fig = pl.figure()
# Some 2D arrays to plot (time,x,y)
data = np.random.random_sample((20,10,10))

# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are just animating one artist, the image, in
# each frame
ims = []
for i in range(len(data[:,0,0])):
    t_step = int(i)
    im = pl.contourf(data[i,:,:])

    #################################################################
    ## Bug fix for Quad Contour set not having attribute 'set_visible'
    def setvisible(self,vis):
        for c in self.collections: c.set_visible(vis)
    im.set_visible = types.MethodType(setvisible,im)
    im.axes = pl.gca()
    im.figure=fig
    ####################################################################

    ims.append([im])

ani = animation.ArtistAnimation(fig, ims, interval=70, blit=False,repeat_delay=1000)

pl.show()

#3


3  

I am plotting geographical data and therefore need Basemap. Based on the answer by captain_M and a discussion/bug report on https://github.com/matplotlib/matplotlib/issues/6139 I post a response inspired by tacaswell that allows you to use contourf in an animation of 2 dimensional data and save it as mp4 if you have ffmpeg:

我正在绘制地理数据,因此需要Basemap。基于captain_M的答案和一个关于https://github.com/matplotlib/matplotlib/issues/6139的讨论/bug报告,我发布了一个受tacaswell启发的响应,该响应允许您在一个二维数据动画中使用contourf,如果您有ffmpeg,则将其保存为mp4:

from matplotlib import animation
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap


fig, ax = plt.subplots()

# set up map projection
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))

# some 2D geo arrays to plot (time,lat,lon)
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)

# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are animating three artists, the contour and 2 
# annotatons (title), in each frame
ims = []
for i in range(len(data[:,0,0])):
    im = m.contourf(lons,lats,data[i,:,:],latlon=True)
    add_arts = im.collections
    text = 'title={0!r}'.format(i)
    te = ax.text(90, 90, text)
    an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
    ims.append(add_arts + [te,an])

ani = animation.ArtistAnimation(fig, ims)
## If you have ffmpeg you can save the animation by uncommenting 
## the following 2 lines
# FFwriter = animation.FFMpegWriter()
# ani.save('basic_animation.mp4', writer = FFwriter)
plt.show()

#4


1  

If you are like me and the matplotlib.animation doesn't work. Here is something else you can try. If you want to continuously update the colorbar and everything else in the figure, use plt.ion() at the very beginning to enable interactive plotting and use a combo of plt.draw() and plt.clf() to continuously update the plot. Here is example code:

如果你像我和matplotlib一样。动画是行不通的。这里还有一些你可以尝试的东西。如果您想持续更新图中的colorbar和其他内容,请在开始时使用pl .ion()来启用交互式绘图,并使用pl .draw()和pl .clf()的组合来持续更新绘图。下面是示例代码:

import matplotlib.pyplot as plt
import numpy as np

plt.ion(); plt.figure(1);
for k in range(10):
    plt.clf(); plt.subplot(121);
    plt.contourf(np.random.randn(10,10)); plt.colorbar();
    plt.subplot(122,polar=True)
    plt.contourf(np.random.randn(10,10)); plt.colorbar();
    plt.draw();

Note that this works with figures containing different subplots and various types of plots (i.e. polar or cartesian)

注意,这与包含不同子情节和不同类型情节(例如极地或笛卡尔)的图形有关

#1


6  

There's a simple way to do it with FuncAnimation: You must have a function that clears the axis and plot a new contour based on frame number. Don't forget to set blit as False.

用FuncAnimation有一种简单的方法:必须有一个函数清除轴,并根据帧数绘制新的轮廓。别忘了把blit设为False。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

DATA = np.random.randn(800).reshape(10,10,8)


fig,ax = plt.subplots()

def animate(i):
       ax.clear()
       ax.contourf(DATA[:,:,i])
       ax.set_title('%03d'%(i)) 

interval = 2#in seconds     
ani = animation.FuncAnimation(fig,animate,5,interval=interval*1e+3,blit=False)

plt.show()

#2


3  

Here is what I use to animate 2d contour plots, it was adapted from http://matplotlib.org/examples/animation/dynamic_image2.html

这里是我使用的动画2d等高线图,它是根据http://matplotlib.org/examples/animation/dynamic_image2.html改编的。

import pylab as pl
import numpy as np
import matplotlib.animation as animation
import types


fig = pl.figure()
# Some 2D arrays to plot (time,x,y)
data = np.random.random_sample((20,10,10))

# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are just animating one artist, the image, in
# each frame
ims = []
for i in range(len(data[:,0,0])):
    t_step = int(i)
    im = pl.contourf(data[i,:,:])

    #################################################################
    ## Bug fix for Quad Contour set not having attribute 'set_visible'
    def setvisible(self,vis):
        for c in self.collections: c.set_visible(vis)
    im.set_visible = types.MethodType(setvisible,im)
    im.axes = pl.gca()
    im.figure=fig
    ####################################################################

    ims.append([im])

ani = animation.ArtistAnimation(fig, ims, interval=70, blit=False,repeat_delay=1000)

pl.show()

#3


3  

I am plotting geographical data and therefore need Basemap. Based on the answer by captain_M and a discussion/bug report on https://github.com/matplotlib/matplotlib/issues/6139 I post a response inspired by tacaswell that allows you to use contourf in an animation of 2 dimensional data and save it as mp4 if you have ffmpeg:

我正在绘制地理数据,因此需要Basemap。基于captain_M的答案和一个关于https://github.com/matplotlib/matplotlib/issues/6139的讨论/bug报告,我发布了一个受tacaswell启发的响应,该响应允许您在一个二维数据动画中使用contourf,如果您有ffmpeg,则将其保存为mp4:

from matplotlib import animation
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap


fig, ax = plt.subplots()

# set up map projection
m = Basemap(projection='nsper',lon_0=-0,lat_0=90)
m.drawcoastlines()
m.drawparallels(np.arange(0.,180.,30.))
m.drawmeridians(np.arange(0.,360.,60.))

# some 2D geo arrays to plot (time,lat,lon)
data = np.random.random_sample((20,90,360))
lat = np.arange(len(data[0,:,0]))
lon = np.arange(len(data[0,0,:]))
lons,lats = np.meshgrid(lon,lat)

# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are animating three artists, the contour and 2 
# annotatons (title), in each frame
ims = []
for i in range(len(data[:,0,0])):
    im = m.contourf(lons,lats,data[i,:,:],latlon=True)
    add_arts = im.collections
    text = 'title={0!r}'.format(i)
    te = ax.text(90, 90, text)
    an = ax.annotate(text, xy=(0.45, 1.05), xycoords='axes fraction')
    ims.append(add_arts + [te,an])

ani = animation.ArtistAnimation(fig, ims)
## If you have ffmpeg you can save the animation by uncommenting 
## the following 2 lines
# FFwriter = animation.FFMpegWriter()
# ani.save('basic_animation.mp4', writer = FFwriter)
plt.show()

#4


1  

If you are like me and the matplotlib.animation doesn't work. Here is something else you can try. If you want to continuously update the colorbar and everything else in the figure, use plt.ion() at the very beginning to enable interactive plotting and use a combo of plt.draw() and plt.clf() to continuously update the plot. Here is example code:

如果你像我和matplotlib一样。动画是行不通的。这里还有一些你可以尝试的东西。如果您想持续更新图中的colorbar和其他内容,请在开始时使用pl .ion()来启用交互式绘图,并使用pl .draw()和pl .clf()的组合来持续更新绘图。下面是示例代码:

import matplotlib.pyplot as plt
import numpy as np

plt.ion(); plt.figure(1);
for k in range(10):
    plt.clf(); plt.subplot(121);
    plt.contourf(np.random.randn(10,10)); plt.colorbar();
    plt.subplot(122,polar=True)
    plt.contourf(np.random.randn(10,10)); plt.colorbar();
    plt.draw();

Note that this works with figures containing different subplots and various types of plots (i.e. polar or cartesian)

注意,这与包含不同子情节和不同类型情节(例如极地或笛卡尔)的图形有关