Skip to content

Commit 46a6d78

Browse files
committed
Prep for release
1 parent 21da8df commit 46a6d78

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

CHANGES.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
Changelog
22
=========
33

4+
0.2.1 (2018-11-19)
5+
++++++++++++++++++
6+
7+
- First release.
8+
9+
0.2.0 (2018-10)
10+
+++++++++++++++
11+
12+
- Parser re-write based largely on svg.path (https://github.com/regebro/svg.path/blob/master/src/svg/path/parser.py)
13+
- 2D coordinates are now encoded as complex numbers.
14+
415
0.1.0 (2016-04-10)
516
++++++++++++++++++
617

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This module adds the path commands missing from (1), including smooth curves and
2424
>>> parse_path('M 100 100 L 300 100')
2525
Path(array([[ 100., 100.], [ 300., 100.]]), array([1, 2], dtype=uint8))
2626

27-
There are likely still issues with implicit commands and subpaths to be sorted out.
27+
See the Jupyter Notebook `gallery <http://nbviewer.jupyter.org/github/nvictus/svgpath2mpl/tree/master/examples/>`_ of examples.
2828

2929
Resources
3030
---------
@@ -36,4 +36,4 @@ See the matplotlib path `tutorial <http://matplotlib.org/users/path_tutorial.htm
3636
License
3737
-------
3838

39-
BSD (New).
39+
BSD (3-Clause).

svgpath2mpl.py

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""
33
SVGPATH2MPL
44
~~~~~~~~~~~
5-
Parse SVG path data strings into matplotlib `Path` objects.
5+
Parse SVG path definition strings into matplotlib Path objects.
66
A path in SVG is defined by a 'path' element which contains a
77
``d="(path data)"`` attribute that contains moveto, line, curve (both
88
cubic and quadratic Béziers), arc and closepath instructions. See the SVG
@@ -11,12 +11,6 @@
1111
:copyright: (c) 2016, Nezar Abdennur.
1212
:license: BSD.
1313
14-
Notes
15-
~~~~~
16-
2018-10: Parser re-write based largely on svg.path
17-
(https://github.com/regebro/svg.path/blob/master/src/svg/path/parser.py)
18-
2D coordinates are now encoded as complex numbers.
19-
2014
"""
2115
from __future__ import division, print_function
2216
from math import sin, cos, sqrt, degrees, radians, acos
@@ -161,7 +155,7 @@ def endpoint_to_center(start, radius, rotation, large, sweep, end):
161155
if uy < 0:
162156
theta = -theta
163157

164-
# the angle between two vectors ((x1'-cx')/rx, (y1'-c1y/ry)) and
158+
# the angle between two vectors ((x1'-cx')/rx, (y1'-c1y/ry)) and
165159
# ((-x1'-cx')/rx, (-y1'-c1y/ry))
166160
p = ux * vx + uy * vy
167161
n = sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy))
@@ -190,7 +184,7 @@ def _tokenize_path(pathdef):
190184
for token in FLOAT_RE.findall(x):
191185
yield token
192186

193-
187+
194188
def _next_pos(elements):
195189
return float(elements.pop()) + float(elements.pop()) * 1j
196190

@@ -244,7 +238,7 @@ def _parse_path(pathdef, current_pos):
244238
start_pos = current_pos
245239

246240
yield COMMAND_CODES['M'], [(current_pos.real, current_pos.imag)]
247-
241+
248242
# Implicit moveto commands are treated as lineto commands.
249243
# So we set command to lineto here, in case there are
250244
# further implicit commands after this moveto.
@@ -264,7 +258,7 @@ def _parse_path(pathdef, current_pos):
264258
current_pos = start_pos
265259
start_pos = None
266260
command = None # You can't have implicit commands after closing.
267-
261+
268262
# LINETO
269263
elif command == 'L':
270264
pos = _next_pos(elements)
@@ -389,20 +383,20 @@ def _parse_path(pathdef, current_pos):
389383
end += current_pos
390384

391385
center, theta1, theta2 = endpoint_to_center(
392-
current_pos,
393-
radius,
394-
rotation,
395-
large,
396-
sweep,
386+
current_pos,
387+
radius,
388+
rotation,
389+
large,
390+
sweep,
397391
end
398392
)
399-
393+
400394
# Create an arc on the unit circle
401395
if theta2 > theta1:
402396
arc = Path.arc(theta1=theta1, theta2=theta2)
403397
else:
404398
arc = Path.arc(theta1=theta2, theta2=theta1)
405-
399+
406400
# Transform it into an elliptical arc:
407401
# * scale the minor and major axes
408402
# * translate it to the center
@@ -417,7 +411,7 @@ def _parse_path(pathdef, current_pos):
417411
arc = trans.transform_path(arc)
418412

419413
verts = np.array(arc.vertices)
420-
codes = np.array(arc.codes)
414+
codes = np.array(arc.codes)
421415
if sweep:
422416
# mysterious hack needed to render properly when sweeping the
423417
# arc angle in the "positive" angular direction
@@ -427,8 +421,32 @@ def _parse_path(pathdef, current_pos):
427421

428422
current_pos = end
429423

430-
424+
431425
def parse_path(pathdef, current_pos=0 + 0j):
426+
"""
427+
Parse an SVG path definition string into a matplotlib Path object.
428+
429+
Parameters
430+
----------
431+
pathdef : str
432+
SVG path 'd' attribute, e.g. 'M 100 100 L 300 100 L 200 300 z'.
433+
current_pos : complex, optional
434+
Coordinates of the starting position of the path, given as a complex
435+
number. When provided, an initial moveto operation will be intepreted
436+
as relative to this position even if given as M.
437+
438+
Returns
439+
-------
440+
:class:`matplotlib.path.Path` instance
441+
442+
See also
443+
--------
444+
matplotlib.path.Path
445+
matplotlib.patches.PathPatch
446+
matplotlib.collections.PathCollection
447+
matplotlib.transforms
448+
449+
"""
432450
codes = []
433451
verts = []
434452
for c, v in _parse_path(pathdef, current_pos):

0 commit comments

Comments
 (0)