GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — ENH: introduce PieContainer and pie_label method by rcomer · Pull Request #30733 · matplotlib/matplotlib

Conversation

@rcomer

@rcomer rcomer commented Nov 7, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

PR summary

This PR introduces a new pie_label method for adding labels to the wedges of existing pie charts, following discussion in #29152. Similarly to BarContainer, we introduce a PieContainer as the new return value of pie. This contains the Wedge patches and the numbers that pie_label requires for automatically labelling the wedges with their values and/or fractions.

Closes #19338

A few things I’m not sure about:

  • So far I have added very few new tests, since most of the pie_label functionality should be covered by existing pie tests that use the labels and/or autopct parameters. Is is better to duplicate this coverage? Addressed
  • Should PieContainer inherit from Container as I have currently done? It feels a bit wrong to me as I have also overwritten the __iter__ method to provide backwards compatibility on the return value of pie. So we do not get the standard Container behaviour that looping through it gives you the patches one by one. OTOH it is nice to get the remove method for free. Addressed
  • Should pie_label accept a function for the labels parameter, similar to the autopct parameter of pie? Initially I thought no, because I do not know of a use case and the only example I found in the docs was the bakery one, which can now use the format string. However, supporting a function would allow us to move more of the autopct handling into pie_label, and remove the duplicate handling for the "usetex" case.

PR checklist

  • "closes #0000" is in the body of the PR description to link the related issue
  • new and changed code is tested
  • Plotting related features are demonstrated in an example
  • New Features and API Changes are noted with a directive and release note
  • Documentation complies with general and docstring guidelines

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rcomer rcomer added the New feature label Nov 7, 2025
@github-actions github-actions Bot added topic: pyplot API Documentation: examples files in galleries/examples Documentation: API files in lib/ and doc/api labels Nov 7, 2025
rcomer
rcomer commented Nov 7, 2025
View reviewed changes
Comment thread lib/matplotlib/axes/_axes.py
rotate : bool, default: False
Rotate each label to the angle of the corresponding slice if true.

alignment : {'center', 'outer', 'auto'}, default: 'auto'

@rcomer rcomer Nov 7, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

'center' is how the autopct labels of pie are aligned and 'outer' is how the labels of pie are aligned. We had some discussion about the horizontal alignment at #29152 (comment) and #29152 (comment), but I did not notice the extra complication for vertical alignment with rotate until I was writing the example. autopct does not have an associated rotate option, but I can report that rotated labels that were centred horizontally but not centred vertically looked bad!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

timhoffm reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@rcomer
rcomer marked this pull request as ready for review November 7, 2025 19:34
@timhoffm

timhoffm commented Nov 8, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member
  • Should PieContainer inherit from Container as I have currently done?

Container falls short for our needs here. It is basically a tuple of artists with remove() propagation and a CallbackRegistry (which AFAICS we nowhere use). That simple tuple approach does not suit the more general case that we have not just one type sequence of Artists. In fact, only BarContainer really fits in. Already ErrorbarContainer and StemContainer have to work around the limitation using tuples of tuples, which is not a good API.

I think we need to come up with a more generic concept. For a start, I'd say make your own type (i.e. copy the remove method) and define whatever minimal API is reasonable. If we know what kind of API we want to have based on this example it's easier to design a more general ArtistCollection or CompoundArtist.

On a side-note we want this to not only be pure collections, but be a semantic entity, like StepPatch, i.e. there may be (not necessarily from the start) semantic functions, that non-trivially manipulate multiple properties of the artists; e.g. setting the pie values would need to recompute positions of all wedges and texts and update the text content.

Edit: The case is similar to grouped_bar(), where we currently also only have a provisional class with functionality and minimal guarantees.

rcomer reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@timhoffm

timhoffm commented Nov 8, 2025

Copy link
Copy Markdown
Member
  • So far I have added very few new tests, since most of the pie_label functionality should be covered by existing pie tests that use the labels and/or autopct parameters. Is is better to duplicate this coverage?

If writing from scratch, I would mostly test the functionality on pie_label() directly and only ensure basic propagation from pie() to pie_label(). Given there are already many tests on pie() that is good enough for a start. I would not duplicate but rather move coverage out of pie() tests and into pie_label() tests. But that is a nice-to-have. If done, I'd rather make this a separate cleanup PR.

rcomer reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch 2 times, most recently from 867bd4a to bed6636 Compare November 9, 2025 19:53
rcomer
rcomer commented Nov 9, 2025
View reviewed changes
Comment thread lib/matplotlib/container.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rcomer

rcomer commented Nov 9, 2025

Copy link
Copy Markdown
Member Author

OK, PieContainer is now its own class with its own remove method.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

timhoffm
timhoffm reviewed Nov 9, 2025
View reviewed changes
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/container.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/container.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from dfeeb53 to 6dac737 Compare November 10, 2025 10:02
@rcomer
rcomer marked this pull request as draft November 10, 2025 10:40
@rcomer

rcomer commented Nov 10, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

For complete backwards compatibility, we need "texts" to be returned as an empty list when labeldistance is None. I think both my current and previous implementations broke that.

In draft for now while I think about how to address that. Suggestions of course welcome!

Edit: this is now addressed by the next push.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from 6dac737 to f3f3484 Compare November 10, 2025 12:19
@rcomer
rcomer marked this pull request as ready for review November 10, 2025 12:37
@rcomer
rcomer force-pushed the pie_label branch from f3f3484 to fa0a573 Compare November 10, 2025 17:10
@rcomer

rcomer commented Nov 10, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Apologies - just found some doc changes that I had missed before. None of the examples now unpack or index the return value.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from fa0a573 to b3d9dd2 Compare November 10, 2025 17:31
timhoffm
timhoffm reviewed Nov 10, 2025
View reviewed changes
Comment thread lib/matplotlib/container.pyi Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/container.py
super().__init__(lines, **kwargs)


class PieContainer:

@timhoffm timhoffm Nov 10, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I am unsure on the name. I'm tempted to call this just Pie on the background, that I envision this will become a compound semantic artist. The "Container" puts more focus on "aggregation of parts".

In that context, I'm pondering whether pie() could/should become essentially

def pie(self, *args, **kwargs):
    pie = Pie(*args, **kwargs)
    self.add_artist(pie)
    return pie

OTOH, full semantics may be more than we can easily achieve; e.g. assume a later pie.set_values(new_values) changes the number of wedges. How does that affect explicitly set lists of labels or wedge properties?

Recommendation: Let's stick with PieContainer for now, but make then name provisional. - It's not needed for the basic use case of

pie = ax.pie(...)
ax.pie_label(pie, ....)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@rcomer
rcomer force-pushed the pie_label branch from b3d9dd2 to 26c43e8 Compare November 10, 2025 20:18
timhoffm
timhoffm approved these changes Nov 10, 2025
View reviewed changes

@timhoffm timhoffm left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I've left some minor comments.

Overall a systematic and easy-to-review PR. Thanks for the effort.🚀

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

rcomer reacted with heart emoji
All reactions
  • ❤️ 1 reaction
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/container.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from 7417870 to e9d6466 Compare November 11, 2025 19:00
@rcomer

rcomer commented Nov 11, 2025

Copy link
Copy Markdown
Member Author

Thanks for all your reviewing work @timhoffm. Your latest suggestions seem good to me.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from e9d6466 to 4ea67fe Compare November 11, 2025 19:21
@rcomer

rcomer commented Nov 18, 2025

Copy link
Copy Markdown
Member Author

It just occurred to me that if someone is using pandas pie, they will not get the PieContainer returned but only the Axes. Should we add the PieContainer to the Axes.containers list to support this case?

story645 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer

rcomer commented Nov 18, 2025

Copy link
Copy Markdown
Member Author

To be in the containers list we need at least a get_label method. Container takes the get_label and set_label methods from Artist. Artist.set_label calls Artist.pchanged, and I am wondering if that is the reason Container has the unused callback machinery.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@story645

story645 commented Nov 18, 2025

Copy link
Copy Markdown
Member

To be in the containers list we need at least a get_label method. Container takes the get_label and set_label methods from Artist

Does it make sense to have a container interface/ABC to spell out the membership requirements for the containers list?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@timhoffm

timhoffm commented Nov 19, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

We need to define what exactly a container is. My understanding from the label machinery is that it is an artist that is realized through multiple base artists, but rather as an implementation detail. ErrorbarContainer uses multiple Line2D, but is logically still a single entity that shows up as one legend entry. I haven’t checked, but suspect that tracking containers explicitly in Axes may be done so that we can identify the artists to label (but it could also be that this was done purely to have a place to attach the involved artists to the figure, since historically we tracked different types of artists like lines, patches, etc. in their own lists and we certainly want to mix the lines of BarContainer with regular standalone lines).

In contrast, Pie is a rather a concerted logical aggregation of multiple artists. A single label and legend entry does not make sense. I therefore believe that Pie is not a container as far as current container design goes.

How to move forward?

I wouldn’t jump extra hoops to support advanced plotting through the pandas plot API. It it’s a high-level API to ease plotting from dataframes, but you can always extract the column data and feed it to matplotlib if needed.

we should specify the concept behind the type of aggregation we do with Pie more clearly. And we need to define how that is represented in internal structures. Is it one artist that can provide multiple legend entries? Or is it rather a grouping where the individual parts are tracked as separate entities in the Axes? Currently, and historically, wedges are added as individual patches. As long as we do this, we can live without adding Pie to the Axes as a minimal starting point. Agreed it would be nice to be able to retrieve it back, but it’s not that we are losing functionality. It’s just a yet to be implemented feature which requires additional design and refactoring, and I propose to rather do this as a follow up.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@story645

story645 commented Nov 19, 2025

Copy link
Copy Markdown
Member

A single label and legend entry does not make sense. I therefore believe that Pie is not a container as far as current container design goes

BarContainer also supports multiple legend entries and is basically the analogue to PieContainer.

timhoffm and rcomer reacted with eyes emoji
All reactions
  • 👀 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer

rcomer commented Nov 19, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

OK, I am happy to just drop the latest commit here.

I was thinking that we need to support adding (at least) two sets of labels - once we deprecate labeldistance not None and discourage autopct in the next PR that means at least one set has to be added after the pie is created. However, I was forgetting that pandas will add one of those sets automatically based on what is in the data frame. So pandas could pass on a single set of wedge_labels through **kwargs and then add its automatic ones using the pie_label method.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer

rcomer commented Nov 19, 2025

Copy link
Copy Markdown
Member Author

I haven’t checked, but suspect that tracking containers explicitly in Axes may be done so that we can identify the artists to label

I can confirm that if you put something without a get_label method into the Axes.containers list, you get an error in legend.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer force-pushed the pie_label branch from 82b1c1b to 4ea67fe Compare November 19, 2025 19:46
@rcomer

rcomer commented Nov 19, 2025

Copy link
Copy Markdown
Member Author

OK, PR is now back to what @timhoffm already approved 😇

timhoffm reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@timhoffm

timhoffm commented Nov 20, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

A single label and legend entry does not make sense. I therefore believe that Pie is not a container as far as current container design goes

BarContainer also supports multiple legend entries and is basically the analogue to PieContainer.

BarContainer dues not reasonably handle labels either. There's some low-level hack in bar() to make this work.

matplotlib/lib/matplotlib/axes/_axes.py

Lines 2544 to 2549 in 91b8a07

if not isinstance(label, str) and np.iterable(label):
bar_container_label = '_nolegend_'
patch_labels = label
else:
bar_container_label = label
patch_labels = ['_nolegend_'] * len(x)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@story645

story645 commented Nov 20, 2025

Copy link
Copy Markdown
Member

BarContainer dues not reasonably handle labels either. There's some low-level hack in bar() to make this work.

Looks like it's doing an either use labels on individual artists or container level label. I think it's maybe a questionable API decision to make them mutually exclusive, but I don't think it's a hack.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer rcomer added the status: needs review label Nov 21, 2025
@timhoffm

timhoffm commented Nov 21, 2025

Copy link
Copy Markdown
Member

I think it's maybe a questionable API decision to make them mutually exclusive, but I don't think it's a hack.

Whatever you want to name it. The effect is that responsibility of label handling is distributed between the individual bars and the container. There is no easy way to change between the two approaches afterwards.

But anyway, this is of no concern for Pie, because you don't ever need a single legend entry for the set of all wedges, so Pie itself does not need the label capability.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

story645
story645 approved these changes Nov 21, 2025
View reviewed changes

@story645 story645 left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

nit you can take or leave but mostly fun 'cause I learned some new things.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread doc/release/next_whats_new/pie_label.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread doc/release/next_whats_new/pie_label.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py
Comment on lines -3691 to -3692
for frac, label, expl in zip(x, labels, explode):
x, y = center

@story645 story645 Nov 21, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

🤨 til that loops have local scoping starting in v3

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/tests/test_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rcomer rcomer removed the status: needs review label Nov 22, 2025
@rcomer
ENH: introduce PieContainer and pie_label method
a97c665
@rcomer
rcomer force-pushed the pie_label branch from 4ea67fe to a97c665 Compare November 22, 2025 09:05
rcomer
rcomer commented Nov 22, 2025
View reviewed changes

@rcomer rcomer left a comment

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Thanks for the review @story645

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/tests/test_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread doc/release/next_whats_new/pie_label.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread doc/release/next_whats_new/pie_label.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

@rcomer rcomer added this to the v3.11.0 milestone Nov 22, 2025
@rcomer

rcomer commented Nov 24, 2025

Copy link
Copy Markdown
Member Author

Have I missed something I still need to do for this one?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@story645
story645 merged commit 50fea43 into matplotlib:main Nov 24, 2025
48 of 49 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@story645

story645 commented Nov 24, 2025

Copy link
Copy Markdown
Member

Thanks @rcomer for the new labeling capabilities!

rcomer reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rcomer
rcomer deleted the pie_label branch November 24, 2025 22:29
This was referenced Nov 29, 2025
DOC: don't index or unpack the return value of pie #30799
Merged
ENH: introduce wedge_labels parameter for pie #29152
Merged
@story645 story645 mentioned this pull request Jan 18, 2026
Voxels as mappable for colorbar & changed return type of voxels #30982
Closed
2 of 5 tasks
andreas16700 added a commit to andreas16700/matplotlib that referenced this pull request Jan 28, 2026
@andreas16700 @claude
Run 33: Match upstream 50fea43 (PR matplotlib#30733) - PieContainer a…
32e7b10
…nd pie_label

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@robertoffmoura robertoffmoura mentioned this pull request Sep 8, 2026
[ENH]: Track PieContainer in Axes.containers #32320
Open
@rcomer rcomer mentioned this pull request Sep 12, 2026
TYP: PieContainer does not inherit from Container #32344
Merged
1 task done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@story645 story645 story645 approved these changes
@timhoffm timhoffm timhoffm approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

Documentation: API files in lib/ and doc/api Documentation: examples files in galleries/examples New feature topic: pyplot API

Projects

None yet

Milestone

v3.11.0

Development

Successfully merging this pull request may close these issues.

Allow option to display absolute values for pie chart

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@rcomer @timhoffm @story645
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.