Skip to content

Patchcollection keeps original patch #22814

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
21 changes: 16 additions & 5 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1808,9 +1808,10 @@ def __init__(self, patches, match_original=False, **kwargs):

*match_original*
If True, use the colors and linewidths of the original
patches. If False, new colors may be assigned by
providing the standard collection arguments, facecolor,
edgecolor, linewidths, norm or cmap.
patches. Also use the hatch of the first patch provided.
If False, new colors may be assigned by providing the
standard collection arguments, facecolor, edgecolor,
linewidths, norm or cmap.

If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds* are
None, they default to their `.rcParams` patch setting, in sequence
Expand All @@ -1827,12 +1828,22 @@ def determine_facecolor(patch):
if patch.get_fill():
return patch.get_facecolor()
return [0, 0, 0, 0]

kwargs['facecolors'] = [determine_facecolor(p) for p in patches]
kwargs['edgecolors'] = [p.get_edgecolor() for p in patches]
# If no edgecolor was set within the collection of patches
# then we will not supply the edgecolor argument, which allows the
# default hatch color to be used.
if any(p._original_edgecolor is not None for p in patches):
kwargs['edgecolors'] = [p.get_edgecolor() for p in patches]
kwargs['linewidths'] = [p.get_linewidth() for p in patches]
kwargs['linestyles'] = [p.get_linestyle() for p in patches]
kwargs['antialiaseds'] = [p.get_antialiased() for p in patches]
if patches:
hatch = patches[0].get_hatch()
kwargs['hatch'] = hatch
if any(p.get_hatch() != hatch for p in patches):
warnings.warn("More than one type of hatch detected in "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use _api.warn_external? Also should be tested.

"PatchCollection. Only using hatch of "
"first patch.")

super().__init__(**kwargs)

Expand Down
23 changes: 23 additions & 0 deletions lib/matplotlib/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from matplotlib.backend_bases import MouseEvent
import matplotlib.collections as mcollections
import matplotlib.colors as mcolors
import matplotlib.patches as mpatches
import matplotlib.transforms as mtransforms
from matplotlib.collections import (Collection, LineCollection,
EventCollection, PolyCollection)
Expand Down Expand Up @@ -1117,3 +1118,25 @@ def test_set_offset_units():
off0 = sc.get_offsets()
sc.set_offsets(list(zip(y, d)))
np.testing.assert_allclose(off0, sc.get_offsets())


@check_figures_equal(extensions=['png'])
def test_patch_collection_keeps_hatch(fig_test, fig_ref):
# When creating a PatchCollection, the hatch of the original patches should
# be used if match_original == True.
ax = fig_test.subplots()
patches = [
mpatches.Rectangle((0, 0), 0.2, .2, hatch="/"),
mpatches.Rectangle((0.4, 0.4), 0.2, .2, hatch="/")
]
collection = mcollections.PatchCollection(patches, match_original=True)
ax.add_collection(collection)

ax = fig_ref.subplots()
patches = [
mpatches.Rectangle((0, 0), 0.2, .2),
mpatches.Rectangle((0.4, 0.4), 0.2, .2)
]
collection = mcollections.PatchCollection(patches, match_original=False,
hatch="/")
ax.add_collection(collection)