From a46dfdd70cb09aa0b95de8e99ff7c36f052ca5fc Mon Sep 17 00:00:00 2001 From: Kherim Willems Date: Wed, 10 Jul 2024 16:20:48 +0200 Subject: [PATCH 1/3] (backend.svg) add `svg.id` rcParam If not None, the `svg.id` rcParam value will be used for setting the `id` attribute of the top `` tag. --- doc/users/next_whats_new/svg_id_rc.rst | 31 ++++++++++++++++++++++++ lib/matplotlib/backends/backend_svg.py | 1 + lib/matplotlib/mpl-data/matplotlibrc | 2 ++ lib/matplotlib/rcsetup.py | 1 + lib/matplotlib/tests/test_backend_svg.py | 31 ++++++++++++++++++++++++ 5 files changed, 66 insertions(+) create mode 100644 doc/users/next_whats_new/svg_id_rc.rst 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..98084fdcba30 --- /dev/null +++ b/doc/users/next_whats_new/svg_id_rc.rst @@ -0,0 +1,31 @@ +``svg.id`` rcParam +~~~~~~~~~~~~~~~~~~ +The value of this new rcParam controls whether the top-level ```` tag +contains an ``id`` attribute and what its value is. When set to ``None`` (the +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}"]') From 8f2f20801f872a8b0dcaca24a1d3cbd8e00dc973 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Fri, 12 Jul 2024 08:53:16 +0200 Subject: [PATCH 2/3] Update doc/users/next_whats_new/svg_id_rc.rst --- doc/users/next_whats_new/svg_id_rc.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/users/next_whats_new/svg_id_rc.rst b/doc/users/next_whats_new/svg_id_rc.rst index 98084fdcba30..b608127bd50a 100644 --- a/doc/users/next_whats_new/svg_id_rc.rst +++ b/doc/users/next_whats_new/svg_id_rc.rst @@ -1,7 +1,8 @@ ``svg.id`` rcParam ~~~~~~~~~~~~~~~~~~ -The value of this new rcParam controls whether the top-level ```` tag -contains an ``id`` attribute and what its value is. When set to ``None`` (the +:rc:`svg.id` lets you insert an ``id`` attibute into the top-level ```` tag. + +e.g. ``rcParams["svg.id"] = "svg1"`` results in default), no ``id`` tag is included .. code-block:: XML From 88879a5c84eac41b977f493b7f7f6dc769292d8c Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:09:53 +0200 Subject: [PATCH 3/3] Update doc/users/next_whats_new/svg_id_rc.rst --- doc/users/next_whats_new/svg_id_rc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/next_whats_new/svg_id_rc.rst b/doc/users/next_whats_new/svg_id_rc.rst index b608127bd50a..531d14860167 100644 --- a/doc/users/next_whats_new/svg_id_rc.rst +++ b/doc/users/next_whats_new/svg_id_rc.rst @@ -1,6 +1,6 @@ ``svg.id`` rcParam ~~~~~~~~~~~~~~~~~~ -:rc:`svg.id` lets you insert an ``id`` attibute into the top-level ```` tag. +: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