Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gif output on Windows #385

Closed
stonebig opened this issue Dec 26, 2015 · 25 comments
Closed

Gif output on Windows #385

stonebig opened this issue Dec 26, 2015 · 25 comments
Assignees
Milestone

Comments

@stonebig
Copy link
Contributor

I get this, with no clue of the problem, under Windows 7 / Python 3.4.4. / Notebook 4.0.6

holoviews141a

@jlstevens
Copy link
Contributor

Does hv.ipython.show_traceback() report anything?

The fact that it is an OSError is rather odd...

@stonebig
Copy link
Contributor Author

oups! it first fails on

%%opts Image (cmap='gray') Contours (color='r')
m = hv.HoloMap([(p, hv.Image(sine(grid, phase=p))) for p in phases], kdims=['Phase'])
contours(m, levels=[0.5]) + threshold(m, level=0.5) + gradient(m).hist(bin_range=(0,0.7))

hv.ipython.show_traceback() gives:

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in wrapped(element=:Layout
   .Overlay.I   :HoloMap   [Phase]
     ...  [Phase]
         :Histogram   [z]   (Frequency))
     99             html = fn(element,
    100                       max_frames=OutputMagic.options['max_frames'],
--> 101                       max_branches = OutputMagic.options['max_branches'])
        global max_branches = undefined
        global OutputMagic.options = OrderedDict([('dpi', 72), ('filename', None), ('size', 100), ('backend', 'matplotlib'), ('fps', 20), ('info', False), ('widgets', 'embed'), ('max_branches', 2), ('max_frames', 500), ('fig', 'png'), ('holomap', 'gif'), ('charwidth', 80), ('css', {})])
    102 
    103             # Only want to add to the archive for one display hook...

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in layout_display(layout=:Layout
   .Overlay.I   :HoloMap   [Phase]
     ...  [Phase]
         :Histogram   [z]   (Frequency), max_frames=500, max_branches=2)
    171                 return '<tt>'+ sanitize_HTML(layout) + '</tt>'
    172 
--> 173     return render(layout)
        global render = <function render at 0x0000000009FC1620>
        layout = :Layout
   .Overlay.I   :HoloMap   [Phase]
      :Overlay
         .Image.I :Image   [x,y]   (z)
         .Level.I :NdOverlay   [Levels]
            :Contours   [x,y]   (z)
   .Threshold.I :HoloMap   [Phase]
      :Image   [x,y]   (z)
   .Gradient.I  :AdjointLayout
      :HoloMap   [Phase]
         :Image   [x,y]   (z)
      :HoloMap   [Phase]
         :Histogram   [z]   (Frequency)
    174 
    175 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in render(obj=:Layout
   .Overlay.I   :HoloMap   [Phase]
     ...  [Phase]
         :Histogram   [z]   (Frequency), **kwargs={})
     49 
     50     backend = Store.current_backend
---> 51     return Store.renderers[backend].html(obj, **kwargs)
        global Store.renderers = OrderedDict([('matplotlib', MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000D575AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')), ('bokeh', BokehRenderer(backend='bokeh', css={}, dpi=None, fig='auto', fps=20, holomap='auto', info_fn=<function Exporter.<lambda> at 0x000000000D575AE8>, key_fn=None, mode='default', name='BokehRenderer00502', size=100, widget_mode='embed'))])
        backend.html = undefined
        obj = :Layout
   .Overlay.I   :HoloMap   [Phase]
      :Overlay
         .Image.I :Image   [x,y]   (z)
         .Level.I :NdOverlay   [Levels]
            :Contours   [x,y]   (z)
   .Threshold.I :HoloMap   [Phase]
      :Image   [x,y]   (z)
   .Gradient.I  :AdjointLayout
      :HoloMap   [Phase]
         :Image   [x,y]   (z)
      :HoloMap   [Phase]
         :Histogram   [z]   (Frequency)
        kwargs = {}
     52 
     53 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\renderer.py in html(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), obj=:Layout
   .Overlay.I   :HoloMap   [Phase]
     ...  [Phase]
         :Histogram   [z]   (Frequency), fmt='gif', css=None)
    210         """
    211         plot, fmt =  self._validate(obj, fmt)
--> 212         figdata, _ = self(plot, fmt)
        figdata = undefined
        _ = undefined
        self = MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000D575AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')
        plot = LayoutPlot(aspect_weight=0, fig_alpha=1.0, fig_bounds=(0.05, 0.05, 0.95, 0.95), fig_inches=4.0, fig_latex=False, fig_rcparams={}, fig_size=100, finalize_hooks=[], fontsize={'title': 16}, hspace=0.5, name='LayoutPlot03644', normalize=True, projection=None, show_frame=True, show_title=True, sublabel_format='{Alpha}', sublabel_position=(-0.35, 0.85), sublabel_size=18, tight=False, tight_padding=3, title_format='{label} {group}', vspace=0.1)
        fmt = 'gif'
    213         if css is None: css = self.css
    214 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\mpl\renderer.py in __call__(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), obj=LayoutPlot(aspect_weight=0, fig_alpha=1.0, fig_b...ng=3, title_format='{label} {group}', vspace=0.1), fmt='gif')
     96                 raise Exception("<b>Python 3 matplotlib animation support broken &lt;= 1.3</b>")
     97             anim = plot.anim(fps=self.fps)
---> 98             data = self._anim_data(anim, fmt)
        data = undefined
        self._anim_data = <bound method MPLRenderer._anim_data of MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000D575AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')>
        anim = <matplotlib.animation.FuncAnimation object at 0x00000000108A4D30>
        fmt = 'gif'
     99 
    100         return data, {'file-ext':fmt,

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\mpl\renderer.py in _anim_data(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), anim=<matplotlib.animation.FuncAnimation object>, fmt='gif')
    208         if not hasattr(anim, '_encoded_video'):
    209             with NamedTemporaryFile(suffix='.%s' % fmt) as f:
--> 210                 anim.save(f.name, writer=writer, **anim_kwargs)
        anim.save = <bound method FuncAnimation.save of <matplotlib.animation.FuncAnimation object at 0x00000000108A4D30>>
        f.name = 'C:\\Users\\famille\\AppData\\Local\\Temp\\tmpgzx1_vjx.gif'
        writer = 'imagemagick'
        anim_kwargs = {'fps': 20, 'dpi': 72}
    211                 video = open(f.name, "rb").read()
    212         return video

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in save(self=<matplotlib.animation.FuncAnimation object>, filename=r'C:\Users\famille\AppData\Local\Temp\tmpgzx1_vjx.gif', writer=<matplotlib.animation.ImageMagickWriter object>, fps=20, dpi=72, codec='mpeg4', bitrate=-1, extra_args=None, metadata=None, extra_anim=None, savefig_kwargs={})
    778                     # TODO: Need to see if turning off blit is really necessary
    779                     anim._draw_next_frame(d, blit=False)
--> 780                 writer.grab_frame(**savefig_kwargs)
        writer.grab_frame = <bound method ImageMagickWriter.grab_frame of <matplotlib.animation.ImageMagickWriter object at 0x00000000108AB748>>
        savefig_kwargs = {}
    781 
    782         # Reconnect signal for first draw if necessary

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in grab_frame(self=<matplotlib.animation.ImageMagickWriter object>, **savefig_kwargs={})
    223             # frame format and dpi.
    224             self.fig.savefig(self._frame_sink(), format=self.frame_format,
--> 225                              dpi=self.dpi, **savefig_kwargs)
        global dpi = undefined
        self.dpi = 72
        savefig_kwargs = {}
    226         except RuntimeError:
    227             out, err = self._proc.communicate()

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\figure.py in savefig(self=<matplotlib.figure.Figure object>, *args=(<_io.BufferedWriter name=9>,), **kwargs={'dpi': 72, 'edgecolor': '#f0f0f0', 'facecolor': '#ffffff', 'format': 'rgba'})
   1537             self.set_frameon(frameon)
   1538 
-> 1539         self.canvas.print_figure(*args, **kwargs)
        self.canvas.print_figure = <bound method FigureCanvasAgg.print_figure of <matplotlib.backends.backend_agg.FigureCanvasAgg object at 0x000000001092E438>>
        args = (<_io.BufferedWriter name=9>,)
        kwargs = {'facecolor': '#ffffff', 'edgecolor': '#f0f0f0', 'format': 'rgba', 'dpi': 72}
   1540 
   1541         if frameon:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backend_bases.py in print_figure(self=<matplotlib.backends.backend_agg.FigureCanvasAgg object>, filename=<_io.BufferedWriter name=9>, dpi=72, facecolor='#ffffff', edgecolor='#f0f0f0', orientation='portrait', format='rgba', **kwargs={})
   2228                 orientation=orientation,
   2229                 bbox_inches_restore=_bbox_inches_restore,
-> 2230                 **kwargs)
        kwargs = {}
   2231         finally:
   2232             if bbox_inches and restore_bbox:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backends\backend_agg.py in print_raw(self=<matplotlib.backends.backend_agg.FigureCanvasAgg object>, filename_or_obj=<_io.BufferedWriter name=9>, *args=(), **kwargs={'bbox_inches_restore': None, 'dpi': 72, 'edgecolor': '#f0f0f0', 'facecolor': '#ffffff', 'orientation': 'portrait'})
    517             close = False
    518         try:
--> 519             fileobj.write(renderer._renderer.buffer_rgba())
        fileobj.write = <built-in method write of _io.BufferedWriter object at 0x00000000100E57D8>
        renderer._renderer.buffer_rgba = <built-in method buffer_rgba of matplotlib.backends._backend_agg.RendererAgg object at 0x0000000010195C30>
    520         finally:
    521             if close:

OSError: [Errno 22] Invalid argument


@stonebig
Copy link
Contributor Author

for

red_wave = circular_wave(options={'Image':{'style':{'cmap':'RdGy'}}})
red_wave

, i get:

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in wrapped(element=:HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude))
     99             html = fn(element,
    100                       max_frames=OutputMagic.options['max_frames'],
--> 101                       max_branches = OutputMagic.options['max_branches'])
        global max_branches = undefined
        global OutputMagic.options = OrderedDict([('fig', 'png'), ('charwidth', 80), ('fps', 20), ('max_frames', 500), ('css', {}), ('max_branches', 2), ('filename', None), ('holomap', 'gif'), ('info', False), ('backend', 'matplotlib'), ('size', 100), ('dpi', 72), ('widgets', 'embed')])
    102 
    103             # Only want to add to the archive for one display hook...

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in map_display(vmap=:HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude), max_frames=500, max_branches=2)
    153         return sanitize_HTML(vmap)
    154 
--> 155     return render(vmap)
        global render = <function render at 0x0000000009B51620>
        vmap = :HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude)
    156 
    157 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\ipython\display_hooks.py in render(obj=:HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude), **kwargs={})
     49 
     50     backend = Store.current_backend
---> 51     return Store.renderers[backend].html(obj, **kwargs)
        global Store.renderers = OrderedDict([('matplotlib', MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000CF34AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')), ('bokeh', BokehRenderer(backend='bokeh', css={}, dpi=None, fig='auto', fps=20, holomap='auto', info_fn=<function Exporter.<lambda> at 0x000000000CF34AE8>, key_fn=None, mode='default', name='BokehRenderer00502', size=100, widget_mode='embed'))])
        backend.html = undefined
        obj = :HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude)
        kwargs = {}
     52 
     53 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\renderer.py in html(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), obj=:HoloMap   [Phase,Frequency]
   :Image   [x,y]   (Amplitude), fmt='gif', css=None)
    210         """
    211         plot, fmt =  self._validate(obj, fmt)
--> 212         figdata, _ = self(plot, fmt)
        figdata = undefined
        _ = undefined
        self = MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000CF34AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')
        plot = RasterPlot(apply_extents=True, apply_ranges=True, apply_ticks=True, aspect='equal', bgcolor=None, cbar_padding=0.01, cbar_ticks=None, cbar_width=0.05, colorbar=False, fig_alpha=1.0, fig_bounds=(0.15, 0.15, 0.85, 0.85), fig_inches=4.0, fig_latex=False, fig_rcparams={}, fig_size=100, finalize_hooks=[], fontsize=None, invert_axes=False, invert_xaxis=False, invert_yaxis=False, logx=False, logy=False, logz=False, name='RasterPlot04933', normalize=True, projection=None, show_frame=True, show_grid=False, show_legend=False, show_title=True, show_values=False, situate_axes=False, sublabel_format=None, sublabel_position=(-0.35, 0.85), sublabel_size=18, symmetric=False, title_format='{label} {group}', xaxis='bottom', xrotation=0, xticks=None, yaxis='left', yrotation=0, yticks=None, zaxis=True, zrotation=0, zticks=None)
        fmt = 'gif'
    213         if css is None: css = self.css
    214 

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\mpl\renderer.py in __call__(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), obj=RasterPlot(apply_extents=True, apply_ranges=True...ticks=None, zaxis=True, zrotation=0, zticks=None), fmt='gif')
     96                 raise Exception("<b>Python 3 matplotlib animation support broken &lt;= 1.3</b>")
     97             anim = plot.anim(fps=self.fps)
---> 98             data = self._anim_data(anim, fmt)
        data = undefined
        self._anim_data = <bound method MPLRenderer._anim_data of MPLRenderer(backend='matplotlib', css={}, dpi=72, fig='png', fps=20, holomap='gif', info_fn=<function Exporter.<lambda> at 0x000000000CF34AE8>, key_fn=None, mode='default', name='MPLRenderer00130', size=100, widget_mode='embed')>
        anim = <matplotlib.animation.FuncAnimation object at 0x00000000155956A0>
        fmt = 'gif'
     99 
    100         return data, {'file-ext':fmt,

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\holoviews\plotting\mpl\renderer.py in _anim_data(self=MPLRenderer(backend='matplotlib', css={}, dpi=72...MPLRenderer00130', size=100, widget_mode='embed'), anim=<matplotlib.animation.FuncAnimation object>, fmt='gif')
    208         if not hasattr(anim, '_encoded_video'):
    209             with NamedTemporaryFile(suffix='.%s' % fmt) as f:
--> 210                 anim.save(f.name, writer=writer, **anim_kwargs)
        anim.save = <bound method FuncAnimation.save of <matplotlib.animation.FuncAnimation object at 0x00000000155956A0>>
        f.name = 'C:\\Users\\famille\\AppData\\Local\\Temp\\tmpxe6zzfqc.gif'
        writer = 'imagemagick'
        anim_kwargs = {'fps': 20, 'dpi': 72}
    211                 video = open(f.name, "rb").read()
    212         return video

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in save(self=<matplotlib.animation.FuncAnimation object>, filename=r'C:\Users\famille\AppData\Local\Temp\tmpxe6zzfqc.gif', writer=<matplotlib.animation.ImageMagickWriter object>, fps=20, dpi=72, codec='mpeg4', bitrate=-1, extra_args=None, metadata=None, extra_anim=None, savefig_kwargs={})
    778                     # TODO: Need to see if turning off blit is really necessary
    779                     anim._draw_next_frame(d, blit=False)
--> 780                 writer.grab_frame(**savefig_kwargs)
        writer.grab_frame = <bound method ImageMagickWriter.grab_frame of <matplotlib.animation.ImageMagickWriter object at 0x000000000F7A34A8>>
        savefig_kwargs = {}
    781 
    782         # Reconnect signal for first draw if necessary

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in grab_frame(self=<matplotlib.animation.ImageMagickWriter object>, **savefig_kwargs={})
    223             # frame format and dpi.
    224             self.fig.savefig(self._frame_sink(), format=self.frame_format,
--> 225                              dpi=self.dpi, **savefig_kwargs)
        global dpi = undefined
        self.dpi = 72
        savefig_kwargs = {}
    226         except RuntimeError:
    227             out, err = self._proc.communicate()

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\figure.py in savefig(self=<matplotlib.figure.Figure object>, *args=(<_io.BufferedWriter name=12>,), **kwargs={'dpi': 72, 'edgecolor': '#f0f0f0', 'facecolor': '#ffffff', 'format': 'rgba'})
   1537             self.set_frameon(frameon)
   1538 
-> 1539         self.canvas.print_figure(*args, **kwargs)
        self.canvas.print_figure = <bound method FigureCanvasAgg.print_figure of <matplotlib.backends.backend_agg.FigureCanvasAgg object at 0x0000000015593F98>>
        args = (<_io.BufferedWriter name=12>,)
        kwargs = {'facecolor': '#ffffff', 'edgecolor': '#f0f0f0', 'dpi': 72, 'format': 'rgba'}
   1540 
   1541         if frameon:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backend_bases.py in print_figure(self=<matplotlib.backends.backend_agg.FigureCanvasAgg object>, filename=<_io.BufferedWriter name=12>, dpi=72, facecolor='#ffffff', edgecolor='#f0f0f0', orientation='portrait', format='rgba', **kwargs={})
   2228                 orientation=orientation,
   2229                 bbox_inches_restore=_bbox_inches_restore,
-> 2230                 **kwargs)
        kwargs = {}
   2231         finally:
   2232             if bbox_inches and restore_bbox:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backends\backend_agg.py in print_raw(self=<matplotlib.backends.backend_agg.FigureCanvasAgg object>, filename_or_obj=<_io.BufferedWriter name=12>, *args=(), **kwargs={'bbox_inches_restore': None, 'dpi': 72, 'edgecolor': '#f0f0f0', 'facecolor': '#ffffff', 'orientation': 'portrait'})
    517             close = False
    518         try:
--> 519             fileobj.write(renderer._renderer.buffer_rgba())
        fileobj.write = <built-in method write of _io.BufferedWriter object at 0x000000001033E3B8>
        renderer._renderer.buffer_rgba = <built-in method buffer_rgba of matplotlib.backends._backend_agg.RendererAgg object at 0x000000000F6693F0>
    520         finally:
    521             if close:

OSError: [Errno 22] Invalid argument

@jlstevens
Copy link
Contributor

Thanks. I'll test this with Python 3 and see if I can reproduce it.

@jlstevens
Copy link
Contributor

After fixing the zip issue, I can say that it works on Mac OS. I can also test on Linux but it is a bit more effort for me to test on windows.

The error to me looks like it might be a matplotlib issue when outputting to gif (requires imagemagick and therefore may not be a good example in the end). Could you try this?

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

def animate(n):
      plt.cla()
      plt.plot(np.random.rand(10,2))
      plt.ylim(0,1)

fig = plt.figure()
anim = animation.FuncAnimation(fig, animate, frames=30)
anim.save('test.gif', writer='imagemagick', fps=4)

This doesn't seem to output an animated gif (an issue I notice in Showcase as well and will need to investigate) but it should at least test if ImageMagick works on your system.

@stonebig
Copy link
Contributor Author

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-1-88cf3ba292bb> in <module>()
     10 fig = plt.figure()
     11 anim = animation.FuncAnimation(fig, animate, frames=30)
---> 12 anim.save('test.gif', writer='imagemagick', fps=4)

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs)
    778                     # TODO: Need to see if turning off blit is really necessary
    779                     anim._draw_next_frame(d, blit=False)
--> 780                 writer.grab_frame(**savefig_kwargs)
    781 
    782         # Reconnect signal for first draw if necessary

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\animation.py in grab_frame(self, **savefig_kwargs)
    223             # frame format and dpi.
    224             self.fig.savefig(self._frame_sink(), format=self.frame_format,
--> 225                              dpi=self.dpi, **savefig_kwargs)
    226         except RuntimeError:
    227             out, err = self._proc.communicate()

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\figure.py in savefig(self, *args, **kwargs)
   1537             self.set_frameon(frameon)
   1538 
-> 1539         self.canvas.print_figure(*args, **kwargs)
   1540 
   1541         if frameon:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
   2228                 orientation=orientation,
   2229                 bbox_inches_restore=_bbox_inches_restore,
-> 2230                 **kwargs)
   2231         finally:
   2232             if bbox_inches and restore_bbox:

D:\WinPython\basedir34\buildQt5\winpython-3.4.4.amd64\python-3.4.4.amd64\lib\site-packages\matplotlib\backends\backend_agg.py in print_raw(self, filename_or_obj, *args, **kwargs)
    517             close = False
    518         try:
--> 519             fileobj.write(renderer._renderer.buffer_rgba())
    520         finally:
    521             if close:

OSError: [Errno 22] Invalid argument

I think I don't have imagemagick

@stonebig
Copy link
Contributor Author

It's not listed on anaconda package index either: http://docs.continuum.io/anaconda/pkg-docs

Isn't there another way, nowodays, to achieve the required functionality ?

@jlstevens
Copy link
Contributor

Yes, ImageMagick won't be installed on windows by default (and probably not on Mac OS either).

At a minimum, in the Showcase tutorial, we should mention that ImageMagick is required for gif support, probably after the line:

%output holomap='gif'

Maybe we could even link to information on how to get it installed on those platforms. That said, the gif doesn't seem to animate on Mac OS which is also a worry...

@stonebig
Copy link
Contributor Author

I guess there is a more modern way today... searching.I see:

@jlstevens
Copy link
Contributor

ImageMagick normally works pretty well and this is what matplotlib has supported so far.

I've added a note about ImageMagick to the Showcase tutorial in commit 66d6c30. Perhaps you could follow the link mentioned there?

@stonebig
Copy link
Contributor Author

the download size is 40 Mo on 64bit windows... it's far too big for me.

could the recent Pillow 3.0 work be used (as an alternative) ? http://stackoverflow.com/questions/24688802/saving-an-animated-gif-in-pillow

@jlstevens
Copy link
Contributor

I think Pillow would be a reasonable option instead of ImageMagick. Sadly, I can't see how to make the example in the stackoverflow post work as I can't find the makedelta function in gifmaker.

I think we would have to think very carefully about including this. Pillow is nicer than ImageMagick as it is an easily installed Python library (and smaller as you point out). That said, this is something matplotlib should be concerned with and something their animation module should support. HoloViews could support making gifs with Pillow as a fallback if matplotlib fails but only if very little code is needed to make it work...

@jlstevens
Copy link
Contributor

I've searched again and found the gifmaker script. There isn't that much code in there but I would still be hesitant including it in HoloViews.

@philippjfr What do you think? I would prefer using Pillow but I don't want us to be maintaining code that really matplotlib should be handling for us. I might consider this if it also addresses the fact that the gifs don't seem to be animating properly on MacOS right now...

@stonebig
Copy link
Contributor Author

ok, It would seems indeed better spent effort that matplotlib supports it directly.

@jlstevens
Copy link
Contributor

There are also quite a few FIXME comments in the script I linked to, also making me wary.

@stonebig Perhaps you could use the gifmaker script yourself? I think we could quickly come up with an example that lets you make a gif from frames rendered with HoloViews...

@stonebig
Copy link
Contributor Author

I'm just discovering the possibility of PIL solution with you. python-pillow/Pillow#1525 (comment)

Maybe it's a little to early (yet promising)

@stonebig
Copy link
Contributor Author

Pillow easy backend seems not so far away: matplotlib/matplotlib#5750

@jlstevens
Copy link
Contributor

Great!

Good to see that the matplotlib developers are receptive to the idea of using PIL/Pillow. ImageMagick is fine on Linux but not such a great dependency on other platforms...

@stonebig
Copy link
Contributor Author

WarrenWeckesser has added a proof of concept gist today.

@jlstevens
Copy link
Contributor

@stonebig Have you heard any news about having imagemagick free GIF output? I still think it would be a nice thing to have...

@philippjfr
Copy link
Member

Renaming this issue since Showcase will be removed but gif output is still an issue on some systems.

@philippjfr philippjfr changed the title Windows issue with showcase.ipynb Gif output on Windows Jun 23, 2017
@jlstevens
Copy link
Contributor

Sadly the referenced matplotlib issue hasn't been merged, so I assume depending on imagemagick is still the only option.

@philippjfr
Copy link
Member

Looking hopeful that a Pillow based animation writer will land in matplotlib soon: matplotlib/matplotlib#10240

@jlstevens
Copy link
Contributor

Great! Let's keep an eye on that.

@philippjfr philippjfr added this to the v1.10 milestone Mar 16, 2018
@philippjfr philippjfr self-assigned this Mar 19, 2018
@philippjfr
Copy link
Member

Using matplotlib 2.2.0 it is now possible to get gif output by installing pillow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants