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 wedge_labels parameter forpie#29152

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

Draft
rcomer wants to merge1 commit intomatplotlib:main
base:main
Choose a base branch
Loading
fromrcomer:pie-fmt
Draft
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletionsdoc/api/next_api_changes/behavior/29152_REC.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
Return value of ``pie``
~~~~~~~~~~~~~~~~~~~~~~~
Previously, if no *labels* were passed to `~.Axes.pie`, and *labeldistance* was
not ``None``, empty text labels would be added to the axes and returned. This
is no longer the case. To continue creating empty labels, either pass an empty
string with the new *wedge_labels* parameter ``wedge_labels=''`` or, for
compatibility with older Matplotlib versions, pass an empty string for each wedge
via the *labels* parameter, i.e. ``labels=[''] * number_of_wedges``. Note the
latter option will stop working at Matplotlib 3.16.
10 changes: 10 additions & 0 deletionsdoc/api/next_api_changes/deprecations/29152_REC.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
``pie`` *labels* and *labeldistance* parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Currently the *labels* parameter of `~.Axes.pie` is used both for annotating the
pie wedges directly, and for automatic legend entries. For consistency
with other plotting methods, in future *labels* will only be used for the legend.

The *labeldistance* parameter will therefore default to ``None`` from Matplotlib
3.14, when it will also be deprecated and then removed in Matplotlib 3.16. To
preserve the existing behavior for now, set ``labeldistance=1.1``. For the longer
term, use the new *wedge_labels* parameter of `~.Axes.pie` instead of *labels*.
18 changes: 18 additions & 0 deletionsdoc/release/next_whats_new/pie_wedge_labels.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
New *wedge_labels* parameter for pie
------------------------------------

`~.Axes.pie` now accepts a *wedge_labels* parameter which may be used to
annotate the wedges of the pie chart. It can take

* a list of strings, similar to the existing *labels* parameter
* a format string in analogy to the existing *autopct* parameter except that it
uses the `str.format` method, and it can handle absolute values as well as
fractions/percentages

To add multiple labels per wedge, *wedge_labels* can take a sequence of any combination
of the above two options.

*wedge_labels* have accompanying *wedge_label_distance* and *rotate_wedge_labels*
parameters, to customise the position and rotation of the labels.

For examples, see :doc:`/gallery/pie_and_polar_charts/pie_features`.
7 changes: 4 additions & 3 deletionsgalleries/examples/misc/svg_filter_pie.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,11 +28,12 @@

# We want to draw the shadow for each pie, but we will not use "shadow"
# option as it doesn't save the references to the shadow patches.
pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')
pies = ax.pie(fracs, explode=explode, wedge_labels=[labels, '{frac:.1%}'],
wedge_label_distance=[1.1, 0.6])

for win pies[0]:
for w, labelinzip(pies[0], labels):
# set the id with the label.
w.set_gid(w.get_label())
w.set_gid(label)

# we don't want to draw the edge of the pie
w.set_edgecolor("none")
Expand Down
5 changes: 3 additions & 2 deletionsgalleries/examples/pie_and_polar_charts/bar_of_pie.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,8 +25,9 @@
explode = [0.1, 0, 0]
# rotate so that first wedge is split by the x-axis
angle = -180 * overall_ratios[0]
wedges, *_ = ax1.pie(overall_ratios, autopct='%1.1f%%', startangle=angle,
labels=labels, explode=explode)
wedges, *_ = ax1.pie(
overall_ratios, startangle=angle, explode=explode,
wedge_labels=[labels, '{frac:.1%}'], wedge_label_distance=[1.1, 0.6])

# bar chart parameters
age_ratios = [.33, .54, .07, .06]
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,9 +15,9 @@
# Now it's time for the pie. Starting with a pie recipe, we create the data
# and a list of labels from it.
#
# We can provide afunctionto the``autopct`` argument, which will expand
#automatic percentage labeling by showing absolute values; we calculate
#the latter back from relative data and the known sum of all values.
# We can provide aformat stringto the*wedge_labels* parameter, to
#automatically label each ingredient's wedge with its weight in grams and
#percentages.
#
# We then create the pie and store the returned objects for later. The first
# returned element of the returned tuple is a list of the wedges. Those are
Expand All@@ -31,32 +31,24 @@
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
fig, ax = plt.subplots(figsize=(6, 3))

recipe = ["375 g flour",
"75 g sugar",
"250 g butter",
"300 g berries"]

data = [float(x.split()[0]) for x in recipe]
data = [int(x.split()[0]) for x in recipe]
ingredients = [x.split()[-1] for x in recipe]


def func(pct, allvals):
absolute = int(np.round(pct/100.*np.sum(allvals)))
return f"{pct:.1f}%\n({absolute:d} g)"


wedges, texts, autotexts = ax.pie(data, autopct=lambda pct: func(pct, data),
textprops=dict(color="w"))
wedges, texts = ax.pie(data, wedge_labels='{frac:.1%}\n({absval:d}g)',
textprops=dict(color="w", size=8, weight="bold"))

ax.legend(wedges, ingredients,
title="Ingredients",
loc="center left",
bbox_to_anchor=(1, 0, 0.5, 1))

plt.setp(autotexts, size=8, weight="bold")

ax.set_title("Matplotlib bakery: A pie")

plt.show()
Expand DownExpand Up@@ -97,7 +89,7 @@ def func(pct, allvals):

data = [225, 90, 50, 60, 100, 5]

wedges,texts = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40)
wedges,_ = ax.pie(data, wedgeprops=dict(width=0.5), startangle=-40)

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),
Expand Down
75 changes: 50 additions & 25 deletionsgalleries/examples/pie_and_polar_charts/pie_features.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,40 +15,75 @@
# ------------
#
# Plot a pie chart of animals and label the slices. To add
# labels, pass a list of labels to the *labels* parameter
# labels, pass a list of labels to the *wedge_labels* parameter.

import matplotlib.pyplot as plt

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
sizes = [12, 24, 36, 8]

fig, ax = plt.subplots()
ax.pie(sizes,labels=labels)
ax.pie(sizes,wedge_labels=labels)

# %%
# Each slice of the pie chart is a `.patches.Wedge` object; therefore in
# addition to the customizations shown here, each wedge can be customized using
# the *wedgeprops* argument, as demonstrated in
# :doc:`/gallery/pie_and_polar_charts/nested_pie`.
#
# Controlling label positions
# ---------------------------
# If you want the labels outside the pie, set a *wedge_label_distance* greater than 1.
# This is the distance from the center of the pie as a fraction of its radius.

fig, ax = plt.subplots()
ax.pie(sizes, wedge_labels=labels, wedge_label_distance=1.1)

# %%
#
# Auto-label slices
# -----------------
#
# Pass a function or format string to *autopct* to label slices.
# Pass a format string to *wedge_labels* to label slices with their values...

fig, ax = plt.subplots()
ax.pie(sizes, wedge_labels='{absval:.1f}')

# %%
#
# ...or with their percentages...

fig, ax = plt.subplots()
ax.pie(sizes, wedge_labels='{frac:.1%}')

# %%
#
# ...or both.

fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, autopct='%1.1f%%')
ax.pie(sizes, wedge_labels='{absval:d}\n{frac:.1%}')


# %%
#
# Multiple labels
# ---------------
#
# Pass both a list of labels and a format string to *wedge_labels*, with a
# corresponding *wedge_label_distance* for each.

fig, ax = plt.subplots()
ax.pie(sizes, wedge_labels=[labels, '{frac:.1%}'], wedge_label_distance=[1.1, 0.6])

# %%
# By default, the label values are obtained from the percent size of the slice.
#
# Color slices
# ------------
#
# Pass a list of colors to *colors* to set the color of each slice.

fig, ax = plt.subplots()
ax.pie(sizes,labels=labels,
ax.pie(sizes,wedge_labels=labels, wedge_label_distance=1.1,
colors=['olivedrab', 'rosybrown', 'gray', 'saddlebrown'])

# %%
Expand All@@ -58,22 +93,10 @@
# Pass a list of hatch patterns to *hatch* to set the pattern of each slice.

fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, hatch=['**O', 'oO', 'O.O', '.||.'])

