Skip to content

Commit d8fc3eb

Browse files
committed
dashing line collections (hlines, vlines, ...)
line-style was previously ignored for line collections, this fixes it. Note that I did not add support for offset in line-style, which has not existed in the first place, and I have no need for it. There's a corresponding commit/PR in mpld3 coming. This was done together with gpt-5.1-codex (but I reviewed and edited a lot), here is what it has to say: Handle collection dasharrays in exporter - derive dash arrays from collection linestyles/dashes - carry dasharrays through export and render_path_collection so hlines/vlines/grid keep their patterns
1 parent 2f9d874 commit d8fc3eb

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

mplexporter/exporter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ def draw_collection(self, ax, collection,
259259
styles = {'linewidth': collection.get_linewidths(),
260260
'facecolor': collection.get_facecolors(),
261261
'edgecolor': collection.get_edgecolors(),
262+
'dasharray': utils.get_dasharray_list(collection),
262263
'alpha': collection._alpha,
263264
'zorder': collection.get_zorder()}
264265

mplexporter/renderers/base.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,12 @@ def _iter_path_collection(paths, path_transforms, offsets, styles):
204204
if np.size(facecolor) == 0:
205205
facecolor = ['none']
206206

207+
dasharray = styles.get('dasharray', None)
208+
if dasharray is None or np.size(dasharray) == 0:
209+
dasharray = ['none']
210+
207211
elements = [paths, path_transforms, offsets,
208-
edgecolor, styles['linewidth'], facecolor]
212+
edgecolor, styles['linewidth'], facecolor, dasharray]
209213

210214
it = itertools
211215
return it.islice(py3k.zip(*py3k.map(it.cycle, elements)), N)
@@ -258,7 +262,7 @@ def draw_path_collection(self, paths, path_coordinates, path_transforms,
258262

259263
for tup in self._iter_path_collection(paths, path_transforms,
260264
offsets, styles):
261-
(path, path_transform, offset, ec, lw, fc) = tup
265+
(path, path_transform, offset, ec, lw, fc, da) = tup
262266
vertices, pathcodes = path
263267
path_transform = transforms.Affine2D(path_transform)
264268
vertices = path_transform.transform(vertices)
@@ -268,7 +272,7 @@ def draw_path_collection(self, paths, path_coordinates, path_transforms,
268272
style = {"edgecolor": utils.export_color(ec),
269273
"facecolor": utils.export_color(fc),
270274
"edgewidth": lw,
271-
"dasharray": "10,0",
275+
"dasharray": da,
272276
"alpha": styles['alpha'],
273277
"zorder": styles['zorder']}
274278
self.draw_path(data=vertices, coordinates=path_coordinates,

mplexporter/utils.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ def _many_to_one(input_dict):
4545
('', ' ', 'None', 'none'): None})
4646

4747

48+
def _dasharray_from_linestyle(ls):
49+
if ls is None:
50+
return LINESTYLES['solid']
51+
if isinstance(ls, tuple) and len(ls) == 2: # NOTE: No support for offset yet.
52+
return ','.join(str(val) for val in ls)
53+
dasharray = LINESTYLES.get(ls, 'not found')
54+
if dasharray == 'not found':
55+
warnings.warn(f"line style '{ls}' not understood: defaulting to solid")
56+
dasharray = LINESTYLES['solid']
57+
return dasharray
58+
59+
4860
def get_dasharray(obj):
4961
"""Get an SVG dash array for the given matplotlib linestyle
5062
@@ -59,16 +71,27 @@ def get_dasharray(obj):
5971
dasharray : string
6072
The HTML/SVG dasharray code associated with the object.
6173
"""
62-
if obj.__dict__.get('_dashSeq', None) is not None:
63-
return ','.join(map(str, obj._dashSeq))
74+
if dashseq := getattr(obj, '_dashSeq', None):
75+
return _dasharray_from_linestyle(dashseq)
76+
77+
ls = obj.get_linestyle()
78+
if isinstance(ls, (list, tuple)) and not isinstance(ls, str):
79+
ls = ls[0] if len(ls) else None
80+
return _dasharray_from_linestyle(ls)
81+
82+
83+
def get_dasharray_list(collection):
84+
"""Return a list of SVG dash arrays for a matplotlib Collection"""
85+
linestyles = None
86+
if hasattr(collection, "get_dashes"):
87+
linestyles = collection.get_dashes()
88+
elif hasattr(collection, "get_linestyle"):
89+
linestyles = collection.get_linestyle()
6490
else:
65-
ls = obj.get_linestyle()
66-
dasharray = LINESTYLES.get(ls, 'not found')
67-
if dasharray == 'not found':
68-
warnings.warn("line style '{0}' not understood: "
69-
"defaulting to solid line.".format(ls))
70-
dasharray = LINESTYLES['solid']
71-
return dasharray
91+
return None
92+
if not isinstance(linestyles, (list, tuple)):
93+
linestyles = [linestyles]
94+
return [_dasharray_from_linestyle(ls) for ls in linestyles]
7295

7396

7497
PATH_DICT = {Path.LINETO: 'L',

0 commit comments

Comments
 (0)