Skip to content

Commit c8aa6bf

Browse files
committed
FIX: Restore hatch color tracking edge color
1 parent 5a895da commit c8aa6bf

15 files changed

+662
-113
lines changed

doc/users/dflt_style_changes.rst

+13-9
Original file line numberDiff line numberDiff line change
@@ -617,20 +617,24 @@ To restore the previous behavior explicitly pass the keyword argument
617617
Hatching
618618
========
619619

620-
The color and width of the lines in a hatch pattern are now configurable by the
621-
rcParams `hatch.color` and `hatch.linewidth`, with defaults of black and 1
622-
point, respectively. The old behaviour for the color was to apply the edge
623-
color or use black, depending on the artist; the old behavior for the line
624-
width was different depending on backend:
620+
621+
The color of the lines in the hatch is now determined by
622+
623+
- If an edge color is explicitly, use that for the hatch color
624+
- If the edge color is not explicitly set, use ``rcParam['hatch.color']`` which
625+
is looked up at artist creation time.
626+
627+
The width of the lines in a hatch pattern is now configurable by the
628+
rcParams `hatch.linewidth`, which defaults to 1 point. The old
629+
behavior for the line width was different depending on backend:
625630

626631
- PDF: 0.1 pt
627632
- SVG: 1.0 pt
628633
- PS: 1 px
629634
- Agg: 1 px
630635

631-
The old color behavior can not be restored. The old line width behavior can not
632-
be restored across all backends simultaneously, but can be restored for a
633-
single backend by setting::
636+
The old line width behavior can not be restored across all backends
637+
simultaneously, but can be restored for a single backend by setting::
634638

635639
mpl.rcParams['hatch.linewidth'] = 0.1 # previous pdf hatch linewidth
636640
mpl.rcParams['hatch.linewidth'] = 1.0 # previous svg hatch linewidth
@@ -643,7 +647,7 @@ The behavior of the PS and Agg backends was DPI dependent, thus::
643647
mpl.rcParams['hatch.linewidth'] = 1.0 / dpi # previous ps and Agg hatch linewidth
644648

645649

646-
There is no API level control of the hatch color or linewidth.
650+
There is no direct API level control of the hatch color or linewidth.
647651

648652
Hatching patterns are now rendered at a consistent density, regardless of DPI.
649653
Formerly, high DPI figures would be more dense than the default, and low DPI

lib/matplotlib/backend_bases.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,8 @@ def copy_properties(self, gc):
817817
self._linewidth = gc._linewidth
818818
self._rgb = gc._rgb
819819
self._hatch = gc._hatch
820+
self._hatch_color = gc._hatch_color
821+
self._hatch_linewidth = gc._hatch_linewidth
820822
self._url = gc._url
821823
self._gid = gc._gid
822824
self._snap = gc._snap
@@ -1107,10 +1109,16 @@ def get_hatch_path(self, density=6.0):
11071109

11081110
def get_hatch_color(self):
11091111
"""
1110-
Gets the color to use for hatching.
1112+
Sets the color to use for hatching.
11111113
"""
11121114
return self._hatch_color
11131115

1116+
def set_hatch_color(self, hatch_color):
1117+
"""
1118+
Gets the color to use for hatching.
1119+
"""
1120+
self._hatch_color = hatch_color
1121+
11141122
def get_hatch_linewidth(self):
11151123
"""
11161124
Gets the linewidth to use for hatching.

lib/matplotlib/backends/backend_pdf.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -2210,14 +2210,14 @@ def alpha_cmd(self, alpha, forced, effective_alphas):
22102210
name = self.file.alphaState(effective_alphas)
22112211
return [name, Op.setgstate]
22122212

2213-
def hatch_cmd(self, hatch):
2213+
def hatch_cmd(self, hatch, hatch_color):
22142214
if not hatch:
22152215
if self._fillcolor is not None:
22162216
return self.fillcolor_cmd(self._fillcolor)
22172217
else:
22182218
return [Name('DeviceRGB'), Op.setcolorspace_nonstroke]
22192219
else:
2220-
hatch_style = (self._hatch_color, self._fillcolor, hatch)
2220+
hatch_style = (hatch_color, self._fillcolor, hatch)
22212221
name = self.file.hatchPattern(hatch_style)
22222222
return [Name('Pattern'), Op.setcolorspace_nonstroke,
22232223
name, Op.setcolor_nonstroke]
@@ -2281,7 +2281,8 @@ def clip_cmd(self, cliprect, clippath):
22812281
(('_linewidth',), linewidth_cmd),
22822282
(('_dashes',), dash_cmd),
22832283
(('_rgb',), rgb_cmd),
2284-
(('_hatch',), hatch_cmd), # must come after fillcolor and rgb
2284+
# must come after fillcolor and rgb
2285+
(('_hatch', '_hatch_color'), hatch_cmd),
22852286
)
22862287

22872288
# TODO: _linestyle
@@ -2312,7 +2313,7 @@ def delta(self, other):
23122313
break
23132314

23142315
# Need to update hatching if we also updated fillcolor
2315-
if params == ('_hatch',) and fill_performed:
2316+
if params == ('_hatch', '_hatch_color') and fill_performed:
23162317
different = True
23172318

23182319
if different:

lib/matplotlib/collections.py

+12
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def __init__(self,
136136
self._linewidths = [0]
137137
self._is_filled = True # May be modified by set_facecolor().
138138

139+
self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color'])
139140
self.set_facecolor(facecolors)
140141
self.set_edgecolor(edgecolors)
141142
self.set_linewidth(linewidths)
@@ -293,6 +294,12 @@ def draw(self, renderer):
293294

294295
if self._hatch:
295296
gc.set_hatch(self._hatch)
297+
try:
298+
gc.set_hatch_color(self._hatch_color)
299+
except AttributeError:
300+
# if we end up with a GC that does not have this method
301+
warnings.warn("Your backend does not support setting the "
302+
"hatch color.")
296303

297304
if self.get_sketch_params() is not None:
298305
gc.set_sketch_params(*self.get_sketch_params())
@@ -690,12 +697,15 @@ def get_edgecolor(self):
690697
get_edgecolors = get_edgecolor
691698

692699
def _set_edgecolor(self, c):
700+
set_hatch_color = True
693701
if c is None:
694702
if (mpl.rcParams['patch.force_edgecolor'] or
695703
not self._is_filled or self._edge_default):
696704
c = mpl.rcParams['patch.edgecolor']
697705
else:
698706
c = 'none'
707+
set_hatch_color = False
708+
699709
self._is_stroked = True
700710
try:
701711
if c.lower() == 'none':
@@ -710,6 +720,8 @@ def _set_edgecolor(self, c):
710720
except AttributeError:
711721
pass
712722
self._edgecolors = mcolors.to_rgba_array(c, self._alpha)
723+
if set_hatch_color and len(self._edgecolors):
724+
self._hatch_color = tuple(self._edgecolors[0])
713725
self.stale = True
714726

715727
def set_edgecolor(self, c):

lib/matplotlib/patches.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import six
77
from six.moves import map, zip
8+
import warnings
89

910
import math
1011

@@ -113,10 +114,10 @@ def __init__(self,
113114
if antialiased is None:
114115
antialiased = mpl.rcParams['patch.antialiased']
115116

117+
self._hatch_color = colors.to_rgba(mpl.rcParams['hatch.color'])
116118
self._fill = True # needed for set_facecolor call
117119
if color is not None:
118120
if (edgecolor is not None or facecolor is not None):
119-
import warnings
120121
warnings.warn("Setting the 'color' property will override"
121122
"the edgecolor or facecolor properties. ")
122123
self.set_color(color)
@@ -288,13 +289,18 @@ def set_aa(self, aa):
288289
return self.set_antialiased(aa)
289290

290291
def _set_edgecolor(self, color):
292+
set_hatch_color = True
291293
if color is None:
292294
if (mpl.rcParams['patch.force_edgecolor'] or
293295
not self._fill or self._edge_default):
294296
color = mpl.rcParams['patch.edgecolor']
295297
else:
296298
color = 'none'
299+
set_hatch_color = False
300+
297301
self._edgecolor = colors.to_rgba(color, self._alpha)
302+
if set_hatch_color:
303+
self._hatch_color = self._edgecolor
298304
self.stale = True
299305

300306
def set_edgecolor(self, color):
@@ -545,6 +551,12 @@ def draw(self, renderer):
545551

546552
if self._hatch:
547553
gc.set_hatch(self._hatch)
554+
try:
555+
gc.set_hatch_color(self._hatch_color)
556+
except AttributeError:
557+
# if we end up with a GC that does not have this method
558+
warnings.warn("Your backend does not have support for "
559+
"setting the hatch color.")
548560

549561
if self.get_sketch_params() is not None:
550562
gc.set_sketch_params(*self.get_sketch_params())
@@ -4286,6 +4298,13 @@ def draw(self, renderer):
42864298

42874299
if self._hatch:
42884300
gc.set_hatch(self._hatch)
4301+
if self._hatch_color is not None:
4302+
try:
4303+
gc.set_hatch_color(self._hatch_color)
4304+
except AttributeError:
4305+
# if we end up with a GC that does not have this method
4306+
warnings.warn("Your backend does not support setting the "
4307+
"hatch color.")
42894308

42904309
if self.get_sketch_params() is not None:
42914310
gc.set_sketch_params(*self.get_sketch_params())
Binary file not shown.

0 commit comments

Comments
 (0)