# %%
# Swap label and autopct text positions
# -------------------------------------
# Use the *labeldistance* and *pctdistance* parameters to position the *labels*
# and *autopct* text respectively.

fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, autopct='%1.1f%%',
pctdistance=1.25, labeldistance=.6)
ax.pie(sizes, wedge_labels=labels, wedge_label_distance=1.1,
hatch=['**O', 'oO', 'O.O', '.||.'])

# %%
# *labeldistance* and *pctdistance* are ratios of the radius; therefore they
# vary between ``0`` for the center of the pie and ``1`` for the edge of the
# pie, and can be set to greater than ``1`` to place text outside the pie.
#
# Explode, shade, and rotate slices
# ---------------------------------
Expand All@@ -89,8 +112,8 @@
explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')

fig, ax = plt.subplots()
ax.pie(sizes, explode=explode,labels=labels,autopct='%1.1f%%',
shadow=True, startangle=90)
ax.pie(sizes, explode=explode,wedge_labels=[labels,'{frac:.1%}'],
wedge_label_distance=[1.1, 0.6],shadow=True, startangle=90)
plt.show()

# %%
Expand All@@ -107,7 +130,8 @@

fig, ax = plt.subplots()

ax.pie(sizes, labels=labels, autopct='%.0f%%',
ax.pie(sizes, wedge_labels=[labels, '{frac:.1%}'],
wedge_label_distance=[1.1, 0.6],
textprops={'size': 'small'}, radius=0.5)
plt.show()

Expand All@@ -119,7 +143,8 @@
# the `.Shadow` patch. This can be used to modify the default shadow.

fig, ax = plt.subplots()
ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
ax.pie(sizes, explode=explode, wedge_labels=[labels, '{frac:.1%}'],
wedge_label_distance=[1.1, 0.6],
shadow={'ox': -0.04, 'edgecolor': 'none', 'shade': 0.9}, startangle=90)
plt.show()

Expand Down
14 changes: 12 additions & 2 deletionslib/matplotlib/__init__.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1429,7 +1429,8 @@ def _add_data_doc(docstring, replace_names):
return docstring.replace(' DATA_PARAMETER_PLACEHOLDER', data_doc)


def _preprocess_data(func=None, *, replace_names=None, label_namer=None):
def _preprocess_data(func=None, *, replace_names=None, replace_names_multi=None,
label_namer=None):
"""
A decorator to add a 'data' kwarg to a function.

Expand All@@ -1454,6 +1455,11 @@ def func(ax, *args, **kwargs): ...
replace_names : list of str or None, default: None
The list of parameter names for which lookup into *data* should be
attempted. If None, replacement is attempted for all arguments.
replace_names_multi : list of str or None, default: None
As for *replace_names*, but if a sequence is passed, a lookup into *data*
will be attempted for each element of the sequence. Currently only
supported for parameters named in the function signature (not those passed via
*args or **kwargs).
label_namer : str, default: None
If set e.g. to "namer" (which must be a kwarg in the function's
signature -- not as ``**kwargs``), if the *namer* argument passed in is
Expand All@@ -1471,7 +1477,8 @@ def func(foo, label=None): ...
if func is None: # Return the actual decorator.
return functools.partial(
_preprocess_data,
replace_names=replace_names, label_namer=label_namer)
replace_names=replace_names, replace_names_multi=replace_names_multi,
label_namer=label_namer)

sig = inspect.signature(func)
varargs_name = None
Expand DownExpand Up@@ -1523,6 +1530,9 @@ def inner(ax, *args, data=None, **kwargs):
else:
if replace_names is None or k in replace_names:
bound.arguments[k] = _replacer(data, v)
if (replace_names_multi is not None and k in replace_names_multi and
not cbook.is_scalar_or_string(v)):
bound.arguments[k] = [_replacer(data, vi) for vi in v]

new_args = bound.args
new_kwargs = bound.kwargs
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp