Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4dbd98e

Browse files
committed
ENH: add wedge_labels parameter for pie
1 parent dcff41f commit 4dbd98e

10 files changed

Lines changed: 231 additions & 81 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
``pie`` *labels* and *labeldistance* parameters
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
Currently the *labels* parameter of `~.Axes.pie` is used both for annotating the
4+
pie wedges directly, and for automatic legend entries. For consistency
5+
with other plotting methods, in future *labels* will only be used for the legend.
6+
7+
The *labeldistance* parameter will therefore default to ``None`` from Matplotlib
8+
3.14, when it will also be deprecated and then removed in Matplotlib 3.16. To
9+
preserve the existing behavior for now, set ``labeldistance=1.1``. For the longer
10+
term, use the new *wedge_labels* parameter of `~.Axes.pie` or the `~.Axes.pie_label`
11+
method instead of *labels*.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
New *wedge_labels* parameter for pie
2+
------------------------------------
3+
4+
`~.Axes.pie` now accepts a *wedge_labels* parameter as a shortcut to the
5+
`~.Axes.pie_label` method. This may be used for simple annotation of the wedges
6+
of the pie chart. It can take
7+
8+
* a list of strings, similar to the existing *labels* parameter
9+
* a format string similar to the existing *autopct* parameter except that it
10+
uses the `str.format` method, and it can handle absolute values as well as
11+
fractions/percentages
12+
13+
*wedge_labels* has an accompanying *wedge_label_distance* parameter, to control
14+
the distance of the labels from the center of the pie.
15+
16+
17+
.. plot::
18+
:include-source: true
19+
:alt: Two pie charts. The chart on the left has labels 'foo' and 'bar' outside the wedges. The chart on the right has labels '1' and '2' inside the wedges.
20+
21+
import matplotlib.pyplot as plt
22+
23+
fig, (ax1, ax2) = plt.subplots(ncols=2, layout='constrained')
24+
25+
ax1.pie([1, 2], wedge_labels=['foo', 'bar'], wedge_label_distance=1.1)
26+
ax2.pie([1, 2], wedge_labels='{absval:d}', wedge_label_distance=0.6)

galleries/examples/misc/svg_filter_pie.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828

2929
# We want to draw the shadow for each pie, but we will not use "shadow"
3030
# option as it doesn't save the references to the shadow patches.
31-
pie = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')
31+
pie = ax.pie(fracs, explode=explode, wedge_labels=labels, wedge_label_distance=1.1)
3232

33-
for w in pie.wedges:
33+
for w, label in zip(pie.wedges, labels):
3434
# set the id with the label.
35-
w.set_gid(w.get_label())
35+
w.set_gid(label)
3636

3737
# we don't want to draw the edge of the pie
3838
w.set_edgecolor("none")

galleries/examples/pie_and_polar_charts/bar_of_pie.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
explode = [0.1, 0, 0]
2626
# rotate so that first wedge is split by the x-axis
2727
angle = -180 * overall_ratios[0]
28-
wedges, *_ = ax1.pie(overall_ratios, autopct='%1.1f%%', startangle=angle,
29-
labels=labels, explode=explode)
28+
pie = ax1.pie(overall_ratios, startangle=angle, explode=explode)
29+
30+
# label the wedges with our label strings and the ratios as percentages
31+
ax1.pie_label(pie, labels, distance=1.1)
32+
ax1.pie_label(pie, '{frac:.1%}', distance=0.6)
3033

3134
# bar chart parameters
3235
age_ratios = [.33, .54, .07, .06]
@@ -47,8 +50,8 @@
4750
ax2.set_xlim(- 2.5 * width, 2.5 * width)
4851

4952
# use ConnectionPatch to draw lines between the two plots
50-
theta1, theta2 = wedges[0].theta1, wedges[0].theta2
51-
center, r = wedges[0].center, wedges[0].r
53+
theta1, theta2 = pie.wedges[0].theta1, pie.wedges[0].theta2
54+
center, r = pie.wedges[0].center, pie.wedges[0].r
5255
bar_height = sum(age_ratios)
5356

5457
# draw top connecting line

galleries/examples/pie_and_polar_charts/pie_features.py

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,68 @@
1515
# ------------
1616
#
1717
# Plot a pie chart of animals and label the slices. To add
18-
# labels, pass a list of labels to the *labels* parameter
18+
# labels, pass a list of labels to the *wedge_labels* parameter.
1919

2020
import matplotlib.pyplot as plt
2121

2222
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
23-
sizes = [15, 30, 45, 10]
23+
sizes = [12, 24, 36, 8]
2424

2525
fig, ax = plt.subplots()
26-
ax.pie(sizes, labels=labels)
26+
ax.pie(sizes, wedge_labels=labels)
2727

2828
# %%
2929
# Each slice of the pie chart is a `.patches.Wedge` object; therefore in
3030
# addition to the customizations shown here, each wedge can be customized using
3131
# the *wedgeprops* argument, as demonstrated in
3232
# :doc:`/gallery/pie_and_polar_charts/nested_pie`.
3333
#
34+
# Controlling label positions
35+
# ---------------------------
36+
# If you want the labels outside the pie, set a *wedge_label_distance* greater than 1.
37+
# This is the distance from the center of the pie as a fraction of its radius.
38+
39+
fig, ax = plt.subplots()
40+
ax.pie(sizes, wedge_labels=labels, wedge_label_distance=1.1)
41+
42+
# %%
43+
#
3444
# Auto-label slices
3545
# -----------------
3646
#
37-
# Pass a function or format string to *autopct* to label slices.
47+
# Pass a format string to *wedge_labels* to label slices with their values...
48+
49+
fig, ax = plt.subplots()
50+
ax.pie(sizes, wedge_labels='{absval:.1f}')
51+
52+
# %%
53+
#
54+
# ...or with their percentages...
55+
56+
fig, ax = plt.subplots()
57+
ax.pie(sizes, wedge_labels='{frac:.1%}')
58+
59+
# %%
60+
#
61+
# ...or both.
3862

3963
fig, ax = plt.subplots()
40-
ax.pie(sizes, labels=labels, autopct='%1.1f%%')
64+
ax.pie(sizes, wedge_labels='{absval:d}\n{frac:.1%}')
65+
66+
# %%
67+
#
68+
# For more control over labels, or to add multiple sets, see
69+
# :doc:`/gallery/pie_and_polar_charts/pie_label`.
4170

4271
# %%
43-
# By default, the label values are obtained from the percent size of the slice.
4472
#
4573
# Color slices
4674
# ------------
4775
#
4876
# Pass a list of colors to *colors* to set the color of each slice.
4977

5078
fig, ax = plt.subplots()
51-
ax.pie(sizes, labels=labels,
52-
colors=['olivedrab', 'rosybrown', 'gray', 'saddlebrown'])
79+
ax.pie(sizes, colors=['olivedrab', 'rosybrown', 'gray', 'saddlebrown'])
5380

5481
# %%
5582
# Hatch slices
@@ -58,22 +85,9 @@
5885
# Pass a list of hatch patterns to *hatch* to set the pattern of each slice.
5986

6087
fig, ax = plt.subplots()
61-
ax.pie(sizes, labels=labels, hatch=['**O', 'oO', 'O.O', '.||.'])
62-
63-
# %%
64-
# Swap label and autopct text positions
65-
# -------------------------------------
66-
# Use the *labeldistance* and *pctdistance* parameters to position the *labels*
67-
# and *autopct* text respectively.
68-
69-
fig, ax = plt.subplots()
70-
ax.pie(sizes, labels=labels, autopct='%1.1f%%',
71-
pctdistance=1.25, labeldistance=.6)
88+
ax.pie(sizes, hatch=['**O', 'oO', 'O.O', '.||.'])
7289

7390
# %%
74-
# *labeldistance* and *pctdistance* are ratios of the radius; therefore they
75-
# vary between ``0`` for the center of the pie and ``1`` for the edge of the
76-
# pie, and can be set to greater than ``1`` to place text outside the pie.
7791
#
7892
# Explode, shade, and rotate slices
7993
# ---------------------------------
@@ -86,11 +100,10 @@
86100
#
87101
# This example orders the slices, separates (explodes) them, and rotates them.
88102

89-
explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
103+
explode = (0, 0.2, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
90104

91105
fig, ax = plt.subplots()
92-
ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
93-
shadow=True, startangle=90)
106+
ax.pie(sizes, explode=explode, wedge_labels='{frac:.1%}', shadow=True, startangle=90)
94107
plt.show()
95108

96109
# %%
@@ -107,8 +120,7 @@
107120

108121
fig, ax = plt.subplots()
109122

