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

[Bug] .gif files don't loop #24

Closed
TomNicholas opened this issue Nov 29, 2018 · 5 comments
Closed

[Bug] .gif files don't loop #24

TomNicholas opened this issue Nov 29, 2018 · 5 comments

Comments

@TomNicholas
Copy link
Contributor

TomNicholas commented Nov 29, 2018

.gif files created with animatplot only run once through, then stop on the final frame. They do loop properly when running interactively (in a Jupyter notebook) though.

I'm creating a gif in a jupyter notebook, using %matplotlib notebook. I save the gif, then try to open it using

![Ising](ising.gif "ising")

This displays the gif once through, then it stops on the final frame. If I rerun the cell then it just opens a static image of the final frame.

If I open the .gif file with another program it also stops on the final frame, so I think it's a problem with the created file.

I've tried explicitly passing repeat=True to FuncAnimation() inside animatplot.Animation, and I've also tried using the imagemagick writer rather than PillowWriter, but the problem persists.

A reproducible example, which is basically just this example):

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import animatplot as amp
# Define LxL matrix
L = 55
# Initialize as random spin
M = 2*(np.random.rand(L,L)>.5)-1
J = 1
b = 2.5

nPer = 100

images = [M]
for i in range(100):
    M = M.copy()
    for dm in range(nPer):
        jj = int(np.random.rand()*L - 1)
        kk = int(np.random.rand()*L - 1)
        dE = 2*J*(M[jj+1,kk] + M[jj-1,kk] + M[jj,kk+1] + M[jj,kk-1])*M[jj,kk]
        if dE <= 0:
            M[jj,kk]*=-1
        else:
            if(np.random.rand()<np.exp(-b*dE)):
                M[jj,kk]*=-1
    images.append(M)
    M[:,-1] = M[:,0]
    M[-1,:] = M[0,:]
fig1, ax1 = plt.subplots()

block = amp.blocks.Imshow(images, axis=ax1)
anim = amp.Animation([block])

anim.controls()
anim.save_gif('ising')
![Ising](ising.gif "ising")

Also the output of using conda list to see which versions of everything I'm using:

# Name                    Version                   Build
alabaster                 0.7.12                   py36_0  
anaconda                  custom           py36hbbc8b67_0  
anaconda-client           1.7.2                    py36_0  
anaconda-project          0.8.2                    py36_0  
animatplot                0.4.0.dev1                <pip>
appdirs                   1.4.3            py36h28b3542_0  
asn1crypto                0.24.0                   py36_0  
astroid                   2.0.4                    py36_0  
astropy                   3.0.5            py36h7b6447c_0  
atomicwrites              1.2.1                    py36_0  
attrs                     18.2.0           py36h28b3542_0  
automat                   0.7.0                    py36_0  
babel                     2.6.0                    py36_0  
backcall                  0.1.0                    py36_0  
backports                 1.0                      py36_1  
backports.os              0.1.1                    py36_0  
backports.shutil_get_terminal_size 1.0.0                    py36_2  
beautifulsoup4            4.6.3                    py36_0  
bitarray                  0.8.3            py36h14c3975_0  
bkcharts                  0.2                      py36_0  
blas                      1.0                         mkl  
blaze                     0.11.3                   py36_0  
bleach                    3.0.2                    py36_0  
blosc                     1.14.4               hdbcaa40_0  
bokeh                     1.0.1                    py36_0  
boto                      2.49.0                   py36_0  
bottleneck                1.2.1            py36h035aef0_1  
bzip2                     1.0.6                h14c3975_5  
ca-certificates           2018.03.07                    0  
cairo                     1.14.12              h8948797_3  
certifi                   2018.10.15               py36_0  
cffi                      1.11.5           py36he75722e_1  
cftime                    1.0.2.1          py36hdd07704_0  
chardet                   3.0.4                    py36_1  
click                     7.0                      py36_0  
cloudpickle               0.6.1                    py36_0  
clyent                    1.2.2                    py36_1  
colorama                  0.4.0                    py36_0  
constantly                15.1.0           py36h28b3542_0  
contextlib2               0.5.5                    py36_0  
cryptography              2.3.1            py36hc365091_0  
curl                      7.61.0               h84994c4_0  
cycler                    0.10.0                   py36_0  
cython                    0.29             py36he6710b0_0  
cytoolz                   0.9.0.1          py36h14c3975_1  
dask                      0.20.2                   py36_0  
dask-core                 0.20.2                   py36_0  
datashape                 0.5.4                    py36_1  
dbus                      1.13.2               h714fa37_1  
decorator                 4.3.0                    py36_0  
defusedxml                0.5.0                    py36_1  
distributed               1.24.2                   py36_0  
docutils                  0.14                     py36_0  
entrypoints               0.2.3                    py36_2  
et_xmlfile                1.0.1                    py36_0  
expat                     2.2.6                he6710b0_0  
experi                    0.2.11                    <pip>
fastcache                 1.0.2            py36h14c3975_2  
filelock                  3.0.10                   py36_0  
flask                     1.0.2                    py36_1  
flask-cors                3.0.7                    py36_0  
fontconfig                2.13.0               h9420a91_0  
freetype                  2.9.1                h8a8886c_1  
fribidi                   1.0.5                h7b6447c_0  
get_terminal_size         1.0.0                haa9412d_0  
gevent                    1.3.7            py36h7b6447c_1  
glib                      2.56.2               hd408876_0  
glob2                     0.6                      py36_1  
gmp                       6.1.2                h6c8ec71_1  
gmpy2                     2.0.8            py36h10f8cd9_2  
graphite2                 1.3.12               h23475e2_2  
greenlet                  0.4.15           py36h7b6447c_0  
gst-plugins-base          1.14.0               hbbd80ab_1  
gstreamer                 1.14.0               hb453b48_1  
h5py                      2.8.0            py36h989c5e5_3  
harfbuzz                  1.8.8                hffaf4a1_0  
hdf4                      4.2.13               h3ca952b_2  
hdf5                      1.10.2               hba1933b_1  
heapdict                  1.0.0                    py36_2  
html5lib                  1.0.1                    py36_0  
hyperlink                 18.0.0                   py36_0  
icu                       58.2                 h9c2bf20_1  
idna                      2.7                      py36_0  
imageio                   2.4.1                    py36_0  
imagesize                 1.1.0                    py36_0  
importlib_metadata        0.6                      py36_0  
incremental               17.5.0                   py36_0  
intel-openmp              2019.1                      144  
ipykernel                 5.1.0            py36h39e3cac_0  
ipython                   7.1.1            py36h39e3cac_0  
ipython_genutils          0.2.0                    py36_0  
ipywidgets                7.4.2                    py36_0  
isort                     4.3.4                    py36_0  
itsdangerous              1.1.0                    py36_0  
jbig                      2.1                  hdba287a_0  
jdcal                     1.4                      py36_0  
jedi                      0.13.1                   py36_0  
jeepney                   0.4                      py36_0  
jinja2                    2.10                     py36_0  
jpeg                      9b                   h024ee3a_2  
jsonschema                2.6.0                    py36_0  
jupyter                   1.0.0                    py36_7  
jupyter_client            5.2.3                    py36_0  
jupyter_console           6.0.0                    py36_0  
jupyter_core              4.4.0                    py36_0  
jupyterlab                0.35.3                   py36_0  
jupyterlab_launcher       0.13.1                   py36_0  
jupyterlab_server         0.2.0                    py36_0  
keyring                   16.1.0                   py36_0  
kiwisolver                1.0.1            py36hf484d3e_0  
lazy-object-proxy         1.3.1            py36h14c3975_2  
libcurl                   7.61.0               h1ad7b7a_0  
libedit                   3.1.20170329         h6b74fdf_2  
libffi                    3.2.1                hd88cf55_4  
libgcc-ng                 8.2.0                hdf63c60_1  
libgfortran-ng            7.3.0                hdf63c60_0  
libnetcdf                 4.6.1                h10edf3e_1  
libpng                    1.6.35               hbc83047_0  
libsodium                 1.0.16               h1bed415_0  
libssh2                   1.8.0                h9cfc8f7_4  
libstdcxx-ng              8.2.0                hdf63c60_1  
libtiff                   4.0.9                he85c1e1_2  
libtool                   2.4.6                h7b6447c_5  
libuuid                   1.0.3                h1bed415_2  
libxcb                    1.13                 h1bed415_1  
libxml2                   2.9.8                h26e45fe_1  
libxslt                   1.1.32               h1312cb7_0  
llvmlite                  0.25.0           py36hd408876_0  
locket                    0.2.0                    py36_1  
lxml                      4.2.5            py36hefd8a0e_0  
lzo                       2.10                 h49e0be7_2  
markupsafe                1.1.0            py36h7b6447c_0  
matplotlib                3.0.1            py36h5429711_0  
mccabe                    0.6.1                    py36_1  
mistune                   0.8.4            py36h7b6447c_0  
mkl                       2018.0.3                      1  
mkl-service               1.1.2            py36h90e4bf4_5  
mkl_fft                   1.0.6            py36h7dd41cf_0  
mkl_random                1.0.1            py36h4414c95_1  
more-itertools            4.3.0                    py36_0  
mpc                       1.1.0                h10f8cd9_1  
mpfr                      4.0.1                hdf1c602_3  
mpmath                    1.0.0                    py36_2  
msgpack-python            0.5.6            py36h6bb024c_1  
multipledispatch          0.6.0                    py36_0  
natsort                   5.5.0                     <pip>
nbconvert                 5.3.1                    py36_0  
nbformat                  4.4.0                    py36_0  
ncurses                   6.1                  he6710b0_1  
netcdf4                   1.4.2            py36h4b4f87f_0  
networkx                  2.2                      py36_1  
nltk                      3.3.0                    py36_0  
nose                      1.3.7                    py36_2  
notebook                  5.7.2                    py36_0  
numba                     0.40.0           py36h962f231_0  
numexpr                   2.6.8            py36hd89afb7_0  
numpy                     1.15.4           py36h1d66e8a_0  
numpy-base                1.15.4           py36h81de0dd_0  
numpydoc                  0.8.0                    py36_0  
odo                       0.5.1                    py36_0  
olefile                   0.46                     py36_0  
openpyxl                  2.5.9                    py36_0  
openssl                   1.0.2p               h14c3975_0  
packaging                 18.0                     py36_0  
pandas                    0.23.4           py36h04863e7_0  
pandoc                    2.2.3.2                       0  
pandocfilters             1.4.2                    py36_1  
pango                     1.42.4               h049681c_0  
parso                     0.3.1                    py36_0  
partd                     0.3.9                    py36_0  
patchelf                  0.9                  he6710b0_3  
path.py                   11.5.0                   py36_0  
pathlib2                  2.3.2                    py36_0  
patsy                     0.5.1                    py36_0  
pcre                      8.42                 h439df22_0  
pep8                      1.7.1                    py36_0  
pexpect                   4.6.0                    py36_0  
pickleshare               0.7.5                    py36_0  
pillow                    5.3.0            py36h34e0f95_0  
pip                       18.1                     py36_0  
pixman                    0.34.0               hceecf20_3  
pkginfo                   1.4.2                    py36_1  
pluggy                    0.8.0                    py36_0  
ply                       3.11                     py36_0  
prometheus_client         0.4.2                    py36_0  
prompt_toolkit            2.0.7                    py36_0  
psutil                    5.4.8            py36h7b6447c_0  
ptyprocess                0.6.0                    py36_0  
py                        1.7.0                    py36_0  
pyasn1                    0.4.4            py36h28b3542_0  
pyasn1-modules            0.2.2                    py36_0  
pycodestyle               2.4.0                    py36_0  
pycosat                   0.6.3            py36h14c3975_0  
pycparser                 2.19                     py36_0  
pycrypto                  2.6.1            py36h14c3975_9  
pycurl                    7.43.0.2         py36hb7f436b_0  
pyflakes                  2.0.0                    py36_0  
pygments                  2.2.0                    py36_0  
pyhamcrest                1.9.0                    py36_2  
pylint                    2.1.1                    py36_0  
pyodbc                    4.0.24           py36he6710b0_0  
pyopenssl                 18.0.0                   py36_0  
pyparsing                 2.3.0                    py36_0  
pyqt                      5.9.2            py36h05f1152_2  
pysocks                   1.6.8                    py36_0  
pytables                  3.4.4            py36ha205bf6_0  
pytest                    4.0.0                    py36_0  
pytest-arraydiff          0.2              py36h39e3cac_0  
pytest-astropy            0.4.0                    py36_0  
pytest-doctestplus        0.2.0                    py36_0  
pytest-openfiles          0.3.0                    py36_0  
pytest-remotedata         0.3.1                    py36_0  
python                    3.6.6                h6e4f718_2  
python-dateutil           2.7.5                    py36_0  
pytz                      2018.7                   py36_0  
pywavelets                1.0.1            py36hdd07704_0  
pyyaml                    3.13             py36h14c3975_0  
pyzmq                     17.1.2           py36h14c3975_0  
qt                        5.9.6                h8703b6f_2  
qtawesome                 0.5.3                    py36_0  
qtconsole                 4.4.2                    py36_0  
qtpy                      1.5.2                    py36_0  
readline                  7.0                  h7b6447c_5  
requests                  2.20.1                   py36_0  
rope                      0.11.0                   py36_0  
ruamel_yaml               0.15.46          py36h14c3975_0  
scikit-image              0.14.0           py36hf484d3e_1  
scikit-learn              0.20.1           py36h4989274_0  
scipy                     1.1.0            py36hfa4b5c9_1  
seaborn                   0.9.0                    py36_0  
secretstorage             3.1.0                    py36_0  
send2trash                1.5.0                    py36_0  
service_identity          17.0.0           py36h28b3542_0  
setuptools                40.6.2                   py36_0  
simplegeneric             0.8.1                    py36_2  
singledispatch            3.4.0.3                  py36_0  
sip                       4.19.8           py36hf484d3e_0  
six                       1.11.0                   py36_1  
snappy                    1.1.7                hbae5bb6_3  
snowballstemmer           1.2.1                    py36_0  
sortedcollections         1.0.1                    py36_0  
sortedcontainers          2.0.5                    py36_0  
sphinx                    1.8.2                    py36_0  
sphinxcontrib             1.0                      py36_1  
sphinxcontrib-websupport  1.1.0                    py36_1  
spyder                    3.3.2                    py36_0  
spyder-kernels            0.3.0                    py36_0  
sqlalchemy                1.2.14           py36h7b6447c_0  
sqlite                    3.25.3               h7b6447c_0  
statsmodels               0.9.0            py36h035aef0_0  
sympy                     1.3                      py36_0  
tblib                     1.3.2                    py36_0  
terminado                 0.8.1                    py36_1  
testpath                  0.4.2                    py36_0  
tk                        8.6.8                hbc83047_0  
toolz                     0.9.0                    py36_0  
tornado                   5.1.1            py36h7b6447c_0  
tqdm                      4.28.1           py36h28b3542_0  
traitlets                 4.3.2                    py36_0  
twisted                   18.9.0           py36h7b6447c_0  
typed-ast                 1.1.0            py36h14c3975_0  
unicodecsv                0.14.1                   py36_0  
unixodbc                  2.3.7                h14c3975_0  
urllib3                   1.23                     py36_0  
wcwidth                   0.1.7                    py36_0  
webencodings              0.5.1                    py36_1  
werkzeug                  0.14.1                   py36_0  
wheel                     0.32.3                   py36_0  
widgetsnbextension        3.4.2                    py36_0  
wrapt                     1.10.11          py36h14c3975_2  
wurlitzer                 1.0.2                    py36_0  
xarray                    0.10.9+50.g17815b4           <pip>
xBOUT                     0.1                       <pip>
xcollect                  0.1                       <pip>
xlrd                      1.1.0                    py36_1  
xlsxwriter                1.1.2                    py36_0  
xlwt                      1.3.0                    py36_0  
xstorm                    0.1                       <pip>
xz                        5.2.4                h14c3975_4  
yaml                      0.1.7                had09818_2  
zeromq                    4.2.5                hf484d3e_1  
zict                      0.1.3                    py36_0  
zlib                      1.2.11               h7b6447c_3  
zope                      1.0                      py36_1  
zope.interface            4.6.0            py36h7b6447c_0
@t-makaro
Copy link
Owner

This is actually a bug with matplotlib's pillowWriter. See matplotlib/matplotlib#11787. I submitted a bug fix and it will be released with matplotlib 3.1. I actually monkey patched the fix into my local version of matplotlib, so that when I made the documentation the gif's looped.

You can use anim.save('image.gif', writer='imagemagick') as a work around for now. If imagemagick isn't making looping gifs, then matplotlib may not be finding imagemagick and defaulting back to PillowWriter. See matplotlib/matplotlib#11792

@TomNicholas
Copy link
Contributor Author

Changing to imagemagick with that command worked, thanks!

@educhana
Copy link

As a workaround using Pillow, you can subclass PillowWriter:

from matplotlib.animation import PillowWriter    

class LoopingPillowWriter(PillowWriter):
    def finish(self):
        self._frames[0].save(
            self._outfile, save_all=True, append_images=self._frames[1:],
            duration=int(1000 / self.fps), loop=0)

ani = ArtistAnimation(fig, images)
ani.save('data.gif', writer=LoopingPillowWriter(fps=15))    

@jonnyhtw
Copy link

Just to note that I am having this error too and look forward to a fix from the matplotlib folks.

Loving this software though!

Cheers

@jonnyhtw
Copy link

... Just a quick note to say that a quick workaround is to save the gif and then run this at the terminal...

> convert -loop 0 mygif.gif mygif.gif

Works for me!

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

4 participants