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

Skip to content

[Bug]: .remove() on ErrorbarContainer object does not remove the corresponding item from the legend #25274

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

Closed
shntrnkgw opened this issue Feb 21, 2023 · 6 comments · Fixed by #29401
Milestone

Comments

@shntrnkgw
Copy link

Bug summary

When I do .remove() on ErrorbarContainer objects returned from Axes.errorbar(), the objects are removed from the plot but the legend items are not removed.

Code for reproduction

# coding="utf-8"

from matplotlib import pyplot

if __name__ == "__main__":
    
    ax = pyplot.gca()

    obj1 = ax.errorbar([1], [1], [1], marker="o", label="foo")

    pyplot.legend()
    pyplot.savefig("test_errorbar_1.pdf") # it has "foo" in the legend as expected

    obj1.remove() # this should remove obj1 from the axes

    ax.errorbar([1.1], [1.1], [1], marker="o", label="bar")

    pyplot.legend()
    pyplot.savefig("test_errorbar_2.pdf") # it has both "foo" and "bar" in the legend

Actual outcome

test_errorbar_1.pdf
test_errorbar_2.pdf

Expected outcome

The legend in test_errorbar_2.pdf contains only one entry corresponding to the second call to ax.errorbar(), i.e., the label "bar".

Additional information

I am not sure if this is the right way to remove the errorbar objects from the axes after their creation. Please correct me if I am doing it wrong or there is a better way.

As a side note, when I remove Line2D objects returned from Axes.plot(), the corresponding legend items also disappear, as one might expect. Maybe there is a problem specific to errorbar plots?

Operating system

macOS Ventura 13.0

Matplotlib Version

3.6.2

Matplotlib Backend

MacOSX

Python version

3.10.9

Jupyter version

No response

Installation

conda

@Higgs32584
Copy link
Contributor

Hey, I am new to open-source projects, but I was wondering where I would go about creating a patch for this issue.
If this helps at all, it looks like when you ask for .get_legend() both entries still show up in the file.
I would like to do this as my first issue, but do you know what .py file I should look into to make the patch? I am still getting used to this structure. Thank you!

@Higgs32584
Copy link
Contributor

Ok, I just added a patch for this bug.

@Higgs32584
Copy link
Contributor

Higgs32584 commented Mar 25, 2023

So I was not able to figure it out, but it looks like the crux of the problem appears to be that the self.remove_method is never correctly called on ErrorBar Container. This is perplexing, as for barh(BarContainer), the remove method successfully works.

It also looks like BarContainer is only one Artist object, but ErrorBar Container is three. This is because ErrorBarContainer has children of Line2D and LineCollections(not sure why it is three), both of which are successfully called, hence why the line is not there, but it is still present on the legend. This line might still exist as well(I am not entirely sure),. After a call, it is also strange cause the ErrorBar object still contains three Artists, including Line2D and LineCollections.

Once the ErrorBar container is successfully removed from self.containers, which is around line ~1300 on _base.py, the problem will be solved. Although, ErrorBar still needs to remove ITSELF from self.containers, in order to stay in line with semantics.

It is also supposed to note that this is not a rendering or updating issue, as the container's object still contains ErrorBarContainer.

What likely happens is that both ErrorBar Container and BarContainer both inherit the same remove method, but likely due to their specific implementation, you cannot remove ErrorBar Container from containers from a self-reference point of view, at least the way this is currently written. These are probably the main files you should look into for fixing this bug:

https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/container.py
https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/artist.py
https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_base.py

Hopefully you all figure this out !!

@jklymak
Copy link
Member

jklymak commented Mar 25, 2023

@Higgs32584 Thanks for the detailed look, and leaving some notes for others to follow...

@Higgs32584
Copy link
Contributor

Higgs32584 commented Mar 30, 2023

Hey man, I do not know if you can figure this out, but I could not. I left some notes for you to follow if necessary @rohitchouhan35

@rohitchouhan35
Copy link

@Higgs32584 Thanks man, I'll look into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants