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

Add support for multiple hatches, edgecolors and linewidths in histograms#28073

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
QuLogic merged 13 commits intomatplotlib:mainfromImpaler343:histogram
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
13 commits
Select commitHold shift + click to select a range
1a6ec0f
Add support for multiple hatches, edgecolor and linewidth in histograms
Impaler343Apr 13, 2024
0e52daa
Add hatch, linewidth and edgecolor parameters to multihist example
Impaler343Apr 14, 2024
34df06a
Add test for added parameters
Impaler343Apr 25, 2024
4fcb709
Reduced to 13 tests in total
Impaler343Jun 16, 2024
347ce22
Added color semantics test and modified vectorized parameters test
Impaler343Jun 25, 2024
d7ffeaa
Added None patch test
Impaler343Jun 28, 2024
9024be4
Heading edit
Impaler343Jun 28, 2024
3bfca5f
Simplified test
Impaler343Jun 28, 2024
6029e32
Updated none patch test
Impaler343Jul 1, 2024
0349e7d
Made None patch condition explicit
Impaler343Jul 2, 2024
d1a8079
Made suggested changes
Impaler343Jul 9, 2024
9a813f4
Added version-added directive
Impaler343Jul 10, 2024
43ce57d
Made suggested changes
Impaler343Jul 14, 2024
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
46 changes: 46 additions & 0 deletionsdoc/users/next_whats_new/histogram_vectorized_parameters.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
Vectorized ``hist`` style parameters
------------------------------------

The parameters *hatch*, *edgecolor*, *facecolor*, *linewidth* and *linestyle*
of the `~matplotlib.axes.Axes.hist` method are now vectorized.
This means that you can pass in individual parameters for each histogram
when the input *x* has multiple datasets.


.. plot::
:include-source: true
:alt: Four charts, each displaying stacked histograms of three Poisson distributions. Each chart differentiates the histograms using various parameters: top left uses different linewidths, top right uses different hatches, bottom left uses different edgecolors, and bottom right uses different facecolors. Each histogram on the left side also has a different edgecolor.

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(19680801)

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(9, 9))

data1 = np.random.poisson(5, 1000)
data2 = np.random.poisson(7, 1000)
data3 = np.random.poisson(10, 1000)

labels = ["Data 1", "Data 2", "Data 3"]

ax1.hist([data1, data2, data3], bins=range(17), histtype="step", stacked=True,
edgecolor=["red", "green", "blue"], linewidth=[1, 2, 3])
ax1.set_title("Different linewidths")
ax1.legend(labels)

ax2.hist([data1, data2, data3], bins=range(17), histtype="barstacked",
hatch=["/", ".", "*"])
ax2.set_title("Different hatch patterns")
ax2.legend(labels)

ax3.hist([data1, data2, data3], bins=range(17), histtype="bar", fill=False,
edgecolor=["red", "green", "blue"], linestyle=["--", "-.", ":"])
ax3.set_title("Different linestyles")
ax3.legend(labels)

ax4.hist([data1, data2, data3], bins=range(17), histtype="barstacked",
facecolor=["red", "green", "blue"])
ax4.set_title("Different facecolors")
ax4.legend(labels)

plt.show()
90 changes: 89 additions & 1 deletiongalleries/examples/statistics/histogram_multihist.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@
select these parameters:
http://docs.astropy.org/en/stable/visualization/histogram.html
"""

# %%
import matplotlib.pyplot as plt
import numpy as np

Expand DownExpand Up@@ -45,6 +45,94 @@
fig.tight_layout()
plt.show()

# %%
# -----------------------------------
# Setting properties for each dataset
# -----------------------------------
#
# You can style the histograms individually by passing a list of values to the
# following parameters:
#
# * edgecolor
# * facecolor
# * hatch
# * linewidth
# * linestyle
#
#
# edgecolor
# .........

fig, ax = plt.subplots()

edgecolors = ['green', 'red', 'blue']

ax.hist(x, n_bins, fill=False, histtype="step", stacked=True,
edgecolor=edgecolors, label=edgecolors)
ax.legend()
ax.set_title('Stacked Steps with Edgecolors')

plt.show()

# %%
# facecolor
# .........

fig, ax = plt.subplots()

facecolors = ['green', 'red', 'blue']

ax.hist(x, n_bins, histtype="barstacked", facecolor=facecolors, label=facecolors)
ax.legend()
ax.set_title("Bars with different Facecolors")

plt.show()

# %%
# hatch
# .....

fig, ax = plt.subplots()

hatches = [".", "o", "x"]

ax.hist(x, n_bins, histtype="barstacked", hatch=hatches, label=hatches)
ax.legend()
ax.set_title("Hatches on Stacked Bars")

plt.show()

# %%
# linewidth
# .........

fig, ax = plt.subplots()

linewidths = [1, 2, 3]
edgecolors = ["green", "red", "blue"]

ax.hist(x, n_bins, fill=False, histtype="bar", linewidth=linewidths,
edgecolor=edgecolors, label=linewidths)
ax.legend()
ax.set_title("Bars with Linewidths")

plt.show()

# %%
# linestyle
# .........

fig, ax = plt.subplots()

linestyles = ['-', ':', '--']

ax.hist(x, n_bins, fill=False, histtype='bar', linestyle=linestyles,
edgecolor=edgecolors, label=linestyles)
ax.legend()
ax.set_title('Bars with Linestyles')

plt.show()

# %%
#
# .. admonition:: References
Expand Down
42 changes: 34 additions & 8 deletionslib/matplotlib/axes/_axes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6937,7 +6937,13 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
DATA_PARAMETER_PLACEHOLDER

**kwargs
`~matplotlib.patches.Patch` properties
`~matplotlib.patches.Patch` properties. The following properties
additionally accept a sequence of values corresponding to the
datasets in *x*:
*edgecolors*, *facecolors*, *lines*, *linestyles*, *hatches*.

.. versionadded:: 3.10
Allowing sequences of values in above listed Patch properties.

See Also
--------
Expand DownExpand Up@@ -7210,15 +7216,35 @@ def hist(self, x, bins=None, range=None, density=False, weights=None,
# If None, make all labels None (via zip_longest below); otherwise,
# cast each element to str, but keep a single str as it.
labels = [] if label is None else np.atleast_1d(np.asarray(label, str))

if histtype == "step":
edgecolors = itertools.cycle(np.atleast_1d(kwargs.get('edgecolor',
colors)))
else:
edgecolors = itertools.cycle(np.atleast_1d(kwargs.get("edgecolor", None)))

facecolors = itertools.cycle(np.atleast_1d(kwargs.get('facecolor', colors)))
hatches = itertools.cycle(np.atleast_1d(kwargs.get('hatch', None)))
linewidths = itertools.cycle(np.atleast_1d(kwargs.get('linewidth', None)))
linestyles = itertools.cycle(np.atleast_1d(kwargs.get('linestyle', None)))

for patch, lbl in itertools.zip_longest(patches, labels):
if patch:
p = patch[0]
if not patch:
continue
p = patch[0]
kwargs.update({
'hatch': next(hatches),
'linewidth': next(linewidths),
'linestyle': next(linestyles),
'edgecolor': next(edgecolors),
'facecolor': next(facecolors),
})
p._internal_update(kwargs)
if lbl is not None:
p.set_label(lbl)
for p in patch[1:]:
p._internal_update(kwargs)
if lbl is not None:
p.set_label(lbl)
for p in patch[1:]:
p._internal_update(kwargs)
p.set_label('_nolegend_')
p.set_label('_nolegend_')

if nx == 1:
return tops[0], bins, patches[0]
Expand Down
67 changes: 67 additions & 0 deletionslib/matplotlib/tests/test_axes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4603,6 +4603,64 @@ def test_hist_stacked_bar():
ax.legend(loc='upper right', bbox_to_anchor=(1.0, 1.0), ncols=1)


@pytest.mark.parametrize('kwargs', ({'facecolor': ["b", "g", "r"]},
{'edgecolor': ["b", "g", "r"]},
{'hatch': ["/", "\\", "."]},
{'linestyle': ["-", "--", ":"]},
{'linewidth': [1, 1.5, 2]},
{'color': ["b", "g", "r"]}))
@check_figures_equal(extensions=["png"])
def test_hist_vectorized_params(fig_test, fig_ref, kwargs):
np.random.seed(19680801)
xs = [np.random.randn(n) for n in [20, 50, 100]]

(axt1, axt2) = fig_test.subplots(2)
(axr1, axr2) = fig_ref.subplots(2)

for histtype, axt, axr in [("stepfilled", axt1, axr1), ("step", axt2, axr2)]:
_, bins, _ = axt.hist(xs, bins=10, histtype=histtype, **kwargs)

kw, values = next(iter(kwargs.items()))
for i, (x, value) in enumerate(zip(xs, values)):
axr.hist(x, bins=bins, histtype=histtype, **{kw: value},
zorder=(len(xs)-i)/2)


@pytest.mark.parametrize('kwargs, patch_face, patch_edge',
# 'C0'(blue) stands for the first color of the
# default color cycle as well as the patch.facecolor rcParam
# When the expected edgecolor is 'k'(black),
# it corresponds to the patch.edgecolor rcParam
[({'histtype': 'stepfilled', 'color': 'r',
'facecolor': 'y', 'edgecolor': 'g'}, 'y', 'g'),
({'histtype': 'step', 'color': 'r',
'facecolor': 'y', 'edgecolor': 'g'}, ('y', 0), 'g'),
({'histtype': 'stepfilled', 'color': 'r',
'edgecolor': 'g'}, 'r', 'g'),
({'histtype': 'step', 'color': 'r',
'edgecolor': 'g'}, ('r', 0), 'g'),
({'histtype': 'stepfilled', 'color': 'r',
'facecolor': 'y'}, 'y', 'k'),
({'histtype': 'step', 'color': 'r',
'facecolor': 'y'}, ('y', 0), 'r'),
({'histtype': 'stepfilled',
'facecolor': 'y', 'edgecolor': 'g'}, 'y', 'g'),
({'histtype': 'step', 'facecolor': 'y',
'edgecolor': 'g'}, ('y', 0), 'g'),
({'histtype': 'stepfilled', 'color': 'r'}, 'r', 'k'),
({'histtype': 'step', 'color': 'r'}, ('r', 0), 'r'),
({'histtype': 'stepfilled', 'facecolor': 'y'}, 'y', 'k'),
({'histtype': 'step', 'facecolor': 'y'}, ('y', 0), 'C0'),
({'histtype': 'stepfilled', 'edgecolor': 'g'}, 'C0', 'g'),
({'histtype': 'step', 'edgecolor': 'g'}, ('C0', 0), 'g'),
({'histtype': 'stepfilled'}, 'C0', 'k'),
({'histtype': 'step'}, ('C0', 0), 'C0')])
def test_hist_color_semantics(kwargs, patch_face, patch_edge):
_, _, patches = plt.figure().subplots().hist([1, 2, 3], **kwargs)
assert all(mcolors.same_color([p.get_facecolor(), p.get_edgecolor()],
[patch_face, patch_edge]) for p in patches)


def test_hist_barstacked_bottom_unchanged():
b = np.array([10, 20])
plt.hist([[0, 1], [0, 1]], 2, histtype="barstacked", bottom=b)
Expand All@@ -4614,6 +4672,15 @@ def test_hist_emptydata():
ax.hist([[], range(10), range(10)], histtype="step")


def test_hist_unused_labels():
# When a list with one dataset and N elements is provided and N labels, ensure
# that the first label is used for the dataset and all other labels are ignored
fig, ax = plt.subplots()
ax.hist([[1, 2, 3]], label=["values", "unused", "also unused"])
_, labels = ax.get_legend_handles_labels()
assert labels == ["values"]


def test_hist_labels():
# test singleton labels OK
fig, ax = plt.subplots()
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp