From 7af1e49fee2e4461a36667497d2104a161fb6462 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 26 Feb 2026 13:39:05 +1000 Subject: [PATCH 1/3] Deduplicate spanning axes in SubplotGrid slicing --- ultraplot/gridspec.py | 13 ++++++++++++- ultraplot/tests/test_gridspec.py | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ultraplot/gridspec.py b/ultraplot/gridspec.py index 4dae9eee3..69f439ceb 100644 --- a/ultraplot/gridspec.py +++ b/ultraplot/gridspec.py @@ -1988,9 +1988,20 @@ def __getitem__(self, key): elif not isinstance(objs, list): objs = [objs] + # Spanning subplots can appear more than once in the sliced slot grid. + # De-duplicate while preserving order so method dispatch does not repeat. + seen = set() + unique = [] + for obj in objs: + obj_id = id(obj) + if obj_id in seen: + continue + seen.add(obj_id) + unique.append(obj) + objs = unique + if len(objs) == 1: return objs[0] - objs = [obj for obj in objs if obj is not None] return SubplotGrid(objs) def __setitem__(self, key, value): diff --git a/ultraplot/tests/test_gridspec.py b/ultraplot/tests/test_gridspec.py index b676f36a9..3c8e8250b 100644 --- a/ultraplot/tests/test_gridspec.py +++ b/ultraplot/tests/test_gridspec.py @@ -126,3 +126,22 @@ def test_gridspec_slicing(): # subset_mixed[4] -> Row 1, Col 0 -> Number 5 (since 4 cols per row) assert subset_mixed[0].number == 1 assert subset_mixed[4].number == 5 + + +def test_gridspec_spanning_slice_deduplicates_axes(): + import numpy as np + + fig, axs = uplt.subplots(np.array([[1, 1, 2], [3, 4, 5]])) + + # The first two slots in the top row refer to the same spanning subplot. + ax = axs[0, :2] + assert isinstance(ax, uplt.axes.Axes) + assert ax is axs[0, 0] + + data = np.array([[0.1, 0.2], [0.4, 0.5], [0.7, 0.8]]) + ax.scatter(data[:, 0], data[:, 1], c="grey", label="data", legend=True) + fig.canvas.draw() + + legend = ax.get_legend() + assert legend is not None + assert [t.get_text() for t in legend.texts] == ["data"] From 8b8e039ddebda01666d2b9047b80dbf272a35e09 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 26 Feb 2026 13:46:29 +1000 Subject: [PATCH 2/3] Simplify SubplotGrid slice deduplication --- ultraplot/gridspec.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ultraplot/gridspec.py b/ultraplot/gridspec.py index 69f439ceb..18d40d02f 100644 --- a/ultraplot/gridspec.py +++ b/ultraplot/gridspec.py @@ -1990,15 +1990,19 @@ def __getitem__(self, key): # Spanning subplots can appear more than once in the sliced slot grid. # De-duplicate while preserving order so method dispatch does not repeat. - seen = set() - unique = [] - for obj in objs: - obj_id = id(obj) - if obj_id in seen: - continue - seen.add(obj_id) - unique.append(obj) - objs = unique + try: + objs = list(dict.fromkeys(objs)) + except TypeError: + # Fallback for any unhashable custom axes-like objects. + seen = set() + unique = [] + for obj in objs: + obj_id = id(obj) + if obj_id in seen: + continue + seen.add(obj_id) + unique.append(obj) + objs = unique if len(objs) == 1: return objs[0] From cfc2884e417d456eab1b22ca2a93ab3508a1ad30 Mon Sep 17 00:00:00 2001 From: cvanelteren Date: Thu, 26 Feb 2026 13:47:26 +1000 Subject: [PATCH 3/3] Stylish fix --- ultraplot/gridspec.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/ultraplot/gridspec.py b/ultraplot/gridspec.py index 18d40d02f..5c4ac4066 100644 --- a/ultraplot/gridspec.py +++ b/ultraplot/gridspec.py @@ -1990,20 +1990,7 @@ def __getitem__(self, key): # Spanning subplots can appear more than once in the sliced slot grid. # De-duplicate while preserving order so method dispatch does not repeat. - try: - objs = list(dict.fromkeys(objs)) - except TypeError: - # Fallback for any unhashable custom axes-like objects. - seen = set() - unique = [] - for obj in objs: - obj_id = id(obj) - if obj_id in seen: - continue - seen.add(obj_id) - unique.append(obj) - objs = unique - + objs = list(dict.fromkeys(objs)) if len(objs) == 1: return objs[0] return SubplotGrid(objs)