FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

IndexError thrown by pyplot.legend() when plotting empty bar chart with label · Issue #13003 · matplotlib/matplotlib · GitHub

Repository navigation

IndexError thrown by pyplot.legend() when plotting empty bar chart with label #13003

Closed

Description

Bug report

Bug summary

When I try to create bar chart with no data, and add a label to this chart, IndexError will be raised when trying to create legend for this plot

Code for reproduction

import matplotlib.pyplot as plt
plt.bar([], [], label='foo')
plt.legend()

Actual outcome

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    plt.legend()
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/pyplot.py", line 3823, in legend
    ret = gca().legend(*args, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 557, in legend
    self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend.py", line 699, in __init__
    self._init_legend_box(handles, labels, markerfirst)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend.py", line 954, in _init_legend_box
    fontsize, handlebox))
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend_handler.py", line 119, in legend_artist
    fontsize, handlebox.get_transform())
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend_handler.py", line 303, in create_artists
    self.update_prop(p, orig_handle, legend)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend_handler.py", line 76, in update_prop
    self._update_prop(legend_handle, orig_handle)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend_handler.py", line 69, in _update_prop
    self._update_prop_func(legend_handle, orig_handle)
  File "/opt/conda/lib/python3.6/site-packages/matplotlib/legend_handler.py", line 42, in update_from_first_child
    tgt.update_from(src.get_children()[0])
IndexError: list index out of range

Expected outcome

Matplotlib version

  • Operating system: Linux 1f8cb2653e0b 4.14.85-1-MANJARO Fix autofmt_xdate() when using in conjunction with twinx() #1 SMP PREEMPT Sat Dec 1 12:18:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Matplotlib version: 3.0.2 (installed from PyPi)
  • Matplotlib backend (print(matplotlib.get_backend())): module://backend_interagg
  • Python version: 3.6.7

Activity

  1. timhoffm commented on Dec 17, 2018

    Member

    Thanks for the report.

    Current behavior with bar()

    ax = plt.gca()
    ax.bar([], [], label='foo')
    print(ax.get_legend_handles_labels())
    ax.legend()
    

    prints ([<BarContainer object of 0 artists>], ['foo'])

    Current behavior with plot() and raises the above error.

    ax = plt.gca()
    ax.plot([], [], label='foo')
    print(ax.get_legend_handles_labels())
    ax.legend()
    

    prints ([<matplotlib.lines.Line2D object at 0x7f14fb7c10f0>], ['foo']) and renders an empty plot with a legend.

    Not sure we can bar() behave similarly.

  2. choyiny commented on Feb 26, 2019

    Contributor

    Hi, this is my first time contributing to a large scale open source project, please do pardon my beginner knowledge.

    The error originates the function update_from_first_child in legend_handler, which is called by the legend handler of BarContainer defined at legend.py:682

    def update_from_first_child(tgt, src):
            tgt.update_from(src.get_children()[0])
    

    In the case where there is no children from the original handler src, it will result in an IndexError. A simple fix like so would fix the issue:

    def update_from_first_child(tgt, src):
            try:
                tgt.update_from(src.get_children()[0])
            except IndexError:
                pass
    

    Similarly, we could first check the length of src.get_children() then only update if there is something.

    Could anyone please advise if this is the correct approach to this particular issue?

  3. VanDavv commented on Feb 26, 2019

    Author

    @choyiny I'd rather do

    def update_from_first_child(tgt, src):
        first_child = next(iter(src.get_children()), None)
        tgt.update_from(first_child)

    And handle None value either here or in tgt.update_from method

  4. added this to the v3.2.0 milestone on Mar 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL