Skip to content

BUG Ignore invisible axes in computing tight_layout - #8244

Merged
NelleV merged 4 commits into
matplotlib:masterfrom
ResidentMario:8225
Mar 12, 2017
Merged

NelleV merged 4 commits into
matplotlib:masterfrom
ResidentMario:8225

Conversation

@ResidentMario

Copy link
Copy Markdown
Contributor

cf. #8225

Should pass tests. But, we'll see. Maybe this has side-effects.

@tacaswell tacaswell added this to the 2.0.1 (next bug fix release) milestone Mar 8, 2017
@tomspur

tomspur commented Mar 9, 2017

Copy link
Copy Markdown
Contributor

This only fails pep8:
[gw1] linux -- Python 3.6.0 /home/travis/build/matplotlib/matplotlib/venv/bin/python /home/travis/build/matplotlib/matplotlib/lib/matplotlib/tight_layout.py:126:80: E501 line too long (99 > 79 characters) tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots if ax.get_visible()])

@ResidentMario

Copy link
Copy Markdown
Contributor Author

Gotcha. @tomspur Presumably I should add a test somewhere too, right?

These CIs are taking five-ever...

@tomspur

tomspur commented Mar 9, 2017

Copy link
Copy Markdown
Contributor

Yes, a test/picture helps to understand this issue and stops from breaking it again :)



@image_comparison(baseline_images=['tight_layout9'])
def test_tight_layout9():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How is this passing? The baseline images have not been added...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bear with me here, I have no idea how matplotlib handles its tests. 😅 Was planning on getting back to this in a later commit, but you've caught me red-handed.

for subplots, ax_bbox, (num1, num2) in zip(subplot_list,
ax_bbox_list,
num1num2_list):
if all([not ax.get_visible() for ax in subplots]):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

shouldn't this just be filtering out invisible axes? subplots = [ax for ox in subplots if ax.get_visible()]

Would it make more sense to make sure what ever calls method does that filtering?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yeah, I don't understand why you changed what I originally suggested. I suggested putting a filter in the list comprehension down below. Now, it does make sense to skip this iteration if all the axes in this group are invisible. So, I would put the filter in the list comprehension down below, and also change this one from a any to an all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

grrr, I fail reading comprehension... you do have a all. But the filter should still be down below.

@ResidentMario ResidentMario Mar 10, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The first commit tried that approach (see here).

But it actually failed to fix the issue. If you try to use that code with the original minimal failing example:

import matplotlib.pyplot as plt
f, axarr = plt.subplots(2, 2)
axarr[1][1].set_visible(False)
plt.tight_layout()

The union op will fail because the list comprehension will pass it an empty list ([]).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Before making a PR, please check that your commit actually fixes the issue...ahem. 😅

Skipping the laying calculations altogether (the approach here) meanwhile seems to work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, that's why you need both approaches. if a subset of the subplots are not visible, then the way the code is currently, the invisible axes still have get_tightbbox called on them, which would also fail. You need to protect that (my original approach), and protect from a union() call on an empty list (your current approach).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, I understand you now—I've re-added the conditional check.

@tacaswell

Copy link
Copy Markdown
Member

attn @NelleV @anntzer @Kojoley Something is going wrong with pytest here. Running this locally I get:

15:47 $ python -m pytest -vv lib/matplotlib/tests/test_tightlayout.py 
========================================================================================================================================================================================================= test session starts ==========================================================================================================================================================================================================
platform linux -- Python 3.6.0, pytest-3.0.6, py-1.4.32, pluggy-0.4.0 -- /tmp/mpl_stock/bin/python
cachedir: .cache
rootdir: /home/tcaswell/source/p/matplotlib, inifile: pytest.ini
collected 36 items 

lib/matplotlib/tests/test_tightlayout.py::test_tight_layout1[0-tight_layout1-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout1[0-tight_layout1-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout1[0-tight_layout1-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout2[0-tight_layout2-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout2[0-tight_layout2-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout2[0-tight_layout2-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout3[0-tight_layout3-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout3[0-tight_layout3-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout3[0-tight_layout3-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout4[0-tight_layout4-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py XPASS
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout4[0-tight_layout4-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py XPASS
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout4[0-tight_layout4-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py XPASS
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout5[0-tight_layout5-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout5[0-tight_layout5-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout5[0-tight_layout5-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout6[0-tight_layout6-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout6[0-tight_layout6-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout6[0-tight_layout6-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout7[0-tight_layout7-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout7[0-tight_layout7-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout7[0-tight_layout7-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout8[0-tight_layout8-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout8[0-tight_layout8-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout8[0-tight_layout8-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout9[0-tight_layout9-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py xfail
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout9[0-tight_layout9-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py xfail
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout9[0-tight_layout9-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py xfail
lib/matplotlib/tests/test_tightlayout.py::test_outward_ticks[0-outward_ticks-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_outward_ticks[0-outward_ticks-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_outward_ticks[0-outward_ticks-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[0-tight_layout_offsetboxes1-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[0-tight_layout_offsetboxes1-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[0-tight_layout_offsetboxes1-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[1-tight_layout_offsetboxes2-png] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[1-tight_layout_offsetboxes2-pdf] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED
lib/matplotlib/tests/test_tightlayout.py::test_tight_layout_offsetboxes[1-tight_layout_offsetboxes2-svg] <- /home/tcaswell/source/p/matplotlib/lib/matplotlib/tests/test_tightlayout.py PASSED

=========================================================================================================================================================================================== 30 passed, 3 xfailed, 3 xpassed in 10.63 seconds ===========================================================================================================================================================================================

I would expect the three xfail to be real fails (due to missing files).

@anntzer

anntzer commented Mar 10, 2017

Copy link
Copy Markdown
Contributor

This is the culprit (decorators.py, copy_baseline):

        if os.path.exists(orig_expected_fname):
            shutil.copyfile(orig_expected_fname, expected_fname)
        else:
            reason = ("Do not have baseline image {0} because this "
                      "file does not exist: {1}".format(expected_fname,
                                                        orig_expected_fname))
            if is_called_from_pytest():
                import pytest
                pytest.xfail(reason)
            else:
                from ._nose import knownfail
                knownfail(reason)
        return expected_fname

I would just remove that chunk and replace by a real fail in the actual test function.

@tacaswell

Copy link
Copy Markdown
Member

See #8262 for a fix to my previous comment, sorry to have hi-jacked this PR with other issues.

@ResidentMario

Copy link
Copy Markdown
Contributor Author

Always happy to be breaking things productively. 👍

@ResidentMario

Copy link
Copy Markdown
Contributor Author

This passes tests locally, except for an unrelated error in tight_layout8. A different unrelated failure appears to occur on travis (which reset and is now running again for some reason?).

@NelleV

NelleV commented Mar 12, 2017

Copy link
Copy Markdown
Member

We have some flaky test, so we sometimes restart some tests by hand (hence travis rerunning magically :) )

@ResidentMario

Copy link
Copy Markdown
Contributor Author

All green. LGTM?

@tacaswell tacaswell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Only concern would be if we really need the image comparison tests here. The bug it is fixing is 'do raise'.

@NelleV
NelleV merged commit 27f6781 into matplotlib:master Mar 12, 2017
@NelleV

NelleV commented Mar 12, 2017

Copy link
Copy Markdown
Member

Thanks @ResidentMario !



@image_comparison(baseline_images=['tight_layout9'])
def test_tight_layout9():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There are now two test functions in one file with the same name. So the first one gets clobbered by the second one.

@WeatherGod WeatherGod Mar 16, 2017 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sorry, please ignore. I misread test_tight_layout8 as test_tight_layout9. Really need to fix the default fonts on this computer...

QuLogic pushed a commit to QuLogic/matplotlib that referenced this pull request Mar 27, 2017
BUG Ignore invisible axes in computing tight_layout
@QuLogic

QuLogic commented Mar 27, 2017

Copy link
Copy Markdown
Member

Backported to v2.0.x as 3ff1153.

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

Successfully merging this pull request may close these issues.

7 participants