Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Reset the available animation movie writer on rcParam change #5628

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

Merged
merged 7 commits into from
Feb 7, 2016

Conversation

jankatins
Copy link
Contributor

If one of the rcParams for a path to a program, which was called by a
movie writer, is changed, the the available movie writer in the
registry should be reevaluated if they are (still/became) available.

This also fixes the problem that you have to set the path to a movie
writer before importing mpl.animation, as before the state was
fixed on import time.

Closes: #5616

@tacaswell tacaswell added this to the proposed next point release (2.1) milestone Dec 8, 2015
"""Reset the available state of all registered writers"""
self.avail = {}
for name, writerClass in self._registered.items():
if writerClass.isAvailable():
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: should that be "is_available"? It's the only method in that class(es) which use CamelCase instead of underscores...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is annoying, but I don't think worth breaking user code over.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At most, we can rename and add an alias isAvailable -> is_available with the @deprecated decorator.

@jankatins jankatins force-pushed the ani_writer branch 2 times, most recently from 7d847ea to b46d8aa Compare December 9, 2015 14:53
@jankatins
Copy link
Contributor Author

Apart from the possible deprecation (which should go to a different PR), IMO this is ready to go in...

if writerClass.isAvailable():
self.avail[name] = writerClass
return writerClass
return wrapper

def endsure_not_dirty(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should endsure be ensure?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Omg, fix is on the way...

@jankatins
Copy link
Contributor Author

Ping?

if not isinstance(p, six.text_type):
raise ValueError("path must be a (unicode) string")
from sys import modules
# set dirty, so that the next call to the reistry will reevaluate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... registry will re-evaluate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done and repushed

@dopplershift
Copy link
Contributor

Minor comment nit, otherwise this is 👍 from me.

If one of the rcParams for a path to a program, which was called by a
movie writer, is changed, the the available movie writer in the
registry should be reevaluated if they are (still/became) available.

This also fixes the problem that you have to set the path to a movie
writer before importing mpl.animation, as before the state was
fixed on import time.
python is blocking, leading to timeouts...
@jankatins
Copy link
Contributor Author

cleaned up the typo and repushed

animation.writers.list() # resets
assert_false(animation.writers._dirty)
assert_false(animation.writers.is_available("ffmpeg"))
# something which is garanteered to be available in path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"garanteered"?

@WeatherGod
Copy link
Member

Appveyor is having all sorts of failures, some of them having to do with animation stuff, so I am not entirely certain if it is the usual failures or not.

On windows the check ensures that the imagemagick path for 'convert' was
set to '' if it was just 'convert' to prevent clashes with the windows
built-in command 'convert' (doing filesystem conversion). Unfortunately,
the command only set this values in the current rcParams and rcParamsDefault,
but a use of `matplotlib.style.use("classic")` after importing mpl.animation
would again overwrite it with `convert`.

In this case, the image comparison decorator sets the style to classic and
appveyor went BOOM...
@jankatins
Copy link
Contributor Author

The imagemagic problem is that the workaround for masking convert on windows (which is always available to to the internal convert.exefrom windows) is undone by a later call to matplotlib.style.use("classic") in the image comparison decorator...

It seems that the workaround should also be applied in the is_available method...

And for your daily dose of WTF:

c:\data\external\R
λ C:\Users\jschulz\Dropbox\Programme\cmder\vendor\imagemagick\convert --version
Version: ImageMagick 7.0.0-0 Q16 x64 2016-01-23 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2015 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Visual C++: 180040629
Features: Cipher DPC HDRI
Delegates (built-in): bzlib cairo freetype jng jp2 jpeg lcms lqr openexr pangocairo png ps rsvg tiff webp xml zlib

c:\data\external\R
λ echo %errorlevel%
1
c:\data\external\R                         
λ convert                                  
Ein Dateisystem muss angegeben werden.     

c:\data\external\R                         
λ echo %errorlevel%                        
4                                          

and running the tests with mpl.verbose.set_level("debug") triggers a different bug (pobably in subprocess)?:

======================================================================
ERROR: matplotlib.tests.test_animation.test_save_animation_smoketest('mencoder_file', 'mp4')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\site-packages\nose\case.py", line 198, in runTest
    self.test(*self.arg)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\testing\decorators.py", line 152, in wrapped_callable

    func(*args, **kwargs)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\tests\test_animation.py", line 137, in check_save_animation
    anim.save(F.name, fps=30, writer=writer, bitrate=500)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 893, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\contextlib.py", line 66, in __exit__
    next(self.gen)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 174, in saving
    self.finish()
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 453, in finish
    self._run()
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 283, in _run
    creationflags=subprocess_creation_flags)
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\subprocess.py", line 914, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\subprocess.py", line 1145, in _get_handles
    c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
io.UnsupportedOperation: fileno

@jankatins
Copy link
Contributor Author

I also currently have a bug that mencoder returns 3:

======================================================================
ERROR: matplotlib.tests.test_animation.test_save_animation_smoketest('mencoder_file', 'mp4')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\site-packages\nose\case.py", line 198, in runTest
    self.test(*self.arg)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\testing\decorators.py", line 152, in wrapped_callable

    func(*args, **kwargs)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\tests\test_animation.py", line 140, in check_save_animation
    anim.save(F.name, fps=30, writer=writer, bitrate=500)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 894, in save
    writer.grab_frame(**savefig_kwargs)
  File "C:\portabel\miniconda\envs\matplotlib_build\lib\contextlib.py", line 66, in __exit__
    next(self.gen)
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 174, in saving
    self.finish()
  File "c:\data\external\pydata\matplotlib\lib\matplotlib\animation.py", line 462, in finish
    + ' Try running with --verbose-debug')
RuntimeError: Error creating movie, return code: 3 Try running with --verbose-debug

I've actually no clue why that's happens :-/ Anyone with mencoder knowledge here?

@jankatins
Copy link
Contributor Author

The error seems to be this (pull from self._proc._stderr_buff via the debugger):

[b"
WARNING: OUTPUT FILE FORMAT IS _AVI_. See -of help.
[mpeg4 @ 00000000019034e0]AVFrame.format is not set
[mpeg4 @ 00000000019034e0]AVFrame.width or height is not set

[mpeg4 @ 00000000019034e0]AVFrame.format is not set
[mpeg4 @ 00000000019034e0]AVFrame.width or height is not set

[mpeg4 @ 00000000019034e0]AVFrame.format is not set
[mpeg4 @ 00000000019034e0]AVFrame.width or height is not set

[mpeg4 @ 00000000019034e0]AVFrame.format is not set
[mpeg4 @ 00000000019034e0]AVFrame.width or height is not set

[mpeg4 @ 00000000019034e0]AVFrame.format is not set
[mpeg4 @ 00000000019034e0]AVFrame.width or height is not set
Assertion v>0 && v<=(1 ? 32 : 16) failed at libavutil/mem.c:233

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
"]

@jankatins
Copy link
Contributor Author

It seems the problem is this: Assertion v>0 && v<=(1 ? 32 : 16) failed at libavutil/mem.c:233. I've no clue what that means but it seems that others also have no clue, at least I didn't find any proper answer by googling :-(

E.g. here: http://ehc.ac/p/mplayer-win32/bugs/179/ -> unanswered :-(

I use this build: http://mplayerwin.sourceforge.net/downloads.html (build mplayer-svn-37610-x86_64.7z)

-> not a mpl bug and so IMO if this passes (without mplayer/mencoder, which is not installed on appveyor) and no one finds another typo :-), this is IMO good to merge...

This pulls out the stderr and stdout from the internal POpen buffers (tested
on py3.5 and not shown if any error occures while pulling out the messages...).

It also changes the exception message to mention mpl.verbose.set_level("helpful")
because adding a commandline switch is probably not helpful in todays world where
everybody uses the Jupyter notebook and can't add to the kernel commandline...

It would be nice if this verbose level could be set by nose / tests.py, but I
have found no way yet :-(
verbose.report("MovieWriter.finish: stdout: %s" % stdout, level='helpful')
verbose.report("MovieWriter.finish: stderr: %s" % stderr, level='helpful')
except Exception as e:
pass
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not my finest code, but it works on py35...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to provide improved debugging feed back right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, when the called converter fails and the user adds the mpl.verbose.set_level("helpful") before calling the failing method again...

Unfortunately, it doesn't work for the unittests unless I add such a set_level call in the unittest file :-(

@tacaswell
Copy link
Member

Looks like some long lines have crept in

======================================================================
FAIL: matplotlib.tests.test_coding_standards.test_pep8_conformance_installed_files
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/matplotlib/matplotlib/venv/lib/python3.5/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/travis/build/matplotlib/matplotlib/lib/matplotlib/tests/test_coding_standards.py", line 249, in test_pep8_conformance_installed_files
    expected_bad_files=expected_bad_files)
  File "/home/travis/build/matplotlib/matplotlib/lib/matplotlib/tests/test_coding_standards.py", line 143, in assert_pep8_conformance
    assert_equal(result.total_errors, 0, msg)
AssertionError: 3 != 0 : Found code syntax errors (and warnings):
/home/travis/build/matplotlib/matplotlib/lib/matplotlib/animation.py:462:80: E501 line too long (90 > 79 characters)
/home/travis/build/matplotlib/matplotlib/lib/matplotlib/animation.py:463:80: E501 line too long (90 > 79 characters)
/home/travis/build/matplotlib/matplotlib/lib/matplotlib/animation.py:468:80: E501 line too long (81 > 79 characters)

@tacaswell
Copy link
Member

👍 modulo small comments / pep8

@jankatins
Copy link
Contributor Author

Oh damn, I really should add a pep8 precommit / prepush hook in the matplotlib repo...

Ok, added comments and hopefully fixed the PEP8 thingies...

tacaswell added a commit that referenced this pull request Feb 7, 2016
Reset the available animation movie writer on rcParam change
@tacaswell tacaswell merged commit 424556b into matplotlib:master Feb 7, 2016
@efiring
Copy link
Member

efiring commented Oct 18, 2016

@tacaswell, it looks to me like this could be backported to v2.x, in the spirit of making 2.0 less likely to trip people up.

@tacaswell
Copy link
Member

I completely forget about this and was contemplating re-writing it to fix issues that Christoph reported.

tacaswell added a commit to tacaswell/matplotlib that referenced this pull request Oct 19, 2016
Reset the available animation movie writer on rcParam change
NelleV added a commit that referenced this pull request Oct 19, 2016
Merge pull request #5628 from JanSchulz/ani_writer
@efiring
Copy link
Member

efiring commented Oct 22, 2016

backported to v2.x via #7306

@QuLogic QuLogic modified the milestones: 2.0.1 (next bug fix release), 2.1 (next point release) Oct 22, 2016
@QuLogic QuLogic modified the milestones: 2.0.1 (next bug fix release), 2.0 (style change major release) Dec 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Better error message if no animation writer is available
7 participants