diff --git a/doc/users/next_whats_new/svg_id_rc.rst b/doc/users/next_whats_new/svg_id_rc.rst new file mode 100644 index 000000000000..531d14860167 --- /dev/null +++ b/doc/users/next_whats_new/svg_id_rc.rst @@ -0,0 +1,32 @@ +``svg.id`` rcParam +~~~~~~~~~~~~~~~~~~ +:rc:`svg.id` lets you insert an ``id`` attribute into the top-level ```` tag. + +e.g. ``rcParams["svg.id"] = "svg1"`` results in +default), no ``id`` tag is included + +.. code-block:: XML + + + +This is useful if you would like to link the entire matplotlib SVG file within +another SVG file with the ```` tag. + +.. code-block:: XML + + + + +Where the ``#svg1`` indicator will now refer to the top level ```` tag, and +will hence result in the inclusion of the entire file. diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 51eee57a6a84..9d27861e9a9c 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -322,6 +322,7 @@ def __init__(self, width, height, svgwriter, basename=None, image_dpi=72, viewBox=f'0 0 {str_width} {str_height}', xmlns="http://www.w3.org/2000/svg", version="1.1", + id=mpl.rcParams['svg.id'], attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"}) self._write_metadata(metadata) self._write_default_style() diff --git a/lib/matplotlib/mpl-data/matplotlibrc b/lib/matplotlib/mpl-data/matplotlibrc index 29ffb20f4280..60ad9a51f276 100644 --- a/lib/matplotlib/mpl-data/matplotlibrc +++ b/lib/matplotlib/mpl-data/matplotlibrc @@ -735,6 +735,8 @@ # None: Assume fonts are installed on the # machine where the SVG will be viewed. #svg.hashsalt: None # If not None, use this string as hash salt instead of uuid4 +#svg.id: None # If not None, use this string as the value for the `id` + # attribute in the top tag ### pgf parameter ## See https://matplotlib.org/stable/tutorials/text/pgf.html for more information. diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index b0cd22098489..71dc0c6ceb82 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -1311,6 +1311,7 @@ def _convert_validator_spec(key, conv): "svg.image_inline": validate_bool, "svg.fonttype": ["none", "path"], # save text as text ("none") or "paths" "svg.hashsalt": validate_string_or_None, + "svg.id": validate_string_or_None, # set this when you want to generate hardcopy docstring "docstring.hardcopy": validate_bool, diff --git a/lib/matplotlib/tests/test_backend_svg.py b/lib/matplotlib/tests/test_backend_svg.py index b694bb297912..b13cabe67614 100644 --- a/lib/matplotlib/tests/test_backend_svg.py +++ b/lib/matplotlib/tests/test_backend_svg.py @@ -669,3 +669,34 @@ def test_annotationbbox_gid(): expected = '' assert expected in buf + + +def test_svgid(): + """Test that `svg.id` rcparam appears in output svg if not None.""" + + fig, ax = plt.subplots() + ax.plot([1, 2, 3], [3, 2, 1]) + fig.canvas.draw() + + # Default: svg.id = None + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + + tree = xml.etree.ElementTree.fromstring(buf) + + assert plt.rcParams['svg.id'] is None + assert not tree.findall('.[@id]') + + # String: svg.id = str + svg_id = 'a test for issue 28535' + plt.rc('svg', id=svg_id) + + with BytesIO() as fd: + fig.savefig(fd, format='svg') + buf = fd.getvalue().decode() + + tree = xml.etree.ElementTree.fromstring(buf) + + assert plt.rcParams['svg.id'] == svg_id + assert tree.findall(f'.[@id="{svg_id}"]')