Skip to content

Refactor legend+colorbar internals, support "queueing" and location-based replacements #254

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

Merged
merged 4 commits into from
Jul 3, 2021

Conversation

lukelbd
Copy link
Collaborator

@lukelbd lukelbd commented Jul 3, 2021

Resolves #198. Proplot supports more than one legend per subplot. However this means that each legend() call creates a brand new legend -- sometimes one on top of another. This was confusing to new users (IIRC there's a closed issue floating around) and broke external packages that rely on one legend per subplot (#198).

This PR does the best of both worlds. Proplot still supports multiple legends, but not on top of each other. If you call legend() more than once with the same location loc (or without loc, implying the same default location), proplot
will either 1) replace the previous legend (if queue=False, the default) or 2) add handles to a "queue" (if queue=True). This "queueing" option was previously only available in the wrapper functions, which didn't make sense.

This PR also cleans up/organizes the messy legend and colorbar code. It also changes behavior: legend(..., center=True) no longer returns the background patch. I think it's kind of weird for legend() to return a non-legend object and "inner colorbars" made with e.g. colorbar(..., loc='upper right') also don't return the patch. Really should just merge #74.

Here's the example from #198 (no more errors):

import pandas as pd
import proplot as plot
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar', 'foo', 'foo'],
                   'B' : ['one', 'one', 'two', 'three',
                       'two', 'two', 'one', 'three'],
                   'C' : np.random.randn(8),
                   'D' : np.random.randn(8)})
fig, axs = plot.subplots()
df.groupby('A')['C'].plot(legend='ur', ax=axs)

issue

Here's an example showing the new location-specific legend-replacing behavior:

import proplot as plot
data = np.random.rand(10, 4)
fig, ax = plot.subplots()
hs = ax.plot(data[:, :2], labels=('foo', 'bar'))
ax.legend(hs, loc='ur')
hs = ax.plot(data[:, 2:], labels=('abc', 'def'))  # overwrites old one
ax.legend(hs, loc='ur')
ax.legend(hs, loc='top')

sample

And here's an example of the now publicly-available queue feature:

import proplot as plot
data = np.random.rand(10, 4)
fig, ax = plot.subplots()
hs = ax.plot(data[:, 0], label='foo')
ax.legend(hs,  queue=True)
hs = ax.plot(data[:, 1], label='bar')
ax.legend(hs,  queue=True)
hs = ax.plot(data[:, 2], label='abc')
ax.legend(hs, loc='b', queue=True)
hs = ax.plot(data[:, 3], label='def')
ax.legend(hs, loc='b', queue=True)

sample

@lukelbd lukelbd merged commit 8c01866 into master Jul 3, 2021
@lukelbd lukelbd deleted the successive-legend-calls branch July 3, 2021 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show labels of grouped pandas dataframe in one legend
1 participant