Skip to content

[ENH] hatch keyword for pie + some pie documentation #24470

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 18 additions & 0 deletions doc/users/next_whats_new/pie_hatch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
``hatch`` parameter for pie
-------------------------------------------

`~matplotlib.axes.Axes.pie` now accepts a *hatch* keyword that takes as input
a hatch or list of hatches:

.. plot::
:include-source: true
:alt: Two pie charts, identified as ax1 and ax2, both have a small blue slice, a medium orange slice, and a large green slice. ax1 has a dot hatching on the small slice, a small open circle hatching on the medium slice, and a large open circle hatching on the large slice. ax2 has the same large open circle with a dot hatch on every slice.

fig, (ax1, ax2) = plt.subplots(ncols=2)
x = [10, 30, 60]

ax1.pie(x, hatch=['.', 'o', 'O'])
ax2.pie(x, hatch='.O')

ax1.set_title("hatch=['.', 'o', 'O']")
ax2.set_title("hatch='.O'")
57 changes: 35 additions & 22 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3083,7 +3083,7 @@ def pie(self, x, explode=None, labels=None, colors=None,
autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
startangle=0, radius=1, counterclock=True,
wedgeprops=None, textprops=None, center=(0, 0),
frame=False, rotatelabels=False, *, normalize=True):
frame=False, rotatelabels=False, *, normalize=True, hatch=None):
"""
Plot a pie chart.

Expand All @@ -3109,29 +3109,34 @@ def pie(self, x, explode=None, labels=None, colors=None,
A sequence of colors through which the pie chart will cycle. If
*None*, will use the colors in the currently active cycle.

hatch : str or list, default: None
Hatching pattern applied to all pie wedges or sequence of patterns
through which the chart will cycle. For a list of valid patterns,
see :doc:`/gallery/shapes_and_collections/hatch_style_reference`.

.. versionadded:: 3.7

autopct : None or str or callable, default: None
If not *None*, is a string or function used to label the wedges
with their numeric value. The label will be placed inside the
wedge. If it is a format string, the label will be ``fmt % pct``.
If it is a function, it will be called.
If not *None*, *autopct* is a string or function used to label the
wedges with their numeric value. The label will be placed inside
the wedge. If *autopct* is a format string, the label will be
``fmt % pct``. If *autopct* is a function, then it will be called.

pctdistance : float, default: 0.6
The ratio between the center of each pie slice and the start of
the text generated by *autopct*. Ignored if *autopct* is *None*.
The relative distance along the radius at which the the text
generated by *autopct* is drawn. To draw the text outside the pie,
set *pctdistance* > 1. This parameter is ignored if *autopct* is
``None``.

labeldistance : float or None, default: 1.1
The relative distance along the radius at which the labels are
drawn. To draw the labels inside the pie, set *labeldistance* < 1.
If set to ``None``, labels are not drawn but are still stored for
use in `.legend`.

shadow : bool, default: False
Draw a shadow beneath the pie.

normalize : bool, default: True
When *True*, always make a full pie by normalizing x so that
``sum(x) == 1``. *False* makes a partial pie if ``sum(x) <= 1``
and raises a `ValueError` for ``sum(x) > 1``.

labeldistance : float or None, default: 1.1
The radial distance at which the pie labels are drawn.
If set to ``None``, label are not drawn, but are stored for use in
``legend()``

startangle : float, default: 0 degrees
The angle by which the start of the pie is rotated,
counterclockwise from the x-axis.
Expand All @@ -3143,11 +3148,11 @@ def pie(self, x, explode=None, labels=None, colors=None,
Specify fractions direction, clockwise or counterclockwise.

wedgeprops : dict, default: None
Dict of arguments passed to the wedge objects making the pie.
For example, you can pass in ``wedgeprops = {'linewidth': 3}``
to set the width of the wedge border lines equal to 3.
For more details, look at the doc/arguments of the wedge object.
By default, ``clip_on=False``.
Dict of arguments passed to each `.patches.Wedge` of the pie.
For example, ``wedgeprops = {'linewidth': 3}`` sets the width of
the wedge border lines equal to 3. By default, ``clip_on=False``.
When there is a conflict between these properties and other
keywords, properties passed to *wedgeprops* take precedence.

textprops : dict, default: None
Dict of arguments to pass to the text objects.
Expand All @@ -3161,6 +3166,11 @@ def pie(self, x, explode=None, labels=None, colors=None,
rotatelabels : bool, default: False
Rotate each label to the angle of the corresponding slice if true.

normalize : bool, default: True
When *True*, always make a full pie by normalizing x so that
``sum(x) == 1``. *False* makes a partial pie if ``sum(x) <= 1``
and raises a `ValueError` for ``sum(x) > 1``.

data : indexable object, optional
DATA_PARAMETER_PLACEHOLDER

Expand Down Expand Up @@ -3215,6 +3225,8 @@ def pie(self, x, explode=None, labels=None, colors=None,
def get_next_color():
return next(color_cycle)

hatch_cycle = itertools.cycle(np.atleast_1d(hatch))

_api.check_isinstance(Number, radius=radius, startangle=startangle)
if radius <= 0:
raise ValueError(f'radius must be a positive number, not {radius}')
Expand All @@ -3241,6 +3253,7 @@ def get_next_color():
w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2),
360. * max(theta1, theta2),
facecolor=get_next_color(),
hatch=next(hatch_cycle),
clip_on=False,
label=label)
w.set(**wedgeprops)
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/pyplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2784,15 +2784,15 @@ def pie(
pctdistance=0.6, shadow=False, labeldistance=1.1,
startangle=0, radius=1, counterclock=True, wedgeprops=None,
textprops=None, center=(0, 0), frame=False,
rotatelabels=False, *, normalize=True, data=None):
rotatelabels=False, *, normalize=True, hatch=None, data=None):
return gca().pie(
x, explode=explode, labels=labels, colors=colors,
autopct=autopct, pctdistance=pctdistance, shadow=shadow,
labeldistance=labeldistance, startangle=startangle,
radius=radius, counterclock=counterclock,
wedgeprops=wedgeprops, textprops=textprops, center=center,
frame=frame, rotatelabels=rotatelabels, normalize=normalize,
**({"data": data} if data is not None else {}))
hatch=hatch, **({"data": data} if data is not None else {}))


# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
Expand Down
18 changes: 18 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5744,6 +5744,24 @@ def test_normalize_kwarg_pie():
assert abs(t2[0][-1].theta2 - 360.) > 1e-3


@check_figures_equal()
def test_pie_hatch_single(fig_test, fig_ref):
x = [0.3, 0.3, 0.1]
hatch = '+'
fig_test.subplots().pie(x, hatch=hatch)
wedges, _ = fig_ref.subplots().pie(x)
[w.set_hatch(hatch) for w in wedges]


@check_figures_equal()
def test_pie_hatch_multi(fig_test, fig_ref):
x = [0.3, 0.3, 0.1]
hatch = ['/', '+', '.']
fig_test.subplots().pie(x, hatch=hatch)
wedges, _ = fig_ref.subplots().pie(x)
[w.set_hatch(hp) for w, hp in zip(wedges, hatch)]


@image_comparison(['set_get_ticklabels.png'])
def test_set_get_ticklabels():
# test issue 2246
Expand Down