Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ENH: introduce PieContainer and pie_label method#30733

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
story645 merged 1 commit intomatplotlib:mainfromrcomer:pie_label
Nov 24, 2025

Conversation

@rcomer
Copy link
Member

@rcomerrcomer commentedNov 7, 2025
edited
Loading

PR summary

This PR introduces a newpie_label method for adding labels to the wedges of existing pie charts, following discussion in#29152. Similarly toBarContainer, we introduce aPieContainer as the new return value ofpie. This contains theWedge patches and the numbers thatpie_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 thepie_label functionality should be covered by existingpie tests that use thelabels and/orautopct parameters. Is is better to duplicate this coverage? Addressed
  • ShouldPieContainer inherit fromContainer 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 ofpie. So we do not get the standardContainer behaviour that looping through it gives you the patches one by one. OTOH it is nice to get theremove method for free. Addressed
  • Shouldpie_label accept a function for thelabels parameter, similar to theautopct parameter ofpie? 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 theautopct handling intopie_label, and remove the duplicate handling for the "usetex" case.

PR checklist

@github-actionsgithub-actionsbot added topic: pyplot API Documentation: examplesfiles in galleries/examples Documentation: APIfiles in lib/ and doc/api labelsNov 7, 2025
rotate : bool, default: False
Rotate each label to the angle of the corresponding slice if true.
alignment : {'center', 'outer', 'auto'}, default: 'auto'
Copy link
MemberAuthor

@rcomerrcomerNov 7, 2025
edited
Loading

Choose a reason for hiding this comment

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

'center' is how theautopct labels ofpie are aligned and 'outer' is how thelabels ofpie 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 withrotate 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!

timhoffm reacted with thumbs up emoji
@rcomerrcomer marked this pull request as ready for reviewNovember 7, 2025 19:34
@timhoffm
Copy link
Member

timhoffm commentedNov 8, 2025
edited
Loading

  • ShouldPieContainer inherit fromContainer as I have currently done?

Container falls short for our needs here. It is basically a tuple of artists withremove() 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, onlyBarContainer really fits in. AlreadyErrorbarContainer andStemContainer 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 generalArtistCollection orCompoundArtist.

On a side-note we want this to not only be pure collections, but be a semantic entity, likeStepPatch, 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 togrouped_bar(), where we currently also only have a provisional class with functionality and minimal guarantees.

rcomer reacted with thumbs up emoji

@timhoffm
Copy link
Member

  • So far I have added very few new tests, since most of thepie_label functionality should be covered by existingpie tests that use thelabels and/orautopct parameters. Is is better to duplicate this coverage?

If writing from scratch, I would mostly test the functionality onpie_label() directly and only ensure basic propagation frompie() topie_label(). Given there are already many tests onpie() that is good enough for a start. I would not duplicate but rather move coverage out ofpie() tests and intopie_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

@rcomerrcomerforce-pushed thepie_label branch 2 times, most recently from867bd4a tobed6636CompareNovember 9, 2025 19:53
@rcomer
Copy link
MemberAuthor

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

@rcomerrcomer marked this pull request as draftNovember 10, 2025 10:40
@rcomer
Copy link
MemberAuthor

rcomer commentedNov 10, 2025
edited
Loading

For complete backwards compatibility, we need "texts" to be returned as an empty list whenlabeldistance isNone. 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.

@rcomer
Copy link
MemberAuthor

rcomer commentedNov 10, 2025
edited
Loading

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

super().__init__(lines,**kwargs)


classPieContainer:
Copy link
Member

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 justPie 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 whetherpie() could/should become essentially

defpie(self,*args,**kwargs):pie=Pie(*args,**kwargs)self.add_artist(pie)returnpie

OTOH, full semantics may be more than we can easily achieve; e.g. assume a laterpie.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 withPieContainer for now, but make then name provisional. - It's not needed for the basic use case of

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

Copy link
Member

@timhoffmtimhoffm left a 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.🚀

rcomer reacted with heart emoji
@rcomer
Copy link
MemberAuthor

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

@rcomer
Copy link
MemberAuthor

It just occurred to me that if someone is usingpandas pie, they will not get thePieContainer returned but only theAxes. Should we add thePieContainer to theAxes.containers list to support this case?

story645 reacted with thumbs up emoji

@rcomer
Copy link
MemberAuthor

To be in the containers list we need at least aget_label method.Container takes theget_label andset_label methods fromArtist.Artist.set_label callsArtist.pchanged, and I am wondering if that is the reasonContainer has the unused callback machinery.

@story645
Copy link
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?

@timhoffm
Copy link
Member

timhoffm commentedNov 19, 2025
edited
Loading

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.

@story645
Copy link
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 multiplelegend entries and is basically the analogue toPieContainer.

timhoffm and rcomer reacted with eyes emoji

@rcomer
Copy link
MemberAuthor

rcomer commentedNov 19, 2025
edited
Loading

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 deprecatelabeldistance not None and discourageautopct 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 ofwedge_labels through**kwargs and then add its automatic ones using thepie_label method.

@rcomer
Copy link
MemberAuthor

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 aget_label method into theAxes.containers list, you get an error inlegend.

@rcomer
Copy link
MemberAuthor

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

timhoffm reacted with thumbs up emoji

@timhoffm
Copy link
Member

timhoffm commentedNov 20, 2025
edited
Loading

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 multiplelegend entries and is basically the analogue toPieContainer.

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

ifnotisinstance(label,str)andnp.iterable(label):
bar_container_label='_nolegend_'
patch_labels=label
else:
bar_container_label=label
patch_labels= ['_nolegend_']*len(x)

@story645
Copy link
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.

@timhoffm
Copy link
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 forPie, because you don't ever need a single legend entry for the set of all wedges, soPie itself does not need the label capability.

Copy link
Member

@story645story645 left a comment
edited
Loading

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.

Comment on lines -3691 to -3692
forfrac,label,explinzip(x,labels,explode):
x,y=center
Copy link
Member

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

Copy link
MemberAuthor

@rcomerrcomer left a 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

@rcomerrcomer added this to thev3.11.0 milestoneNov 22, 2025
@rcomer
Copy link
MemberAuthor

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

@story645story645 merged commit50fea43 intomatplotlib:mainNov 24, 2025
48 of 49 checks passed
@story645
Copy link
Member

Thanks@rcomer for the new labeling capabilities!

rcomer reacted with hooray emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@story645story645story645 approved these changes

@timhoffmtimhoffmtimhoffm approved these changes

Assignees

No one assigned

Labels

Documentation: APIfiles in lib/ and doc/apiDocumentation: examplesfiles in galleries/examplesNew featuretopic: 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

3 participants

@rcomer@timhoffm@story645

[8]ページ先頭

©2009-2025 Movatter.jp