110-
ax.pie(sizes, labels=labels, autopct='%.0f%%',
111-
textprops={'size': 'small'}, radius=0.5)
123+
ax.pie(sizes, wedge_labels='{frac:.1%}', textprops={'size': 'small'}, radius=0.5)
112124
plt.show()
113125

114126
# %%
@@ -119,8 +131,8 @@
119131
# the `.Shadow` patch. This can be used to modify the default shadow.
120132

121133
fig, ax = plt.subplots()
122-
ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
123-
shadow={'ox': -0.04, 'edgecolor': 'none', 'shade': 0.9}, startangle=90)
134+
ax.pie(sizes, explode=explode, shadow={'ox': -0.04, 'edgecolor': 'none', 'shade': 0.9},
135+
startangle=90)
124136
plt.show()
125137

126138
# %%

lib/matplotlib/axes/_axes.py

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,13 +3514,13 @@ def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
35143514
self.add_container(stem_container)
35153515
return stem_container
35163516

3517-
@_api.make_keyword_only("3.10", "explode")
3518-
@_preprocess_data(replace_names=["x", "explode", "labels", "colors"])
3519-
def pie(self, x, explode=None, labels=None, colors=None,
3520-
autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
3521-
startangle=0, radius=1, counterclock=True,
3522-
wedgeprops=None, textprops=None, center=(0, 0),
3523-
frame=False, rotatelabels=False, *, normalize=True, hatch=None):
3517+
@_preprocess_data(replace_names=["x", "explode", "labels", "colors",
3518+
"wedge_labels"])
3519+
def pie(self, x, *, explode=None, labels=None, colors=None, wedge_labels=None,
3520+
wedge_label_distance=0.6, autopct=None, pctdistance=0.6, shadow=False,
3521+
labeldistance=False, startangle=0, radius=1, counterclock=True,
3522+
wedgeprops=None, textprops=None, center=(0, 0), frame=False,
3523+
rotatelabels=False, normalize=True, hatch=None):
35243524
"""
35253525
Plot a pie chart.
35263526
@@ -3540,7 +3540,13 @@ def pie(self, x, explode=None, labels=None, colors=None,
35403540
of the radius with which to offset each wedge.
35413541
35423542
labels : list, default: None
3543-
A sequence of strings providing the labels for each wedge
3543+
A sequence of strings providing the legend labels for each wedge.
3544+
3545+
.. deprecated:: 3.12
3546+
In future these labels will not appear on the wedges but only
3547+
be made available for the legend (see *labeldistance* below).
3548+
To label the wedges directly, use *wedge_labels* or the
3549+
`pie_label` method.
35443550
35453551
colors : :mpltype:`color` or list of :mpltype:`color`, default: None
35463552
A sequence of colors through which the pie chart will cycle. If
@@ -3553,12 +3559,34 @@ def pie(self, x, explode=None, labels=None, colors=None,
35533559
35543560
.. versionadded:: 3.7
35553561
3562+
wedge_labels : str or list of str, optional
3563+
A sequence of strings providing the labels for each wedge, or a format
3564+
string with ``absval`` and/or ``frac`` placeholders. For example, to label
3565+
each wedge with its value and the percentage in brackets::
3566+
3567+
wedge_labels="{absval:d} ({frac:.0%})"
3568+
3569+
For more control or to add multiple sets of labels, use `pie_label`.
3570+
3571+
.. versionadded:: 3.12
3572+
3573+
wedge_label_distance : float, default: 0.6
3574+
The radial position of the wedge labels, relative to the pie radius.
3575+
Values > 1 are outside the wedge and values < 1 are inside the wedge.
3576+
3577+
.. versionadded:: 3.12
3578+
35563579
autopct : None or str or callable, default: None
35573580
If not *None*, *autopct* is a string or function used to label the
35583581
wedges with their numeric value. The label will be placed inside
35593582
the wedge. If *autopct* is a format string, the label will be
35603583
``fmt % pct``. If *autopct* is a function, then it will be called.
35613584
3585+
.. admonition:: Discouraged
3586+
3587+
Consider using the *wedge_labels* parameter or `pie_label`
3588+
method instead.
3589+
35623590
pctdistance : float, default: 0.6
35633591
The relative distance along the radius at which the text
35643592
generated by *autopct* is drawn. To draw the text outside the pie,
@@ -3571,6 +3599,11 @@ def pie(self, x, explode=None, labels=None, colors=None,
35713599
If set to ``None``, labels are not drawn but are still stored for
35723600
use in `.legend`.
35733601
3602+
.. deprecated:: 3.12
3603+
From v3.14 *labeldistance* will default to ``None`` and will
3604+
later be removed altogether. Use *wedge_labels* and
3605+
*wedge_label_distance* or the `pie_label` method instead.
3606+
35743607
shadow : bool or dict, default: False
35753608
If bool, whether to draw a shadow beneath the pie. If dict, draw a shadow
35763609
passing the properties in the dict to `.Shadow`.
@@ -3654,6 +3687,17 @@ def pie(self, x, explode=None, labels=None, colors=None,
36543687
fracs = x
36553688
if labels is None:
36563689
labels = [''] * len(x)
3690+
elif labeldistance is False:
3691+
# NB: when the labeldistance default changes, both labeldistance and
3692+
# rotatelabels should be deprecated for removal.
3693+
msg = ("From %(removal)s labeldistance will default to None, so that the "
3694+
"strings provided in the labels parameter are only available for "
3695+
"the legend. Later labeldistance will be removed completely. To "
3696+
"preserve existing behavior for now, pass labeldistance=1.1. "
3697+
"Consider using the wedge_labels parameter or the pie_label method "
3698+
"instead of the labels parameter.")
3699+
_api.warn_deprecated("3.12", message=msg)
3700+
labeldistance = 1.1
36573701
if explode is None:
36583702
explode = [0] * len(x)
36593703
if len(x) != len(labels):
@@ -3711,11 +3755,16 @@ def get_next_color():
37113755

37123756
pc = PieContainer(slices, x, normalize)
37133757

3714-
if labeldistance is None:
3758+
if wedge_labels is not None:
3759+
self.pie_label(pc, wedge_labels, distance=wedge_label_distance,
3760+
textprops=textprops)
3761+
3762+
elif labeldistance is None:
37153763
# Insert an empty list of texts for backwards compatibility of the
37163764
# return value.
37173765
pc.add_texts([])
3718-
else:
3766+
3767+
if labeldistance is not None:
37193768
# Add labels to the wedges.
37203769
labels_textprops = {
37213770
'fontsize': mpl.rcParams['xtick.labelsize'],

lib/matplotlib/axes/_axes.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ class Axes(_AxesBase):
310310
explode: ArrayLike | None = ...,
311311
labels: Sequence[str] | None = ...,
312312
colors: ColorType | Sequence[ColorType] | None = ...,
313+
wedge_labels: str | Sequence | None = ...,
314+
wedge_label_distance: float | Sequence = ...,
313315
autopct: str | Callable[[float], str] | None = ...,
314316
pctdistance: float = ...,
315317
shadow: bool = ...,

lib/matplotlib/pyplot.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,13 +3939,16 @@ def phase_spectrum(
39393939
@_copy_docstring_and_deprecators(Axes.pie)
39403940
def pie(
39413941
x: ArrayLike,
3942+
*,
39423943
explode: ArrayLike | None = None,
39433944
labels: Sequence[str] | None = None,
39443945
colors: ColorType | Sequence[ColorType] | None = None,
3946+
wedge_labels: str | Sequence | None = None,
3947+
wedge_label_distance: float | Sequence = 0.6,
39453948
autopct: str | Callable[[float], str] | None = None,
39463949
pctdistance: float = 0.6,
39473950
shadow: bool = False,
3948-
labeldistance: float | None = 1.1,
3951+
labeldistance: float | None = False,
39493952
startangle: float = 0,
39503953
radius: float = 1,
39513954
counterclock: bool = True,
@@ -3954,7 +3957,6 @@ def pie(
39543957
center: tuple[float, float] = (0, 0),
39553958
frame: bool = False,
39563959
rotatelabels: bool = False,
3957-
*,
39583960
normalize: bool = True,
39593961
hatch: str | Sequence[str] | None = None,
39603962
data=None,
@@ -3964,6 +3966,8 @@ def pie(
39643966
explode=explode,
39653967
labels=labels,
39663968
colors=colors,
3969+
wedge_labels=wedge_labels,
3970+
wedge_label_distance=wedge_label_distance,
39673971
autopct=autopct,
39683972
pctdistance=pctdistance,
39693973
shadow=shadow,

0 commit comments

Comments
 (0)