Skip to content

Commit 9dc65ce

Browse files
authored
Implement frameon parameter and deprecate fig in show() (#573)
1 parent e54c74f commit 9dc65ce

5 files changed

Lines changed: 83 additions & 1 deletion

File tree

src/spatialdata_plot/pl/basic.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
import contextlib
44
import sys
5+
import warnings
56
from collections import OrderedDict
6-
from collections.abc import Callable
7+
from collections.abc import Callable, Sequence
78
from copy import deepcopy
89
from pathlib import Path
910
from typing import Any, Literal, cast
@@ -938,6 +939,15 @@ def show(
938939
show,
939940
)
940941

942+
if fig is not None and not isinstance(ax, Sequence):
943+
warnings.warn(
944+
"`fig` is being deprecated as an argument to `PlotAccessor.show` in spatialdata-plot. "
945+
"To use a custom figure, create axes from it and pass them via `ax` instead: "
946+
"`ax = fig.add_subplot(111)`.",
947+
DeprecationWarning,
948+
stacklevel=2,
949+
)
950+
941951
sdata = self._copy()
942952

943953
# Evaluate execution tree for plotting
@@ -1242,6 +1252,8 @@ def _draw_colorbar(
12421252
raise IndexError("The number of titles must match the number of coordinate systems.") from e
12431253
ax.set_title(t)
12441254
ax.set_aspect("equal")
1255+
if fig_params.frameon is False:
1256+
ax.axis("off")
12451257

12461258
extent = get_extent(
12471259
sdata,
84.3 KB
Loading
87 KB
Loading
93.4 KB
Loading

tests/pl/test_show.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import warnings
12
from unittest.mock import patch
23

34
import matplotlib
45
import matplotlib.pyplot as plt
6+
import pytest
57
import scanpy as sc
8+
from matplotlib.figure import Figure
69
from spatialdata import SpatialData
10+
from spatialdata.transformations import Identity, set_transformation
711

812
import spatialdata_plot # noqa: F401
913
from tests.conftest import DPI, PlotTester, PlotTesterMeta
@@ -25,6 +29,19 @@ class TestShow(PlotTester, metaclass=PlotTesterMeta):
2529
def test_plot_pad_extent_adds_padding(self, sdata_blobs: SpatialData):
2630
sdata_blobs.pl.render_images(element="blobs_image").pl.show(pad_extent=100)
2731

32+
def test_plot_frameon_false_single_panel(self, sdata_blobs: SpatialData):
33+
"""Visual test: frameon=False hides axes decorations on a single panel (regression for #204)."""
34+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=False)
35+
36+
def test_plot_frameon_false_multi_panel(self, sdata_blobs: SpatialData):
37+
"""Visual test: frameon=False hides axes decorations on all panels (regression for #204)."""
38+
set_transformation(sdata_blobs["blobs_image"], Identity(), "second_cs")
39+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=False, title="")
40+
41+
def test_plot_no_decorations(self, sdata_blobs: SpatialData):
42+
"""Visual test: frameon=False + title='' produces just the plot content (regression for #204)."""
43+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=False, title="", colorbar=False)
44+
2845
def test_no_plt_show_when_ax_provided(self, sdata_blobs: SpatialData):
2946
"""plt.show() must not be called when the user supplies ax= (regression for #362)."""
3047
_, ax = plt.subplots()
@@ -40,3 +57,56 @@ def test_plt_show_when_ax_provided_and_show_true(self, sdata_blobs: SpatialData)
4057
sdata_blobs.pl.render_images(element="blobs_image").pl.show(ax=ax, show=True)
4158
mock_show.assert_called_once()
4259
plt.close("all")
60+
61+
def test_frameon_false_hides_axes_decorations(self, sdata_blobs: SpatialData):
62+
"""frameon=False should turn off axes decorations (regression for #204)."""
63+
ax = sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=False, return_ax=True, show=False)
64+
assert not ax.axison
65+
plt.close("all")
66+
67+
def test_frameon_none_keeps_axes_decorations(self, sdata_blobs: SpatialData):
68+
"""Default frameon=None should keep axes decorations visible."""
69+
ax = sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=None, return_ax=True, show=False)
70+
assert ax.axison
71+
plt.close("all")
72+
73+
def test_title_empty_string_suppresses_title(self, sdata_blobs: SpatialData):
74+
"""title='' should suppress the default coordinate system title (regression for #204)."""
75+
ax = sdata_blobs.pl.render_images(element="blobs_image").pl.show(title="", return_ax=True, show=False)
76+
assert ax.get_title() == ""
77+
plt.close("all")
78+
79+
80+
def test_fig_parameter_emits_deprecation_warning(sdata_blobs: SpatialData):
81+
"""Passing fig= should emit a DeprecationWarning (regression for #204)."""
82+
fig = Figure()
83+
with pytest.warns(DeprecationWarning, match="`fig` is being deprecated"):
84+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(fig=fig, show=False)
85+
plt.close("all")
86+
87+
88+
def test_fig_parameter_default_no_warning(sdata_blobs: SpatialData):
89+
"""Not passing fig= should not emit a deprecation warning."""
90+
with warnings.catch_warnings():
91+
warnings.simplefilter("error", DeprecationWarning)
92+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(show=False)
93+
plt.close("all")
94+
95+
96+
def test_fig_parameter_no_warning_with_ax_list(sdata_blobs: SpatialData):
97+
"""Passing fig= with a list of axes should not warn (fig is still required there)."""
98+
set_transformation(sdata_blobs["blobs_image"], Identity(), "second_cs")
99+
fig, axs = plt.subplots(1, 2)
100+
with warnings.catch_warnings():
101+
warnings.simplefilter("error", DeprecationWarning)
102+
sdata_blobs.pl.render_images(element="blobs_image").pl.show(fig=fig, ax=list(axs), show=False)
103+
plt.close("all")
104+
105+
106+
def test_frameon_false_multi_panel(sdata_blobs: SpatialData):
107+
"""frameon=False should apply to all panels in a multi-panel plot (regression for #204)."""
108+
set_transformation(sdata_blobs["blobs_image"], Identity(), "second_cs")
109+
axs = sdata_blobs.pl.render_images(element="blobs_image").pl.show(frameon=False, return_ax=True, show=False)
110+
for ax in axs:
111+
assert not ax.axison
112+
plt.close("all")

0 commit comments

Comments
 (0)