-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
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
base: main
Are you sure you want to change the base?
Patchcollection keeps original patch #22814
Conversation
…llection. PatchCollection will currently ignore hatches of the provided patches, only allowing a hatch passed as a keyword into the constructor. If match_original is true, we now keep the hatch of the first patch provided in the collection. Additionally, the hatchcolor is determined by the edge color, so we will only pass the edgecolors of the patches to the Collection if the edgecolor is not blank - its default color of [0, 0, 0, 0]. This ensures that the hatch will use its default of black in the case where no edgecolor of the patches was ever set.
…r a PatchCollection when match_original is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for opening your first PR into Matplotlib!
If you have not heard from us in a while, please feel free to ping @matplotlib/developers
or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.
You can also join us on gitter for real-time discussion.
For details on testing, writing docs, and our review process, please see the developer guide
We strive to be a welcoming and open project. Please follow our Code of Conduct.
lib/matplotlib/collections.py
Outdated
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: | ||
kwargs['hatch'] = patches[0].get_hatch() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are going to only pick of the hatch from the first patch, then we should warn or raise if we are going to ignore the rest of the hatches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? If that's true, it would be impossible to make a collection of multiple patches w/ hatches without getting a warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I was not clear. The check should be "are all of the hatches the same? if so carry on, if not fail!" As implemented if the user passes in
[
mpatches.Rectangle((0, 0), 0.2, .2, hatch="/"),
mpatches.Rectangle((0.4, 0.4), 0.2, .2, hatch="\\")
]
then the first hatch will be used for both and we will silently drop the "\\"
on the second one!
lib/matplotlib/collections.py
Outdated
@@ -1827,12 +1828,20 @@ def determine_facecolor(patch): | |||
if patch.get_fill(): | |||
return patch.get_facecolor() | |||
return [0, 0, 0, 0] | |||
|
|||
def is_default(c): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This in only the default default (that is, there is a set of rcparams which will cause this to be miss. Looking at
matplotlib/lib/matplotlib/patches.py
Lines 315 to 339 in c19cd34
def _set_edgecolor(self, color): | |
set_hatch_color = True | |
if color is None: | |
if (mpl.rcParams['patch.force_edgecolor'] or | |
not self._fill or self._edge_default): | |
color = mpl.rcParams['patch.edgecolor'] | |
else: | |
color = 'none' | |
set_hatch_color = False | |
self._edgecolor = colors.to_rgba(color, self._alpha) | |
if set_hatch_color: | |
self._hatch_color = self._edgecolor | |
self.stale = True | |
def set_edgecolor(self, color): | |
""" | |
Set the patch edge color. | |
Parameters | |
---------- | |
color : color or None | |
""" | |
self._original_edgecolor = color | |
self._set_edgecolor(color) |
p._original_edgecolor
and if None
either re-implement the default logic or pass in None
here (if we can) and let the next layer down deal with resolving the default behavior.
Thank you for working on this @hhalwan and apologies for the delay in getting this reviewed. Do my comments make sense? |
…h._original_edgecolor to see if edgecolors were set.
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 " |
There was a problem hiding this comment.
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.
@hhalwan do you plan to come back to this? |
@timhoffm I don't have time right now, I'm happy to let someone else take it up. |
PR Summary
Fixes this issue. PatchCollection currently ignores the hatches of the provided patches, only allowing a hatch passed as a keyword into the constructor. If match_original is true, we now keep the hatch of the first patch provided in the collection, rather than using the hatch passed as a keyword into the constructor. Edited the doc strings to reflect this. Additionally, the hatchcolor is determined by the edge color, so we will only initialize the collection with the edgecolors of the patches if the edgecolor is not blank - its default color of [0, 0, 0, 0]. This ensures that the hatch will use its default of black in the case where no edgecolor of the patches is ever set.
PR Checklist
Tests and Styling
pytest
passes).flake8-docstrings
and runflake8 --docstring-convention=all
).Documentation
doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).