Xarray: Animate DataArrays

Created on 30 Mar 2018  路  12Comments  路  Source: pydata/xarray

Hi, this is my first a feature request here. I've been using xarray for a while but it always comes somewhat short when I'm trying to do animations. It always ends up being a big hassle.

Is there a good way to provide some functionality to make animations easier? I really like the way xarray sets up the plots by default, but I always end up re-writing it when setting up an animation, which I always feel like is kind of a shame.

Cheers

Most helpful comment

The fact that it can't create an animation file (as far as I could tell so far) does mean I can't use it, though

You can create animation files using the matplotlib backend in holoviews, as a simple example:

import xarray as xr
import holoviews as hv
hv.extension('matplotlib')

air = xr.tutorial.load_dataset('air_temperature')
ds = hv.Dataset(air.isel(time=range(100)))
images = ds.to(hv.Image, ['lon', 'lat']).options(fig_inches=(10, 5), colorbar=True, cmap='viridis')

To display it in the notebook:

%%output holomap='mp4'
images

To save it to file:

renderer = hv.renderer('matplotlib')
renderer.save(images, 'hv_anim', 'mp4')

All 12 comments

Sounds interesting and thanks for your first issue.

What's an example of an animation?

Unfortunately I don't have any example with DataArray right now. Since I never could take advantage of DataArray's plotting capabilities for animations, I always did animations using pure Numpy. However, I'm talking about the standard matplotlib animations. Here's an example taken from here:

```import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def update_line(num, data, line):
line.set_data(data[..., :num])
return line,

Set up formatting for the movie files

Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)

fig1 = plt.figure()

data = np.random.rand(2, 25)
l, = plt.plot([], [], 'r-')
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.xlabel('x')
plt.title('test')
line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
interval=50, blit=True)
line_ani.save('lines.mp4', writer=writer)
```

If you have some directions on a smart way to bring xarray into the picture, maybe I can try to come up with an example that might evolve into a contribution.

@tomchor Note that holoviews supports xarray objects.

You can find an example of an animation made using holoviews and xarray here:
http://nbviewer.jupyter.org/gist/benbovy/e9d4f3d3be076de24b8842dae109d6e7

I didn't know holoviews existed, thanks for pointing that out to me. The fact that it can't create an animation file (as far as I could tell so far) does mean I can't use it, though. So I'll still try to pursue the matplotlib animation option, although maybe for most users holoviews+xarray might already be enough (I don't know).

The fact that it can't create an animation file (as far as I could tell so far) does mean I can't use it, though

You can create animation files using the matplotlib backend in holoviews, as a simple example:

import xarray as xr
import holoviews as hv
hv.extension('matplotlib')

air = xr.tutorial.load_dataset('air_temperature')
ds = hv.Dataset(air.isel(time=range(100)))
images = ds.to(hv.Image, ['lon', 'lat']).options(fig_inches=(10, 5), colorbar=True, cmap='viridis')

To display it in the notebook:

%%output holomap='mp4'
images

To save it to file:

renderer = hv.renderer('matplotlib')
renderer.save(images, 'hv_anim', 'mp4')

@philippjfr Thanks for the comment. I hand't found anything like that. For me, %%output isn't a recognized magic command, and the renderer.save command fails for me with a tkinter-related error (can't invoke "wm" command), so I really couldn't see anything yet. But I believe I'll be able to solve that eventually.

I hand't found anything like that.

Yes, the Plotting with Matplotlib section in the user guide should cover it but it appears to be broken in the last website build.

For me, %%output isn't a recognized magic command

That will only work in the notebook after you have run hv.extension('matplotlib').

fails for me with a tkinter-related error (can't invoke "wm" command), so I really couldn't see anything yet.

You might have to switch to a different matplotlib GUI toolkit or forego one entirely and use agg, either by declaring it in your matplotlib.rc or by setting the backend before importing holoviews, e.g.:

import matplotlib
matplotlib.use('Agg')

In the example above I had to change this line:

images = ds.to(hv.Image, ['lon', 'lat']).options(fig_inches=(10, 5), colorbar=True, cmap='viridis')

to

images = ds.to(hv.Image, ['lon', 'lat']).options('Image', fig_inches=(10, 5), colorbar=True, cmap='viridis')

in order to avoid

ValueError: HoloMap type not found, could not apply options.

(Holoviews version 1.10.0a2)

@benbovy Yes that's right, my apologies, I always work with the bleeding edge and forget what was merged before the last release. What I posted will be valid in 1.10.0, due to be released next week.

@philippjfr Even with the alteration I still get a HoloMap type not found (using HV 1.9.5) error. I can still see the animation, though. And switching to 'Agg' did allow me to save the animation in mp4, which is good. All workarounds aside, this works pretty well. Thanks a lot to all.

@philippjfr

How do you change the fps in the code that you posted above

Thanks for your help!

Small update in the syntax, which also happens to make it easier to set fps:

import xarray as xr
import holoviews as hv
hv.extension('matplotlib')

air = xr.tutorial.open_dataset('air_temperature').load()
ds = hv.Dataset(air.isel(time=range(100)))
images = ds.to(hv.Image, ['lon', 'lat']).options(fig_inches=(10, 5), colorbar=True, cmap='viridis')
hv.save(images, 'hv_anim.mp4', fps=4)
Was this page helpful?
0 / 5 - 0 ratings