Skip to content

figure.legend can be called without arguments - #2128

Closed
sinhrks wants to merge 4 commits into
matplotlib:masterfrom
sinhrks:legend
Closed

sinhrks wants to merge 4 commits into
matplotlib:masterfrom
sinhrks:legend

Conversation

@sinhrks

@sinhrks sinhrks commented Jun 17, 2013

Copy link
Copy Markdown

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

mdboom commented Jun 17, 2013

Copy link
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown
Member

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

@mdboom

mdboom commented Jun 17, 2013

Copy link
Copy Markdown
Member

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

sinhrks commented Jun 19, 2013

Copy link
Copy Markdown
Author

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

leejjoon commented Aug 7, 2013

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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

pelson commented Sep 18, 2013

Copy link
Copy Markdown
Member

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,

Comment thread lib/matplotlib/figure.py Outdated

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.

does this need to be six-ified?

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.

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
Copy Markdown
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
Copy Markdown
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
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 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

mrterry commented Sep 18, 2013

Copy link
Copy Markdown
Contributor

@WeatherGod OrderedDict is new in python2.7.

@WeatherGod

Copy link
Copy Markdown
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

mrterry commented Sep 18, 2013

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Member

This having issues with pyparsing on 3.3.

@tacaswell

Copy link
Copy Markdown
Member

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

@tacaswell

Copy link
Copy Markdown
Member

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

@sinhrks

sinhrks commented Mar 19, 2014

Copy link
Copy Markdown
Author

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

NelleV commented Jan 13, 2017

Copy link
Copy Markdown
Member

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.