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

Skip to content

Commit 7dd858b

Browse files
committed
added angle attr
1 parent 20d46b2 commit 7dd858b

File tree

7 files changed

+87
-14
lines changed

7 files changed

+87
-14
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,9 @@ def set_snap(self, snap):
936936
"""
937937
self._snap = snap
938938

939+
def set_hatch_buffer_size(self, size):
940+
self._hatch_buffer_size = size
941+
939942
def set_hatch(self, hatch):
940943
"""Set the hatch style (for fills)."""
941944
self._hatch = hatch
@@ -947,7 +950,7 @@ def get_hatch(self):
947950
def get_hatch_path(self, density=6.0):
948951
"""Return a `.Path` for the current hatch."""
949952
if len(self.get_hatchstyles()):
950-
return Path.hatchstyles(self.get_hatchstyles())
953+
return Path.hatchstyles(self.get_hatchstyles(), self._hatch_buffer_size)
951954
hatch = self.get_hatch()
952955
if hatch is None:
953956
return None

lib/matplotlib/backends/backend_agg.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ def __init__(self, width, height, dpi):
6767
self.dpi = dpi
6868
self.width = width
6969
self.height = height
70-
self._renderer = _RendererAgg(int(width), int(height), dpi)
70+
hatchstyles = False
71+
if hatchstyles:
72+
hatch_buffer_size = max(width, height)
73+
else:
74+
hatch_buffer_size = dpi
75+
hatch_buffer_size = int(hatch_buffer_size)
76+
self.hatch_buffer_size = hatch_buffer_size
77+
self._renderer = _RendererAgg(int(width), int(height), dpi, hatch_buffer_size)
7178
self._filter_renderers = []
7279

7380
self._update_methods()
@@ -95,6 +102,7 @@ def draw_path(self, gc, path, transform, rgbFace=None):
95102
# docstring inherited
96103
nmax = mpl.rcParams['agg.path.chunksize'] # here at least for testing
97104
npts = path.vertices.shape[0]
105+
gc.set_hatch_buffer_size(self.hatch_buffer_size)
98106

99107
if (npts > nmax > 100 and path.should_simplify and
100108
rgbFace is None and gc.get_hatch() is None):

lib/matplotlib/hatch.py

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,29 @@ def __init__(self, hatchpattern, **kwargs):
242242
self.hatchpattern = hatchpattern
243243
self.kwargs = {attr: kwargs.get(attr, default) for attr, default in attrs}
244244

245-
def get_vertices_and_codes(self):
245+
def rotate_path(self, vertices, angle=None):
246+
if angle is None:
247+
angle = self.kwargs["angle"]
248+
angle_rad = np.deg2rad(angle)
249+
250+
center = np.mean(vertices, axis=0)
251+
vertices -= center
252+
253+
scaling = np.sin(angle_rad) + np.cos(angle_rad)
254+
vertices *= scaling
255+
256+
rotation_matrix = np.array(
257+
[
258+
[np.cos(angle_rad), -np.sin(angle_rad)],
259+
[np.sin(angle_rad), np.cos(angle_rad)],
260+
]
261+
)
262+
vertices = np.dot(vertices, rotation_matrix)
263+
vertices += center
264+
return vertices
265+
266+
def get_vertices_and_codes(self, hatch_buffer_size=100):
267+
self.hatch_buffer_size = hatch_buffer_size
246268
vertices, codes = np.empty((0, 2)), np.empty(0, Path.code_type)
247269

248270
for hatchpattern in self.hatchpattern:
@@ -252,6 +274,7 @@ def get_vertices_and_codes(self):
252274
vertices = np.concatenate((vertices, verts))
253275
codes = np.concatenate((codes, cods))
254276

277+
vertices = self.rotate_path(vertices)
255278
return vertices, codes
256279

257280

@@ -261,13 +284,47 @@ class MarkerHatchStyle(HatchStyle):
261284

262285
class LineHatchStyle(HatchStyle):
263286
def horizontal(self):
264-
return np.empty((0, 2)), np.empty(0, Path.code_type)
287+
num_lines = round(self.kwargs["scale"] * 2 * self.hatch_buffer_size / 100.0)
288+
if num_lines:
289+
num_vertices = num_lines * 2
290+
else:
291+
num_vertices = 0
292+
293+
vertices = np.empty((num_vertices, 2))
294+
codes = np.empty(num_vertices, Path.code_type)
295+
steps, stepsize = np.linspace(0.0, 1.0, num_lines, False, retstep=True)
296+
steps += stepsize / 2.0
297+
vertices[0::2, 0] = 0.0
298+
vertices[0::2, 1] = steps
299+
vertices[1::2, 0] = 1.0
300+
vertices[1::2, 1] = steps
301+
codes[0::2] = Path.MOVETO
302+
codes[1::2] = Path.LINETO
303+
304+
return vertices, codes
265305

266306
def vertical(self):
267-
return np.empty((0, 2)), np.empty(0, Path.code_type)
307+
num_lines = round(self.kwargs["scale"] * 2 * self.hatch_buffer_size / 100.0)
308+
if num_lines:
309+
num_vertices = num_lines * 2
310+
else:
311+
num_vertices = 0
312+
313+
vertices = np.empty((num_vertices, 2))
314+
codes = np.empty(num_vertices, Path.code_type)
315+
steps, stepsize = np.linspace(0.0, 1.0, num_lines, False, retstep=True)
316+
steps += stepsize / 2.0
317+
vertices[0::2, 0] = steps
318+
vertices[0::2, 1] = 0.0
319+
vertices[1::2, 0] = steps
320+
vertices[1::2, 1] = 1.0
321+
codes[0::2] = Path.MOVETO
322+
codes[1::2] = Path.LINETO
323+
324+
return vertices, codes
268325

269326
def north_east(self):
270-
num_lines = int(self.kwargs["scale"]) * 2
327+
num_lines = round(self.kwargs["scale"] * 2 * self.hatch_buffer_size / 100.0)
271328
if num_lines:
272329
num_vertices = (num_lines + 1) * 2
273330
else:
@@ -286,7 +343,7 @@ def north_east(self):
286343
return vertices, codes
287344

288345
def south_east(self):
289-
num_lines = int(self.kwargs["scale"]) * 2
346+
num_lines = round(self.kwargs["scale"] * 2 * self.hatch_buffer_size / 100.0)
290347
if num_lines:
291348
num_vertices = (num_lines + 1) * 2
292349
else:

lib/matplotlib/path.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,10 +1037,10 @@ def hatch(hatchpattern, density=6):
10371037
return (get_path(hatchpattern, density)
10381038
if hatchpattern is not None else None)
10391039

1040-
def hatchstyles(hatchstyles):
1040+
def hatchstyles(hatchstyles, hatchsize=100):
10411041
vertices, codes = np.empty((0, 2)), np.empty(0, Path.code_type)
10421042
for hatchstyle in hatchstyles:
1043-
verts, cods = hatchstyle.get_vertices_and_codes()
1043+
verts, cods = hatchstyle.get_vertices_and_codes(hatchsize)
10441044
vertices = np.concatenate([vertices, verts])
10451045
codes = np.concatenate([codes, cods])
10461046
return Path(vertices, codes)

src/_backend_agg.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <Python.h>
66
#include "_backend_agg.h"
77

8-
RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
8+
RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi, int hatch_buffer_size)
99
: width(width),
1010
height(height),
1111
dpi(dpi),
@@ -38,7 +38,7 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
3838
rendererBase.clear(_fill_color);
3939
rendererAA.attach(rendererBase);
4040
rendererBin.attach(rendererBase);
41-
hatch_size = int(dpi);
41+
hatch_size = hatch_buffer_size ? hatch_buffer_size : int(dpi);
4242
hatchBuffer = new agg::int8u[hatch_size * hatch_size * 4];
4343
hatchRenderingBuffer.attach(hatchBuffer, hatch_size, hatch_size, hatch_size * 4);
4444
}

src/_backend_agg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class RendererAgg
123123
/* TODO: Remove facepair_t */
124124
typedef std::pair<bool, agg::rgba> facepair_t;
125125

126-
RendererAgg(unsigned int width, unsigned int height, double dpi);
126+
RendererAgg(unsigned int width, unsigned int height, double dpi, int hatch_buffer_size = 0);
127127

128128
virtual ~RendererAgg();
129129

src/_backend_agg_wrapper.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,10 @@ static int PyRendererAgg_init(PyRendererAgg *self, PyObject *args, PyObject *kwd
139139
unsigned int width;
140140
unsigned int height;
141141
double dpi;
142+
int hatch_buffer_size;
142143
int debug = 0;
143144

144-
if (!PyArg_ParseTuple(args, "IId|i:RendererAgg", &width, &height, &dpi, &debug)) {
145+
if (!PyArg_ParseTuple(args, "IId|ii:RendererAgg", &width, &height, &dpi, &hatch_buffer_size, &debug)) {
145146
return -1;
146147
}
147148

@@ -159,7 +160,11 @@ static int PyRendererAgg_init(PyRendererAgg *self, PyObject *args, PyObject *kwd
159160
return -1;
160161
}
161162

162-
CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi))
163+
if (PySequence_Size(args) == 3) {
164+
CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi))
165+
} else {
166+
CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi, hatch_buffer_size))
167+
}
163168

164169
return 0;
165170
}

0 commit comments

Comments
 (0)