Hello!
When I create a multidimensional holoviews Image
with the parameter dynamic=True
starting from an xarray, I cannot save a gif out of it directly. I need to use the slider first, so that the render
method converts my hv.Image
to a 'matplotlib.animation.FuncAnimation
. If I don’t do it, the render
methods converts my hv.Image
to a matplotlib.figure.Figure
, which doesn’t have a save()
method. Is there a more elegant way to force the render
method to convert my hv.Image
to a matplotlib.animation.FuncAnimation
? (The xarray
s with which I am working are pretty huge, so setting dynamic=False
is not really an option)
Minimal example code:
rand, x, y, z, step = np.random.randn(2, 10, 10, 10), np.linspace(0, 10, 10), np.linspace(0, 10, 10), np.linspace(0, 10, 10), [0, 1]
xa2 = xr.DataArray(rand, coords=dict(step=step, x=x, y=y, z=z, ) , dims=["step", "x", "y", "z"], name="field2")
hv_dst = hv.Dataset(xa2)
hv_imt_dynamic = hv_dst.to(hv.Image, dynamic=True)
fig = hv.render(hv_imt_dynamic, backend='matplotlib')
print(type(fig))
test2 = fig.save("testissue.gif", fps=0.5, dpi=200,)
>>> <class 'matplotlib.figure.Figure'>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [40], in <module>
2 fig = hv.render(hv_imt_dynamic, backend='matplotlib')
3 print(type(fig))
----> 4 test2 = fig.save("testissue.gif", fps=0.5, dpi=200,)
AttributeError: 'Figure' object has no attribute 'save'
However, if I open a cell:
hv_imt_dynamic
and play a bit around with the slider, then the error doesn’t appear anymore and the gif
can be stored and the type(fig) == matplotlib.animation.FuncAnimation
I looked at the source code of the render
method and it checks the following condition:
if backend == 'matplotlib' and len(plot) > 1:
Apparently, the plot
object that comes from a DynamicMap
doesn’t detect that the map has more than one frame, only that these are dynamically loaded. I don’t know if it would make sense or which impact this could have, but one could think about expanding the condition with an or 'DynamicMap' in renderer_obj._name_param_value
, or something similar.
(I cannot upload the jupyter notebook because I’m a new user, the imports that I used are:
import holoviews as hv
hv.extension('bokeh', 'matplotlib') # Allow for interactive plots
import xarray as xr
import numpy as np
)