GeezerVison is showing github.com — [ENH]: Track PieContainer in Axes.containers · Issue #32320 · matplotlib/matplotlib
[ENH]: Track PieContainer in Axes.containers #32320DescriptionProblem
Following up on #30733 where adding PieContainer to ax.containers was deferred: downstream export/conversion libraries such as plotly (and pandas plotting users) cannot discover or reconstruct pie plots from an Axes instance because PieContainer is not retained anywhere on the Axes. Once ax.pie() finishes, only disconnected Wedge patches remain in ax.patches.
Proposed solution
Would you be open to an ABC/Protocol for Container that relaxes the tuple inheritance so PieContainer can be tracked in ax.containers? Activitystory645 commented on Sep 9, 2026 I'm all for an ABC/protocol, but, as far as I can tell, it seemed like the sticking point was on labeling: #30733 (comment) timhoffm commented on Sep 10, 2026 Container is an insufficient concept here. They only group a couple independent artists. What we actually want is a semantic artist that can contain and control children. For example, you'll want to be able to change the pie values later. This requires a concerted action to change size and position (possibly even number) of wedges.
PieContainer is a preliminary minimal concept to improve on the previous return type, which was just a tuple of lists of artists. It collects them together into a single entity, which was needed to be able to introduce pie_label(). We plan to develop this into a different direction than Container, and therefore I would not want to at it to ax.containers. From an Axes perspective, these are still independent wedges as have always been. We will collect them into one entity, but that concept still has to be estabilished and will be different from Container.
story645 commented on Sep 10, 2026
, and therefore I would not want to at it to ax.containers
Your reasoning makes sense to me, but I also think the ask of being able to reconstruct the pie chart is reasonable. Are the wedges currently grouped together in a way where it's identifiable that they're part of the same chart? jklymak commented on Sep 10, 2026 I don't see what the issue is with calling this agglomeration of wedges a Container and letting that have the semantic information. I don't see how this is conceptually different than BarContainer timhoffm commented on Sep 10, 2026
Your reasoning makes sense to me, but I also think the ask of being able to reconstruct the pie chart is reasonable. Are the wedges currently grouped together in a way where it's identifiable that they're part of the same chart?
The wedges are currently not grouped together, and have never been so far.
If somebody wants to have all wedges of a pie today, I'd recommend a small heuristic algorithm:
- Take all wedges in an Axes
- Group them by their
center (typically there's only one pie in an Axes so one center, but if you want to be more precise there could be more)
- Each group is a pie. You may or may not refine edge cases
- Groups with only one element that span 360° are most likely still a pie - Nobody would intentionally draw a 360° pie. It's most likely a pie call with just one element.
- Groups with only one element and < 360% are likely no pie. While it could be a call with one elment and and
normalize=False that's rather unlikely and probably someone has manually drawn a Wedge.
- Groups with different radii are not a pie - that's not supported
- You might want to join groups if they have the same radius and their centers are not too different (only a fraction of the radius difference). That's likely
pie(..., explode=...).
- Bonus points if you check the thetas to match up.
That's of course a lot more cumbersome that just having a predefined group. But the advantage is that it works for all past versions of matplotlib, and I'm sure an LLM can come up with even better criteria and implement it for you.
This is not saying that we should not do better, but there are workarounds today. timhoffm commented on Sep 10, 2026
I don't see what the issue is with calling this agglomeration of wedges a Container and letting that have the semantic information. I don't see how this is conceptually different than BarContainer
Apart from grouping, Container has three functionalities
- a collective
remove()
- a callback registry
- a label
Label is not meaningful to a pie as a whole, and the callback registry is most likely not needed. While it could be used as a collection instance, it's not particular fitting.
Additionally, Container is a dedicated "group" object not an artist. I'm yet not sure whether that's reasonable or whether we should have a sort of compound PieArtist that manges its wedges as children. The difference is that with a container, we still store all wedges individually in ax._children and additionally store a container that points to them. In the case of a compoud PieArtist, only that would be in ax._children and it would itself manage the wedges, including creating / deleting when data changes, and with the option for natural bbox calculation etc. Such a PieArist is more self-contained and thus may be easier to handle and be more capable. jklymak commented on Sep 10, 2026 I agree that it would probably make more sense for Pie to be a parent artist that had children. But for whatever reason we have a parallel indexing of some artists into Containers for easy referencing. We could make the same argument that a barred histogram should be a compound artist instead of packing 20 or 30 artists into a BarContainer.
That said, we have the idea of a PieContainer, and we have the idea of putting containers into a list on an axes. I don't see the harm in adding the current wedges to the container list, and indeed it seems a bit perverse that we do not. Given that it's just a list of artists, it could even be backwards compatible if we made a PieArtist in the future by just pointing to its wedge children. story645 commented on Sep 10, 2026
We could make the same argument that a barred histogram should be a compound artist instead of packing 20 or 30 artists into a BarContainer.
I think @ksunden might have a demo of that or something in that direction w/ a histogram data container. timhoffm commented on Sep 10, 2026
But for whatever reason we have a parallel indexing of some artists into Containers for easy referencing.
I haven’t dug up the whole history, but the primary motivation was to create a legend entry for a group of Artists: 3991bea
We could make the same argument that a barred histogram should be a compound artist instead of packing 20 or 30 artists into a BarContainer.
Yes. In hindsight I would say the simplest solution (Container) isn’t the best, and we should have thought more about design back then.
That said, we have the idea of a PieContainer, and we have the idea of putting containers into a list on an axes. I don't see the harm in adding the current wedges to the container list, and indeed it seems a bit perverse that we do not. Given that it's just a list of artists, it could even be backwards compatible if we made a PieArtist in the future by just pointing to its wedge children.
I would like to eventually move away from Containers, and adding more would be going in the wrong direction. I think a PieArtist should live under ax._children not under ax.containers, it therefore would be a breaking change, and the change is worse when we go from individual Wedges to a Container and then to a semantic compound Artist compared to directly switching to a compound Artist. The current PieContainer is a preliminary minimal grouping object needed to be able to pass „the pie“ to pie_label(). It was designed to give as little API surface and guarantees as possible, so that we are still free to design the right structure. jklymak commented on Sep 10, 2026 I'd have proposed
Current state:
ax._children = [wedge1, wedge2, wedge3],
ax.containers = [pie_container1]
pie_container1.wedges = [wedge1, wedge2, wedge3]
And then migrating to:
ax._children = [pie1],
pie1.wegdes = [wedge1, wedge2, wedge3]
pie1.container = pie_container1
ax.containers = [pie_container1]
pie_container1.wedges = [wedge1, wedge2, wedge3]
It's a little duplicative, but it's just a bit of bookkeeping. For better or worse, currently ax.pie returns the container. It seems improper for the axes to lose track of the relationship between the wedges. timhoffm commented on Sep 11, 2026 Why not directly migrate to
ax._children = [pie1],
pie1.wegdes = [wedge1, wedge2, wedge3]
ax.containers = []
jklymak commented on Sep 11, 2026 Sure, but someone has to make pie1. If there are not immediate plans to do that, then I'd still argue it makes sense to keep track of which wedges go with which pie timhoffm commented on Sep 11, 2026 I believe making a minimal PieArtist is not much more work than turning it into a Container. There are probably one or two design decisions that need to be taken early, but that's a good inverstment compared to rolling an intermediate solution. jklymak commented on Sep 11, 2026 It already is a Container, we just don't add it to the list of containers. timhoffm commented on Sep 11, 2026 No, we intentionally did not make it a Container. It does not inherit from it. I concede it's a bit confusing that it's still called "PieContainer" and lives in matplotlib.containers - but that's part historic (first implementation started there) part lack of a better place / completely defined concept.
Relevant discussion:
rcomer commented on Sep 12, 2026 Sorry I’m late to the party. I’ve been at a conference all week.
One thing I did find at #30733 (comment) is
if you put something without a get_label method into the Axes.containers list, you get an error in legend
Adding a get_label method to PieContainer doesn’t really make sense as I doubt many people want a legend entry for the whole pie. So we’d either be adding functionality we don’t need, or having to modify legend’s label collection code.
Note also that PieContainer does not have the __iter__ method of the Container class, so looping through it will not give you the individual artists. This might break existing code that uses the containers list.
Regarding the name, I was tempted to propose PieTin or PieCase 😏 jklymak commented on Sep 12, 2026 The semantics of something that is called a "PieContainer" and calls itself a "Container" in its own docstring leads to the expectation that it would be in ax.containers. Other than the lack of inheritance, there is nothing in the codebase to signal it is not a container like the other containers. I consider the original request reasonable.
If we decide to make it not a container, fine. But making it a container and adding whatever carve out that's needed in legend seems the easiest way to add a container-like object to the axes that tracks the association of the wedges with one another. timhoffm commented on Sep 13, 2026 The docstring explicitly states
The class name PieContainer name is provisional and may change in future to reflect development of its functionality.
I’ve mentioned the historic context in #32320 (comment)
Let’s not make it a Container only based on a preliminary naming, and then bend the labeling mechanism because its structure doesn’t fit the current container specification.
@jklymak you said yourself
I agree that it would probably make more sense for Pie to be a parent artist that had children.
Why not just go this way?
And if we make it an Artist, naming can just be Pie. jklymak commented on Sep 14, 2026
The docstring explicitly states
That caveat is inadequate in my opinion. The docstring in the conatiners API says: PieContainer: Container for the artists of pie charts. If you are not going to rename it, Then I'd at least rewrite this as "Non-traditional container for the artists of pie chart - note this is not added to the list of axes containers like other Containers".
Why not just go this way?
Sure - all I'm saying is that the current state with this zombie class that we lose track of doesn't make a lot of sense. Just adding to the list of containers seems the most simple way forward, but whatever works. timhoffm commented on Sep 15, 2026 As a first step, I've clarified the docs: #32353. robertoffmoura commented on Sep 16, 2026 ContributorAuthor More actions I put together PR #32359 implementing the compound Pie(Artist) design discussed above. Any feedback is welcome!
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|