Skip to content

figure.legend can be called without arguments #2128

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
wants to merge 4 commits into from

Conversation

sinhrks
Copy link

@sinhrks sinhrks commented Jun 17, 2013

figure.legend() can be called without arguments.

In this case, figure legend artists will be created from all the contained axes legend handles and labels in the figure. The figure legend will merge handles if its label is identical, assuming that the same handlers is assigned to the same label names in subplots.

@mdboom
Copy link
Member

mdboom commented Jun 17, 2013

It would be great to get @leejoon's thoughts on this, as the legend guy.

I like this because it brings Figure.legend in line with Axes.legend in terms of what it can do.

@WeatherGod
Copy link
Member

Should we reconsider the behavior of pyplot.legend()? IIRC, it operates upon gca(), not gcf(). I am inclined to keep it as gca(), but I just wanted to make sure a decision is made on it.

@jenshnielsen
Copy link
Member

Doesn't pyplot have figlegend which is the equivalent of this in pyplot?

@mdboom
Copy link
Member

mdboom commented Jun 17, 2013

Yeah -- I think gca().legend() is the more common case (or at least that's how I see it after all these years of expecting that).

And as @jenshnielsen points out, we have pyplot.figlegend to get to Figure.legend(). And it has the same shortcoming -- that lines and labels are required as arguments.

@sinhrks
Copy link
Author

sinhrks commented Jun 19, 2013

Thank you for the confirmation. I've applied the same modification to pyplot.figlegend(). Also, the Figure.legend() can now work for 0, 2, and 3 arguments, because pyplot.figlegend() is intended to be called with handler, labels and loc without keywords.

@leejjoon
Copy link
Contributor

leejjoon commented Aug 7, 2013

I think it is good to merge.

A few minor points.

  1. I am personally not quite convinced for the current behavior for identical labels.
  2. The ordering of handles and labels rely on the order of dict.keys() which is arbitrary.

Unless there is no objection of merging this, I will go ahead and merge it.

@WeatherGod
Copy link
Member

Why not use OrderedDict from the standard library's collection module?
Note that you can't just simply import collections because that would pick
up matplotlib's collection module, so you would have to import from future
the absolute imports feature.

@pelson
Copy link
Member

pelson commented Sep 18, 2013

Unless there is no objection of merging this, I will go ahead and merge it.

I'm currently working on a re-factor of the legend code. It deprecates some of the plt.legend interface and I'd like to have the discussion about that interface before we merge this. I'm hoping to have a PR in the next couple of days and would really value your feedback on it.

Cheers,

handles, labels = ax.get_legend_handles_labels()
ldict = dict(ldict, **dict(zip(labels, handles)))

handles, labels = ldict.values(), ldict.keys()
Copy link
Member

Choose a reason for hiding this comment

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

does this need to be six-ified?

Copy link
Member

Choose a reason for hiding this comment

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

Plus, I would never trust the order to be the same from one call to the next. There is a reason why they say "order is never guaranteed".

Copy link
Contributor

Choose a reason for hiding this comment

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

Is line 1165 legal python? I would have spelled it ldict.update(handles, labels)? handles and labels only need to be iterable, so should be six-compliant.

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like legend entries with the same handle will clober each other. i've definitely used the same handle for multiple lines. i won't promise it was a good idea, but I would be irritated if MPL prevented me from doing so.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that line is legal python. It would be better written as an ldict.update() statement though. I think the idea is that we should expect that legend labels that are the same across axes objects are intended to be the same entry in the figure legend, which makes sense. However, this does confuse situations where the same label is used multiple times within an axes. At the very least, this code needs to be much better commented to explain its intentions and purpose.

@mrterry
Copy link
Contributor

mrterry commented Sep 18, 2013

@WeatherGod OrderedDict is new in python2.7.

@WeatherGod
Copy link
Member

@mrterry yeah, so? We support python2.6. That particular line should really be doing a single call to items() and splitting things out that way, but you do have to watch out for the empty dictionary case.

@mrterry
Copy link
Contributor

mrterry commented Sep 18, 2013

Just pointing out that it is not present in one of our supported python versions. I wanted to use it in setup.py, but got shot down. 😦 I really like OrderedDict.

@tacaswell
Copy link
Member

This having issues with pyparsing on 3.3.

@tacaswell
Copy link
Member

@sinhrks Are you still interested in working on this PR?

@tacaswell
Copy link
Member

pushing off to 1.5 due to issues with py3k and in-activity.

@sinhrks
Copy link
Author

sinhrks commented Mar 19, 2014

Thank you for your comment and I apologize that I hadn't check it long.

I've changed the internal logic not to use dict, but use list to retain the drawing order.

About Legend Labels: My original intention is to create a figure legend easily in subplots which uses similar data, same type of chart and color schema. In such a case, "looks-identical" artists should have the same label, artist, colors, etc. Thus I'd like to ask on what condition 2 artist can be regarded as identical (or looks-similar enough to be omitted in figure legend) in most cases. In other detailed cases, handles and labels can be passed to legend explicitly.

I've implemented a proto which also check artist type, color, edgecolor and facecolor are identical before skipping. I'll try to implement it once what attributes are checked.

Current Outlook:
figure_1

@tacaswell
Copy link
Member

It looks like you have introduced a bunch of pep8 violations into the code.

@tacaswell tacaswell modified the milestones: proposed next point release, next point release Feb 19, 2015
@tacaswell
Copy link
Member

@sinhrks Are you still interested in working on this?

@tacaswell tacaswell modified the milestones: next point release, proposed next point release Jun 18, 2015
@tacaswell tacaswell removed this from the next point release milestone Jun 18, 2015
@tacaswell
Copy link
Member

@sinhrks This needs a rebase.

Does it make sense to group artist by label? It might be worth getting the simpler change (making the API match that of ax.legend) in and doing the smarter grouping in a second pass?

@dstansby
Copy link
Member

Since it's been over 2 years since last contact, I'll pick this up. Merged and rebased onto my own branch, just getting tests to run etc. and I'll open a new PR when ready.

@NelleV
Copy link
Member

NelleV commented Jan 13, 2017

I am closing this in favor of #7811

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.