Skip to content

DataFrame.hist() does not get along with matplotlib.pyplot.tight_layout() #9351

Description

@vfilimonov

When tight_layout() is called after DataFrame.hist() it raises AttributeError: 'NoneType' object has no attribute 'is_bbox if any of subplots is empty (number of charts with histograms is smaller than number os subplots).

I.e. the following code:

pd.DataFrame({'a':np.random.randn(100),
              'b':np.random.randn(100),
              }).hist()
plt.tight_layout()

works fine, but this code:

pd.DataFrame({'a':np.random.randn(100),
              'b':np.random.randn(100),
              'c':np.random.randn(100),
              }).hist()
plt.tight_layout()

raises AttributeError.

My versions:
pandas: 0.15.2
numpy: 1.9.1
scipy: 0.14.1
IPython: 2.3.1
matplotlib: 1.4.2

Activity

  1. ericmjl commented on May 19, 2015

    @ericmjl

    Ditto here, I can't seem to figure out what's going on.

  2. TomAugspurger commented on May 19, 2015

    @TomAugspurger
    Contributor

    Would either of you want to dig into what's causing the problem?

    It seems that

        129         tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots])

    in matplotlib.tight_layout.auto_adjust_subplotpars returns None when it's expected to return a BBox.

  3. goyodiaz commented on Dec 15, 2015

    @goyodiaz
    Contributor

    Actually, just before the error is raised, subplots is a list of one AxesSubplot instance for which get_visible() returns False. ax.get_tightbbox() returns None for invisible axes and auto_adjust_subplotpars() pass this None to TransformedBbox(), which expects a real Bbox and raises the exception.

    Looks like a matplotlib issue to me, or maybe pandas should not be creating that invisible Axes.

    A quick workaround would be to add something like this:

    if tight_bbox_raw is None:
        continue
    

    But it might have side effects.

  4. miraculixx commented on Feb 25, 2016

    @miraculixx

    +1

  5. added this to the milestone on Feb 26, 2016
  6. ResidentMario commented on Feb 26, 2017

    @ResidentMario
    Contributor

    As of matplotlib 2.0 this now works as expected.

  7. jreback commented on Feb 26, 2017

    @jreback
    Contributor

    @ResidentMario can you add a test to confirm this behavior (that skips if mpl < 2.0)?

  8. modified the milestones: 0.20.0, on Feb 27, 2017
  9. 7 remaining items

  10. reopened this on Mar 7, 2017
  11. ResidentMario commented on Mar 7, 2017

    @ResidentMario
    Contributor

    This boils down to a matplotlib bug. This is what pandas is doing internally, which fails:

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

    Going about it a slightly different way, this works:

    import matplotlib.pyplot as plt
    f, axarr = plt.subplots(2, 2)
    axarr[1][1].axis('off')
    plt.tight_layout()
  12. ResidentMario commented on Mar 12, 2017

    @ResidentMario
    Contributor

    This is now fixed downstream in matplotlib as #8255 by PR#8244. Once matplotlib 2.0.1 lands this issue will be fixed and can be closed (use mpl > 2.0.1). For the moment best to leave it open though.

  13. jreback commented on Mar 13, 2017

    @jreback
    Contributor

    thanks @ResidentMario ok can update the release note at some point. any additional tests needed?

  14. ResidentMario commented on Mar 13, 2017

    @ResidentMario
    Contributor

    @jreback I would say no, the PR included a regression test for this in the matplotlib test suite.

  15. jreback commented on Mar 13, 2017

    @jreback
    Contributor

    @ResidentMario the regression test passed though, contrary to the bug fix that was needed, right? (IIRC you did another PR which added a slightly different test which failed though..?)

  16. jreback commented on Mar 13, 2017

    @jreback
    Contributor

    this was corrected in 03dca96

    any reason not to close this issue?

  17. added a commit that references this issue on Mar 13, 2017
  18. ResidentMario commented on Mar 13, 2017

    @ResidentMario
    Contributor

    @jreback Wasn't sure what best practice is for telling users to use a version of a downstream library which may or may not be out yet (maybe pandas 0.20.0 will beat matplotlib 2.0.1 to release). But since the update note is already in place, sure this issue can be closed—but, you should remove the errant test first (see the PR above).

  19. jorisvandenbossche commented on Mar 13, 2017

    @jorisvandenbossche
    Member

    Yeah, I saw the typo of 0.2 vs 2.0, and thought to directly make this 2.0.1, because that is more correct.

  20. added a commit that references this issue on Mar 13, 2017
    998c801
  21. added a commit that references this issue on Apr 3, 2017
    39171b5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions