Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ def get_hatch(self):
def get_hatch_path(self, density=6.0):
"""Return a `.Path` for the current hatch."""
hatch = self.get_hatch()
if hatch is None:
if hatch is None or all(h is None for h in hatch):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if hatch is None or all(h is None for h in hatch):
if all(h is None for h in np.at_least1d(hatch)):

h is not None will trigger checking the second condition, which will then try to iterate over a maybe not iterable hatch.

return None
return Path.hatch(hatch, density)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

will this need to be looped if passed a list of hatches?


Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/backend_bases.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ class GraphicsContextBase:
def set_gid(self, id: int | None) -> None: ...
def set_snap(self, snap: bool | None) -> None: ...
def set_hatch(self, hatch: str | None) -> None: ...
def get_hatch(self) -> str | None: ...
def get_hatch_path(self, density: float = ...) -> Path: ...
def get_hatch(self) -> str | None | tuple[str | None]: ...
def get_hatch_path(self, density: float = ...) -> Path | tuple[Path]: ...
def get_hatch_color(self) -> ColorType: ...
def set_hatch_color(self, hatch_color: ColorType) -> None: ...
def get_hatch_linewidth(self) -> float: ...
Expand Down
59 changes: 40 additions & 19 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def __init__(self, *,
# Flags set by _set_mappable_flags: are colors from mapping an array?
self._face_is_mapped = None
self._edge_is_mapped = None
self._match_original = False
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

where is this set?

self._mapped_colors = None # calculated in update_scalarmappable
self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color'])
self.set_facecolor(facecolors)
Expand Down Expand Up @@ -423,13 +424,31 @@ def draw(self, renderer):
self._antialiaseds, self._urls,
"screen")

renderer.draw_path_collection(
gc, transform.frozen(), paths,
self.get_transforms(), offsets, offset_trf,
self.get_facecolor(), self.get_edgecolor(),
self._linewidths, self._linestyles,
self._antialiaseds, self._urls,
"screen") # offset_position, kept for backcompat.
fcolor = itertools.cycle(facecolors) if facecolors.any() \
else itertools.repeat([])
ecolor = itertools.cycle(edgecolors) if edgecolors.any() \
else itertools.repeat([])
lwidth = itertools.cycle(self._linewidths)
lstyle = itertools.cycle(self._linestyles)
antialiased = itertools.cycle(self._antialiaseds)

if self._match_original:
for idx in range(len(paths)):
gc.set_hatch(self._hatch[idx])
renderer.draw_path_collection(
gc, transform.frozen(), [paths[idx]],
self.get_transforms(), offsets, offset_trf,
[next(fcolor)], [next(ecolor)], [next(lwidth)], [next(lstyle)],
[next(antialiased)], self._urls,
"screen") # offset_position, kept for backcompat.
else:
renderer.draw_path_collection(
gc, transform.frozen(), paths,
self.get_transforms(), offsets, offset_trf,
self.get_facecolor(), self.get_edgecolor(),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

these return lists too, so why can't self.get_hatches, w/ changes as needed being implemented down in .draw_path_collection?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Makes sense

self._linewidths, self._linestyles,
self._antialiaseds, self._urls,
"screen")

gc.restore()
renderer.close_group(self.__class__.__name__)
Expand Down Expand Up @@ -1846,8 +1865,9 @@ def __init__(self, patches, *, match_original=False, **kwargs):
a heterogeneous assortment of different patch types.

match_original : bool, default: False
If True, use the colors and linewidths of the original
patches. If False, new colors may be assigned by
If True, use the colors, linewidths, linestyles
and the hatch of the original patches.
If False, new colors may be assigned by
Comment on lines +1853 to +1855
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how are new colors assigned if not passed in as part of the original patches?

providing the standard collection arguments, facecolor,
edgecolor, linewidths, norm or cmap.

Expand All @@ -1867,16 +1887,17 @@ def __init__(self, patches, *, match_original=False, **kwargs):
"""

if match_original:
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]
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]
self._match_original = True
kwargs['facecolors'] = tuple([p.get_facecolor() for p in patches])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why does it need to be a tuple?

kwargs['linewidths'] = tuple([p.get_linewidth() for p in patches])
kwargs['linestyles'] = tuple([p.get_linestyle() for p in patches])
kwargs['antialiaseds'] = tuple([p.get_antialiased() for p in patches])
kwargs['hatch'] = tuple([p.get_hatch() for p in patches])

# Edgecolors are handled separately because are defaulted to None
# and the Hatch colors depend on them.
if all(p._original_edgecolor is not None for p in patches):
kwargs["edgecolors"] = tuple([p.get_edgecolor() for p in patches])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

how do you handle a patch collection where some edges are none and some aren't?


super().__init__(**kwargs)

Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/hatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def __init__(self, hatch, density):


def _validate_hatch_pattern(hatch):
valid_hatch_patterns = set(r'-+|/\xXoO.*')
valid_hatch_patterns = set(r'-+|/\xXoO.*').union({None})
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why do you need to add None if next line you only validate if not none?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In the case of a list of Nones, the set function makes it into a singleton set with None. So it fails the

if hatch is not None:

condition

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, but then I think you don't need the if hatch is not None anymore and can just go straight to validation

if hatch is not None:
invalids = set(hatch).difference(valid_hatch_patterns)
if invalids:
Expand Down