Skip to content

Commit 6d49bcf

Browse files
committed
WIP: Add support for blend modes in SVG backend
1 parent 028041d commit 6d49bcf

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

‎lib/matplotlib/backends/backend_svg.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,32 @@ def _check_is_iterable_of_str(infos, key):
290290
f'iterable of str, not {type(infos)}.')
291291

292292

293+
def _svg_blend_mode(mpl_blend_mode):
294+
supported_blend_modes = {
295+
"over": "normal",
296+
"multiply": "multiply",
297+
"screen": "screen",
298+
"overlay": "overlay",
299+
"darken": "darken",
300+
"lighten": "lighten",
301+
"color dodge": "color-dodge",
302+
"color burn": "color-burn",
303+
"hard light": "hard-light",
304+
"soft light": "soft-light",
305+
"difference": "difference",
306+
"exclusion": "exclusion",
307+
"hue": "hue",
308+
"saturation": "saturation",
309+
"color": "color",
310+
"luminosity": "luminosity",
311+
}
312+
if mpl_blend_mode in supported_blend_modes:
313+
return supported_blend_modes[mpl_blend_mode]
314+
_log.warning(f"The '{mpl_blend_mode}' blend mode is not supported by the SVG "
315+
f"backend. Falling back to the 'over' blend mode.")
316+
return "normal"
317+
318+
293319
class RendererSVG(RendererBase):
294320
def __init__(self, width, height, svgwriter, basename=None, image_dpi=72,
295321
*, metadata=None):
@@ -581,6 +607,8 @@ def _get_style_dict(self, gc, rgbFace):
581607

582608
if forced_alpha and gc.get_alpha() != 1.0:
583609
attrib['opacity'] = _short_float_fmt(gc.get_alpha())
610+
if (blend_mode := _svg_blend_mode(gc.get_blend_mode())) != "normal":
611+
attrib["mix-blend-mode"] = blend_mode
584612

585613
offset, seq = gc.get_dashes()
586614
if seq is not None:
@@ -950,6 +978,8 @@ def draw_image(self, gc, x, y, im, transform=None):
950978
return
951979

952980
clip_attrs = self._get_clip_attrs(gc)
981+
if (blend_mode := _svg_blend_mode(gc.get_blend_mode())) != "normal":
982+
clip_attrs["style"] = f"mix-blend-mode: {blend_mode}"
953983
if clip_attrs:
954984
# Can't apply clip-path directly to the image because the image has
955985
# a transformation, which would also be applied to the clip-path.
@@ -1274,6 +1304,8 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
12741304
# docstring inherited
12751305

12761306
clip_attrs = self._get_clip_attrs(gc)
1307+
if (blend_mode := _svg_blend_mode(gc.get_blend_mode())) != "normal":
1308+
clip_attrs["style"] = f"mix-blend-mode: {blend_mode}"
12771309
if clip_attrs:
12781310
# Cannot apply clip-path directly to the text, because
12791311
# it has a transformation

0 commit comments

Comments
 (0)