From e1916505eec44b6656c7ee13be0bcd842aaecc45 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 9 Apr 2024 12:02:21 +0530 Subject: [PATCH 01/16] Add hatch linewidth setter in Graphics Context Base --- lib/matplotlib/backend_bases.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 95ed49612b35..80e57311d6de 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -961,6 +961,10 @@ def get_hatch_linewidth(self): """Get the hatch linewidth.""" return self._hatch_linewidth + def set_hatch_linewidth(self, hatch_linewidth): + """Set the hatch linewidth.""" + self._hatch_linewidth = hatch_linewidth + def get_sketch_params(self): """ Return the sketch parameters for the artist. From 7faf10415276aabacba85a29388dc2a35de8637d Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 9 Apr 2024 12:27:24 +0530 Subject: [PATCH 02/16] Add linewidth parameter to hatch style in PDF, PS and SVG backends --- lib/matplotlib/backends/backend_pdf.py | 51 ++++++++++++++------------ lib/matplotlib/backends/backend_ps.py | 3 +- lib/matplotlib/backends/backend_svg.py | 9 +++-- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 44b85cd3136d..07707710494c 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -732,7 +732,7 @@ def __init__(self, filename, metadata=None): self._soft_mask_states = {} self._soft_mask_seq = (Name(f'SM{i}') for i in itertools.count(1)) self._soft_mask_groups = [] - self.hatchPatterns = {} + self._hatch_patterns = {} self._hatch_pattern_seq = (Name(f'H{i}') for i in itertools.count(1)) self.gouraudTriangles = [] @@ -1536,25 +1536,29 @@ def _write_soft_mask_groups(self): def hatchPattern(self, hatch_style): # The colors may come in as numpy arrays, which aren't hashable if hatch_style is not None: - edge, face, hatch = hatch_style + edge, face, hatch, lw = hatch_style if edge is not None: edge = tuple(edge) if face is not None: face = tuple(face) - hatch_style = (edge, face, hatch) + hatch_style = (edge, face, hatch, lw) - pattern = self.hatchPatterns.get(hatch_style, None) + pattern = self._hatch_patterns.get(hatch_style, None) if pattern is not None: return pattern name = next(self._hatch_pattern_seq) - self.hatchPatterns[hatch_style] = name + self._hatch_patterns[hatch_style] = name return name + hatchPatterns = _api.deprecated("3.8")(property(lambda self: { + k: (e, f, h) for k, (e, f, h, l) in self._hatch_patterns.items() + })) + def writeHatches(self): hatchDict = dict() sidelen = 72.0 - for hatch_style, name in self.hatchPatterns.items(): + for hatch_style, name in self._hatch_patterns.items(): ob = self.reserveObject('hatch pattern') hatchDict[name] = ob res = {'Procsets': @@ -1569,7 +1573,7 @@ def writeHatches(self): # Change origin to match Agg at top-left. 'Matrix': [1, 0, 0, 1, 0, self.height * 72]}) - stroke_rgb, fill_rgb, hatch = hatch_style + stroke_rgb, fill_rgb, hatch, lw = hatch_style self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2], Op.setrgb_stroke) if fill_rgb is not None: @@ -1578,7 +1582,7 @@ def writeHatches(self): 0, 0, sidelen, sidelen, Op.rectangle, Op.fill) - self.output(mpl.rcParams['hatch.linewidth'], Op.setlinewidth) + self.output(lw, Op.setlinewidth) self.output(*self.pathOperations( Path.hatch(hatch), @@ -2461,7 +2465,7 @@ def stroke(self): """ # _linewidth > 0: in pdf a line of width 0 is drawn at minimum # possible device width, but e.g., agg doesn't draw at all - return (self._linewidth > 0 and self._alpha > 0 and + return (self.get_linewidth() > 0 and self._alpha > 0 and (len(self._rgb) <= 3 or self._rgb[3] != 0.0)) def fill(self, *args): @@ -2509,14 +2513,15 @@ def alpha_cmd(self, alpha, forced, effective_alphas): name = self.file.alphaState(effective_alphas) return [name, Op.setgstate] - def hatch_cmd(self, hatch, hatch_color): + def hatch_cmd(self, hatch, hatch_color, hatch_linewidth): if not hatch: if self._fillcolor is not None: return self.fillcolor_cmd(self._fillcolor) else: return [Name('DeviceRGB'), Op.setcolorspace_nonstroke] else: - hatch_style = (hatch_color, self._fillcolor, hatch) + hatch_style = (hatch_color, self._fillcolor, hatch, + hatch_linewidth) name = self.file.hatchPattern(hatch_style) return [Name('Pattern'), Op.setcolorspace_nonstroke, name, Op.setcolor_nonstroke] @@ -2572,17 +2577,17 @@ def clip_cmd(self, cliprect, clippath): commands = ( # must come first since may pop - (('_cliprect', '_clippath'), clip_cmd), - (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd), - (('_capstyle',), capstyle_cmd), - (('_fillcolor',), fillcolor_cmd), - (('_joinstyle',), joinstyle_cmd), - (('_linewidth',), linewidth_cmd), - (('_dashes',), dash_cmd), - (('_rgb',), rgb_cmd), + (("_cliprect", "_clippath"), clip_cmd), + (("_alpha", "_forced_alpha", "_effective_alphas"), alpha_cmd), + (("_capstyle",), capstyle_cmd), + (("_fillcolor",), fillcolor_cmd), + (("_joinstyle",), joinstyle_cmd), + (("_linewidth",), linewidth_cmd), + (("_dashes",), dash_cmd), + (("_rgb",), rgb_cmd), # must come after fillcolor and rgb - (('_hatch', '_hatch_color'), hatch_cmd), - ) + (("_hatch", "_hatch_color", "_hatch_linewidth"), hatch_cmd), + ) def delta(self, other): """ @@ -2610,11 +2615,11 @@ def delta(self, other): break # Need to update hatching if we also updated fillcolor - if params == ('_hatch', '_hatch_color') and fill_performed: + if cmd.__name__ == 'hatch_cmd' and fill_performed: different = True if different: - if params == ('_fillcolor',): + if cmd.__name__ == 'fillcolor_cmd': fill_performed = True theirs = [getattr(other, p) for p in params] cmds.extend(cmd(self, *theirs)) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 893c660c0b24..47ad194a9dfb 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -510,7 +510,7 @@ def create_hatch(self, hatch): if hatch in self._hatches: return self._hatches[hatch] name = 'H%d' % len(self._hatches) - linewidth = mpl.rcParams['hatch.linewidth'] + # linewidth = mpl.rcParams['hatch.linewidth'] pageheight = self.height * 72 self._pswriter.write(f"""\ << /PatternType 1 @@ -935,6 +935,7 @@ def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True): if hatch: hatch_name = self.create_hatch(hatch) write("gsave\n") + write("%f setlinewidth" % gc.get_hatch_linewidth()) write(_nums_to_str(*gc.get_hatch_color()[:3])) write(f" {hatch_name} setpattern fill grestore\n") diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index dbf056613696..2f722cc8cb7f 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -500,11 +500,12 @@ def _get_hatch(self, gc, rgbFace): edge = gc.get_hatch_color() if edge is not None: edge = tuple(edge) - dictkey = (gc.get_hatch(), rgbFace, edge) + lw = gc._linewidth + dictkey = (gc.get_hatch(), rgbFace, edge, lw) oid = self._hatchd.get(dictkey) if oid is None: oid = self._make_id('h', dictkey) - self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid) + self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge, lw), oid) else: _, oid = oid return oid @@ -515,7 +516,7 @@ def _write_hatches(self): HATCH_SIZE = 72 writer = self.writer writer.start('defs') - for (path, face, stroke), oid in self._hatchd.values(): + for (path, face, stroke, lw), oid in self._hatchd.values(): writer.start( 'pattern', id=oid, @@ -539,7 +540,7 @@ def _write_hatches(self): hatch_style = { 'fill': rgb2hex(stroke), 'stroke': rgb2hex(stroke), - 'stroke-width': str(mpl.rcParams['hatch.linewidth']), + 'stroke-width': str(lw), 'stroke-linecap': 'butt', 'stroke-linejoin': 'miter' } From e754c824ca0f0ae077e43bf48b6922af23304f72 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 9 Apr 2024 12:33:36 +0530 Subject: [PATCH 03/16] Add linewidht setter and getter methods to Collections --- lib/matplotlib/collections.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index e668308abc82..09bf3c0839f8 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -174,6 +174,7 @@ def __init__(self, *, self._edge_is_mapped = None self._mapped_colors = None # calculated in update_scalarmappable self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color']) + self._hatch_linewidth = mpl.rcParams['hatch.linewidth'] self.set_facecolor(facecolors) self.set_edgecolor(edgecolors) self.set_linewidth(linewidths) @@ -364,6 +365,9 @@ def draw(self, renderer): if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) + print(self._hatch_linewidth) + print(self.get_hatch_linewidth()) + mhatch._set_hatch_linewidth(gc, self.get_hatch_linewidth()) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) @@ -542,6 +546,14 @@ def get_hatch(self): """Return the current hatching pattern.""" return self._hatch + def set_hatch_linewidth(self, lw): + """Set the hatch linewidth""" + self._hatch_linewidth = lw + + def get_hatch_linewidth(self): + """Return the hatch linewidth""" + return self._hatch_linewidth + def set_offsets(self, offsets): """ Set the offsets for the collection. From 9976d31aa374c5f221e8747edeec529bba7533b1 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 9 Apr 2024 12:40:52 +0530 Subject: [PATCH 04/16] Deprecation warning for setting linewidths in non-PDF,PS,SVG backends --- lib/matplotlib/hatch.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 0cbd042e1628..9438472167a5 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -223,3 +223,14 @@ def get_path(hatchpattern, density=6): cursor += pattern.num_vertices return Path(vertices, codes) + + +def _set_hatch_linewidth(gc, hatch_linewidth): + if hasattr(gc, "set_hatch_linewidth"): + gc.set_hatch_linewidth(hatch_linewidth) + else: + _api.warn_deprecated( + "3.8", message="The current backend does not define " + "GraphicsContextRenderer.set_hatch_linewidth; support for such " + "backends is deprecated since %(since)s and will be removed " + "%(removal)s.") From 30726ab2de6ef5dbe7a53506285f8071a3917a68 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 9 Apr 2024 12:44:46 +0530 Subject: [PATCH 05/16] Add setter and getter methods for hatch linewidth in Patch --- lib/matplotlib/patches.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 2db678587ec7..cfffb64c429a 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -72,6 +72,7 @@ def __init__(self, *, joinstyle = JoinStyle.miter self._hatch_color = colors.to_rgba(mpl.rcParams['hatch.color']) + self._hatch_linewidth = mpl.rcParams['hatch.linewidth'] self._fill = bool(fill) # needed for set_facecolor call if color is not None: if edgecolor is not None or facecolor is not None: @@ -571,6 +572,14 @@ def get_hatch(self): """Return the hatching pattern.""" return self._hatch + def set_hatch_linewidth(self, hatch_linewidth): + """Set the hatch linewidth""" + self._hatch_linewidth = hatch_linewidth + + def get_hatch_linewidth(self): + """Return the hatch linewidth""" + return self._hatch_linewidth + def _draw_paths_with_artist_properties( self, renderer, draw_path_args_list): """ @@ -605,6 +614,7 @@ def _draw_paths_with_artist_properties( if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) + mhatch._set_hatch_linewidth(gc, self.get_hatch_linewidth()) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) From 9c385ff71c5feca688433bd87583aeec812823fc Mon Sep 17 00:00:00 2001 From: Pranav Date: Wed, 10 Apr 2024 07:31:17 +0530 Subject: [PATCH 06/16] Add test for patches setter and getter --- lib/matplotlib/collections.pyi | 2 ++ lib/matplotlib/tests/test_patches.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/matplotlib/collections.pyi b/lib/matplotlib/collections.pyi index 06d8676867ee..7237b5846d10 100644 --- a/lib/matplotlib/collections.pyi +++ b/lib/matplotlib/collections.pyi @@ -48,6 +48,8 @@ class Collection(artist.Artist, cm.ScalarMappable): def get_urls(self) -> Sequence[str | None]: ... def set_hatch(self, hatch: str) -> None: ... def get_hatch(self) -> str: ... + def set_hatch_linewidth(self, lw: float) -> None: ... + def get_hatch_linewidth(self) -> float: ... def set_offsets(self, offsets: ArrayLike) -> None: ... def get_offsets(self) -> ArrayLike: ... def set_linewidth(self, lw: float | Sequence[float]) -> None: ... diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index 3544ce8cb10c..71ca81539844 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -960,3 +960,20 @@ def test_arrow_set_data(): ) arrow.set_data(x=.5, dx=3, dy=8, width=1.2) assert np.allclose(expected2, np.round(arrow.get_verts(), 2)) + + +@check_figures_equal(extensions=["png", "pdf", "svg", "eps"]) +def test_set_and_get_hatch_linewidth(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + lw = 2.0 + + with plt.rc_context({"hatch.linewidth": lw}): + ax_ref.add_patch(mpatches.Rectangle((0, 0), 1, 1, hatch="x")) + + ax_test.add_patch(mpatches.Rectangle((0, 0), 1, 1, hatch="x")) + ax_test.patches[0].set_hatch_linewidth(lw) + + assert (ax_ref.patches[0].get_hatch_linewidth() == lw) + assert (ax_test.patches[0].get_hatch_linewidth() == lw) From 6938fbe7af449dc511ce52bd9f748c164275d23a Mon Sep 17 00:00:00 2001 From: Pranav Date: Wed, 10 Apr 2024 07:47:51 +0530 Subject: [PATCH 07/16] Add test for collections setter and getter --- lib/matplotlib/tests/test_collections.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 19af38f3b522..41cec64f054a 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -1361,3 +1361,24 @@ def test_striped_lines(fig_test, fig_ref, gapcolor): for x, gcol, ls in zip(x, itertools.cycle(gapcolor), itertools.cycle(linestyles)): ax_ref.axvline(x, 0, 1, linewidth=20, linestyle=ls, gapcolor=gcol, alpha=0.5) + + +@check_figures_equal(extensions=['png', 'pdf', 'svg', 'eps']) +def test_hatch_linewidth(fig_test, fig_ref): + ax_test = fig_test.add_subplot() + ax_ref = fig_ref.add_subplot() + + lw = 2.0 + + ref = mcollections.CircleCollection(sizes=[1, 2, 3, 4, 5], hatch='x') + ref.set_linewidth(2) + + with mpl.rc_context({'hatch.linewidth': lw}): + test = mcollections.CircleCollection(sizes=[1, 2, 3, 4, 5], hatch='x') + test.set_linewidth(2) + + # Add the collection to the axes + ax_ref.add_collection(ref) + ax_test.add_collection(test) + + assert ((test.get_linewidth() == lw) and (ref.get_linewidth() == lw)) From 05300fe36eb4b4a1114cc2693276a35bc52b926a Mon Sep 17 00:00:00 2001 From: Pranav Date: Thu, 11 Apr 2024 17:06:31 +0530 Subject: [PATCH 08/16] Moved _set_hatch_linewidth to backend_bases --- lib/matplotlib/backend_bases.py | 10 ++++++++++ lib/matplotlib/backend_bases.pyi | 1 + lib/matplotlib/collections.py | 4 +--- lib/matplotlib/patches.py | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 80e57311d6de..a4e74b8bf9ed 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -965,6 +965,16 @@ def set_hatch_linewidth(self, hatch_linewidth): """Set the hatch linewidth.""" self._hatch_linewidth = hatch_linewidth + def _set_hatch_linewidth(self, hatch_linewidth): + if hasattr(self, "set_hatch_linewidth"): + self.set_hatch_linewidth(hatch_linewidth) + else: + _api.warn_deprecated( + "3.8", message="The current backend does not define " + "GraphicsContextRenderer.set_hatch_linewidth; support for such " + "backends is deprecated since %(since)s and will be removed " + "%(removal)s.") + def get_sketch_params(self): """ Return the sketch parameters for the artist. diff --git a/lib/matplotlib/backend_bases.pyi b/lib/matplotlib/backend_bases.pyi index 70be504666fc..12b4d06aa68c 100644 --- a/lib/matplotlib/backend_bases.pyi +++ b/lib/matplotlib/backend_bases.pyi @@ -167,6 +167,7 @@ class GraphicsContextBase: def get_hatch_color(self) -> ColorType: ... def set_hatch_color(self, hatch_color: ColorType) -> None: ... def get_hatch_linewidth(self) -> float: ... + def set_hatch_linewidth(self, hatch_linewidth: float) -> None: ... def get_sketch_params(self) -> tuple[float, float, float] | None: ... def set_sketch_params( self, diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 09bf3c0839f8..8f1133d11f2a 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -365,9 +365,7 @@ def draw(self, renderer): if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) - print(self._hatch_linewidth) - print(self.get_hatch_linewidth()) - mhatch._set_hatch_linewidth(gc, self.get_hatch_linewidth()) + gc._set_hatch_linewidth(self._hatch_linewidth) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index cfffb64c429a..d4a3f1a8926f 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -614,7 +614,7 @@ def _draw_paths_with_artist_properties( if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) - mhatch._set_hatch_linewidth(gc, self.get_hatch_linewidth()) + gc._set_hatch_linewidth(self._hatch_linewidth) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) From 21cd38d3716b4d0edbd2db4d2c874c5a673c3b6f Mon Sep 17 00:00:00 2001 From: Pranav Date: Mon, 13 May 2024 01:00:43 +0530 Subject: [PATCH 09/16] Added API change note --- doc/api/next_api_changes/deprecations/28048-PR.rst | 6 ++++++ lib/matplotlib/backends/backend_pdf.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 doc/api/next_api_changes/deprecations/28048-PR.rst diff --git a/doc/api/next_api_changes/deprecations/28048-PR.rst b/doc/api/next_api_changes/deprecations/28048-PR.rst new file mode 100644 index 000000000000..4c5e9554b1cc --- /dev/null +++ b/doc/api/next_api_changes/deprecations/28048-PR.rst @@ -0,0 +1,6 @@ +``PdfFile.hatchPatterns`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +... is deprecated and replaced by an internal helper called ``PdfFile._hatch_patterns`` instead. + +- The attribute ``PdfFile._hatch_patterns`` now stores hatch linewidths as well. diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 07707710494c..7ebe6c1a0279 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -1551,7 +1551,7 @@ def hatchPattern(self, hatch_style): self._hatch_patterns[hatch_style] = name return name - hatchPatterns = _api.deprecated("3.8")(property(lambda self: { + hatchPatterns = _api.deprecated("3.10")(property(lambda self: { k: (e, f, h) for k, (e, f, h, l) in self._hatch_patterns.items() })) From 1a41d77aa291f6eb50b86e515fbe2c5b48755236 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 22 Oct 2024 15:47:09 +0530 Subject: [PATCH 10/16] Made suggested changes --- doc/api/next_api_changes/deprecations/28048-PR.rst | 4 +--- lib/matplotlib/backends/backend_pdf.py | 2 +- lib/matplotlib/collections.py | 4 ++-- lib/matplotlib/patches.py | 8 ++++---- lib/matplotlib/patches.pyi | 2 ++ lib/matplotlib/tests/test_collections.py | 7 +++---- lib/matplotlib/tests/test_patches.py | 4 ++-- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/doc/api/next_api_changes/deprecations/28048-PR.rst b/doc/api/next_api_changes/deprecations/28048-PR.rst index 4c5e9554b1cc..4e90a3aced19 100644 --- a/doc/api/next_api_changes/deprecations/28048-PR.rst +++ b/doc/api/next_api_changes/deprecations/28048-PR.rst @@ -1,6 +1,4 @@ ``PdfFile.hatchPatterns`` ~~~~~~~~~~~~~~~~~~~~~~~~~ -... is deprecated and replaced by an internal helper called ``PdfFile._hatch_patterns`` instead. - -- The attribute ``PdfFile._hatch_patterns`` now stores hatch linewidths as well. +... is deprecated. diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 7ebe6c1a0279..05636836cc5c 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2465,7 +2465,7 @@ def stroke(self): """ # _linewidth > 0: in pdf a line of width 0 is drawn at minimum # possible device width, but e.g., agg doesn't draw at all - return (self.get_linewidth() > 0 and self._alpha > 0 and + return (self._linewidth > 0 and self._alpha > 0 and (len(self._rgb) <= 3 or self._rgb[3] != 0.0)) def fill(self, *args): diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 8f1133d11f2a..1f8caa641f4b 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -545,11 +545,11 @@ def get_hatch(self): return self._hatch def set_hatch_linewidth(self, lw): - """Set the hatch linewidth""" + """Set the hatch linewidth.""" self._hatch_linewidth = lw def get_hatch_linewidth(self): - """Return the hatch linewidth""" + """Return the hatch linewidth.""" return self._hatch_linewidth def set_offsets(self, offsets): diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index d4a3f1a8926f..40fa88073338 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -572,12 +572,12 @@ def get_hatch(self): """Return the hatching pattern.""" return self._hatch - def set_hatch_linewidth(self, hatch_linewidth): - """Set the hatch linewidth""" - self._hatch_linewidth = hatch_linewidth + def set_hatch_linewidth(self, lw): + """Set the hatch linewidth.""" + self._hatch_linewidth = lw def get_hatch_linewidth(self): - """Return the hatch linewidth""" + """Return the hatch linewidth.""" return self._hatch_linewidth def _draw_paths_with_artist_properties( diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index f6c9ddf75839..0645479ee5e7 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -59,6 +59,8 @@ class Patch(artist.Artist): def set_joinstyle(self, s: JoinStyleType) -> None: ... def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ... def set_hatch(self, hatch: str) -> None: ... + def set_hatch_linewidth(self, lw: float) -> None: ... + def get_hatch_linewidth(self) -> float: ... def get_hatch(self) -> str: ... def get_path(self) -> Path: ... diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 41cec64f054a..4a834161acfb 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -1373,12 +1373,11 @@ def test_hatch_linewidth(fig_test, fig_ref): ref = mcollections.CircleCollection(sizes=[1, 2, 3, 4, 5], hatch='x') ref.set_linewidth(2) - with mpl.rc_context({'hatch.linewidth': lw}): - test = mcollections.CircleCollection(sizes=[1, 2, 3, 4, 5], hatch='x') - test.set_linewidth(2) + with mpl.rc_context({"hatch.linewidth": lw}): + test = PolyCollection(polygons, hatch="x") # Add the collection to the axes ax_ref.add_collection(ref) ax_test.add_collection(test) - assert ((test.get_linewidth() == lw) and (ref.get_linewidth() == lw)) + assert test.get_hatch_linewidth() == ref.get_hatch_linewidth() == lw diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index 71ca81539844..edbafa074de5 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -975,5 +975,5 @@ def test_set_and_get_hatch_linewidth(fig_test, fig_ref): ax_test.add_patch(mpatches.Rectangle((0, 0), 1, 1, hatch="x")) ax_test.patches[0].set_hatch_linewidth(lw) - assert (ax_ref.patches[0].get_hatch_linewidth() == lw) - assert (ax_test.patches[0].get_hatch_linewidth() == lw) + assert ax_ref.patches[0].get_hatch_linewidth() == lw + assert ax_test.patches[0].get_hatch_linewidth() == lw From 36d132f00308504aa8f9185f498815d02b391ce5 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 22 Oct 2024 16:40:14 +0530 Subject: [PATCH 11/16] Resolved merge problems --- lib/matplotlib/backends/backend_pdf.py | 16 +++++++--------- lib/matplotlib/backends/backend_ps.py | 6 +++--- lib/matplotlib/collections.py | 2 +- lib/matplotlib/patches.py | 2 +- lib/matplotlib/tests/test_collections.py | 9 ++++++--- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 05636836cc5c..4c3c222ac72f 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -1535,13 +1535,12 @@ def _write_soft_mask_groups(self): def hatchPattern(self, hatch_style): # The colors may come in as numpy arrays, which aren't hashable - if hatch_style is not None: - edge, face, hatch, lw = hatch_style - if edge is not None: - edge = tuple(edge) - if face is not None: - face = tuple(face) - hatch_style = (edge, face, hatch, lw) + edge, face, hatch, lw = hatch_style + if edge is not None: + edge = tuple(edge) + if face is not None: + face = tuple(face) + hatch_style = (edge, face, hatch, lw) pattern = self._hatch_patterns.get(hatch_style, None) if pattern is not None: @@ -2520,8 +2519,7 @@ def hatch_cmd(self, hatch, hatch_color, hatch_linewidth): else: return [Name('DeviceRGB'), Op.setcolorspace_nonstroke] else: - hatch_style = (hatch_color, self._fillcolor, hatch, - hatch_linewidth) + hatch_style = (hatch_color, self._fillcolor, hatch, hatch_linewidth) name = self.file.hatchPattern(hatch_style) return [Name('Pattern'), Op.setcolorspace_nonstroke, name, Op.setcolor_nonstroke] diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 47ad194a9dfb..f490f88698b4 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -505,12 +505,12 @@ def set_font(self, fontname, fontsize, store=True): self.fontname = fontname self.fontsize = fontsize - def create_hatch(self, hatch): + def create_hatch(self, hatch, gc=None): sidelen = 72 if hatch in self._hatches: return self._hatches[hatch] name = 'H%d' % len(self._hatches) - # linewidth = mpl.rcParams['hatch.linewidth'] + linewidth = gc.get_hatch_linewidth() pageheight = self.height * 72 self._pswriter.write(f"""\ << /PatternType 1 @@ -933,7 +933,7 @@ def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True): write("grestore\n") if hatch: - hatch_name = self.create_hatch(hatch) + hatch_name = self.create_hatch(hatch, gc) write("gsave\n") write("%f setlinewidth" % gc.get_hatch_linewidth()) write(_nums_to_str(*gc.get_hatch_color()[:3])) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 1f8caa641f4b..94aa6b315141 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -365,7 +365,7 @@ def draw(self, renderer): if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) - gc._set_hatch_linewidth(self._hatch_linewidth) + gc.set_hatch_linewidth(self._hatch_linewidth) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 40fa88073338..e7e56c853849 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -614,7 +614,7 @@ def _draw_paths_with_artist_properties( if self._hatch: gc.set_hatch(self._hatch) gc.set_hatch_color(self._hatch_color) - gc._set_hatch_linewidth(self._hatch_linewidth) + gc.set_hatch_linewidth(self._hatch_linewidth) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 4a834161acfb..11934cfca2c3 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -1370,13 +1370,16 @@ def test_hatch_linewidth(fig_test, fig_ref): lw = 2.0 - ref = mcollections.CircleCollection(sizes=[1, 2, 3, 4, 5], hatch='x') - ref.set_linewidth(2) + polygons = [ + [(0.1, 0.1), (0.1, 0.4), (0.4, 0.4), (0.4, 0.1)], + [(0.6, 0.6), (0.6, 0.9), (0.9, 0.9), (0.9, 0.6)], + ] + ref = PolyCollection(polygons, hatch="x") + ref.set_hatch_linewidth(lw) with mpl.rc_context({"hatch.linewidth": lw}): test = PolyCollection(polygons, hatch="x") - # Add the collection to the axes ax_ref.add_collection(ref) ax_test.add_collection(test) From 7d94d86b382e30b313899de98d62cc83a305ffd4 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 22 Oct 2024 16:49:00 +0530 Subject: [PATCH 12/16] Rollback unwanted changes --- lib/matplotlib/backends/backend_pdf.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 4c3c222ac72f..86cbbe4d9a41 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2575,16 +2575,16 @@ def clip_cmd(self, cliprect, clippath): commands = ( # must come first since may pop - (("_cliprect", "_clippath"), clip_cmd), - (("_alpha", "_forced_alpha", "_effective_alphas"), alpha_cmd), - (("_capstyle",), capstyle_cmd), - (("_fillcolor",), fillcolor_cmd), - (("_joinstyle",), joinstyle_cmd), - (("_linewidth",), linewidth_cmd), - (("_dashes",), dash_cmd), - (("_rgb",), rgb_cmd), + (('_cliprect', '_clippath'), clip_cmd), + (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd), + (('_capstyle',), capstyle_cmd), + (('_fillcolor',), fillcolor_cmd), + (('_joinstyle',), joinstyle_cmd), + (('_linewidth',), linewidth_cmd), + (('_dashes',), dash_cmd), + (('_rgb',), rgb_cmd), # must come after fillcolor and rgb - (("_hatch", "_hatch_color", "_hatch_linewidth"), hatch_cmd), + (('_hatch', '_hatch_color', '_hatch_linewidth'), hatch_cmd), ) def delta(self, other): From 65b5c32293400e4ceb88b1be40fdb38ebb2439d6 Mon Sep 17 00:00:00 2001 From: Pranav Date: Tue, 22 Oct 2024 20:48:08 +0530 Subject: [PATCH 13/16] Minor Fixes --- lib/matplotlib/backend_bases.py | 10 ---------- lib/matplotlib/backends/backend_ps.py | 1 - lib/matplotlib/hatch.py | 11 ----------- 3 files changed, 22 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index a4e74b8bf9ed..80e57311d6de 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -965,16 +965,6 @@ def set_hatch_linewidth(self, hatch_linewidth): """Set the hatch linewidth.""" self._hatch_linewidth = hatch_linewidth - def _set_hatch_linewidth(self, hatch_linewidth): - if hasattr(self, "set_hatch_linewidth"): - self.set_hatch_linewidth(hatch_linewidth) - else: - _api.warn_deprecated( - "3.8", message="The current backend does not define " - "GraphicsContextRenderer.set_hatch_linewidth; support for such " - "backends is deprecated since %(since)s and will be removed " - "%(removal)s.") - def get_sketch_params(self): """ Return the sketch parameters for the artist. diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index f490f88698b4..bfe3ad59702e 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -935,7 +935,6 @@ def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True): if hatch: hatch_name = self.create_hatch(hatch, gc) write("gsave\n") - write("%f setlinewidth" % gc.get_hatch_linewidth()) write(_nums_to_str(*gc.get_hatch_color()[:3])) write(f" {hatch_name} setpattern fill grestore\n") diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 9438472167a5..0cbd042e1628 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -223,14 +223,3 @@ def get_path(hatchpattern, density=6): cursor += pattern.num_vertices return Path(vertices, codes) - - -def _set_hatch_linewidth(gc, hatch_linewidth): - if hasattr(gc, "set_hatch_linewidth"): - gc.set_hatch_linewidth(hatch_linewidth) - else: - _api.warn_deprecated( - "3.8", message="The current backend does not define " - "GraphicsContextRenderer.set_hatch_linewidth; support for such " - "backends is deprecated since %(since)s and will be removed " - "%(removal)s.") From 3cad9a1ab8cedd12d61ece7f47cbe604ce67ef5c Mon Sep 17 00:00:00 2001 From: Pranav Date: Wed, 23 Oct 2024 13:18:29 +0530 Subject: [PATCH 14/16] Fixed wrong linewidth get --- lib/matplotlib/backends/backend_svg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 2f722cc8cb7f..2193dc6b6cdc 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -500,7 +500,7 @@ def _get_hatch(self, gc, rgbFace): edge = gc.get_hatch_color() if edge is not None: edge = tuple(edge) - lw = gc._linewidth + lw = gc.get_hatch_linewidth() dictkey = (gc.get_hatch(), rgbFace, edge, lw) oid = self._hatchd.get(dictkey) if oid is None: From 4eb5b87038927c58eb6624085fce44ed65e92134 Mon Sep 17 00:00:00 2001 From: Pranav Date: Thu, 31 Oct 2024 07:59:43 +0530 Subject: [PATCH 15/16] Passed linewidth instead of gc while creating hatches --- lib/matplotlib/backends/backend_ps.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index bfe3ad59702e..a58be976117b 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -505,12 +505,12 @@ def set_font(self, fontname, fontsize, store=True): self.fontname = fontname self.fontsize = fontsize - def create_hatch(self, hatch, gc=None): + def create_hatch(self, hatch, lw): sidelen = 72 if hatch in self._hatches: return self._hatches[hatch] name = 'H%d' % len(self._hatches) - linewidth = gc.get_hatch_linewidth() + linewidth = lw pageheight = self.height * 72 self._pswriter.write(f"""\ << /PatternType 1 @@ -933,7 +933,7 @@ def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True): write("grestore\n") if hatch: - hatch_name = self.create_hatch(hatch, gc) + hatch_name = self.create_hatch(hatch, gc.get_hatch_linewidth()) write("gsave\n") write(_nums_to_str(*gc.get_hatch_color()[:3])) write(f" {hatch_name} setpattern fill grestore\n") From b67df775aa4ad0d32ad69749ec8374aad109a027 Mon Sep 17 00:00:00 2001 From: Pranav Date: Thu, 31 Oct 2024 08:46:00 +0530 Subject: [PATCH 16/16] Dropped recurring linewidth parameter --- lib/matplotlib/backends/backend_ps.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index a58be976117b..78473afa0f06 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -505,12 +505,11 @@ def set_font(self, fontname, fontsize, store=True): self.fontname = fontname self.fontsize = fontsize - def create_hatch(self, hatch, lw): + def create_hatch(self, hatch, linewidth): sidelen = 72 if hatch in self._hatches: return self._hatches[hatch] name = 'H%d' % len(self._hatches) - linewidth = lw pageheight = self.height * 72 self._pswriter.write(f"""\ << /PatternType 1 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy