Skip to content

Commit ed4b87e

Browse files
authored
Merge branch 'main' into feature/202306_support_multipolygons
2 parents bf44326 + 3a70a99 commit ed4b87e

18 files changed

+365
-280
lines changed

.github/codecov.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Based on spatialdata
1+
# Based on pydata/xarray
22
codecov:
33
require_ci_to_pass: false
44

@@ -15,3 +15,6 @@ comment:
1515
layout: "diff, flags, files"
1616
behavior: once
1717
require_base: false
18+
19+
fixes:
20+
- "/spatialdata-plot/spatialdata-plot/::spatialdata-plot/src/spatialdat_plot/"

.github/workflows/build.yaml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,15 @@ on:
66
pull_request:
77
branches: [main]
88

9-
concurrency:
10-
group: ${{ github.workflow }}-${{ github.ref }}
11-
cancel-in-progress: true
12-
139
jobs:
1410
package:
1511
runs-on: ubuntu-latest
1612
steps:
17-
- uses: actions/checkout@v3
13+
- uses: actions/checkout@v2
1814
- name: Set up Python 3.10
19-
uses: actions/setup-python@v4
15+
uses: actions/setup-python@v2
2016
with:
2117
python-version: "3.10"
22-
cache: "pip"
23-
cache-dependency-path: "**/pyproject.toml"
2418
- name: Install build dependencies
2519
run: python -m pip install --upgrade pip wheel twine build
2620
- name: Build package

.github/workflows/test_and_deploy.yaml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ on:
88
pull_request:
99
branches: [main]
1010

11-
concurrency:
12-
group: ${{ github.workflow }}-${{ github.ref }}
13-
cancel-in-progress: true
14-
1511
jobs:
1612
test:
1713
runs-on: ${{ matrix.os }}
@@ -30,9 +26,9 @@ jobs:
3026
PYTHON: ${{ matrix.python }}
3127

3228
steps:
33-
- uses: actions/checkout@v2
29+
- uses: actions/checkout@v3
3430
- name: Set up Python ${{ matrix.python }}
35-
uses: actions/setup-python@v2
31+
uses: actions/setup-python@v3
3632
with:
3733
python-version: ${{ matrix.python }}
3834

@@ -41,7 +37,7 @@ jobs:
4137
run: |
4238
echo "::set-output name=dir::$(pip cache dir)"
4339
- name: Restore pip cache
44-
uses: actions/cache@v2
40+
uses: actions/cache@v3
4541
with:
4642
path: ${{ steps.pip-cache-dir.outputs.dir }}
4743
key: pip-${{ runner.os }}-${{ env.pythonLocation }}-${{ hashFiles('**/pyproject.toml') }}

pyproject.toml

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
1-
[build-system]
2-
build-backend = "hatchling.build"
3-
requires = ["hatchling", "hatch-vcs"]
4-
5-
61
[project]
72
name = "spatialdata-plot"
8-
description = "Static plotting for SpatialData."
3+
description = "Static plotting for spatial data."
94
authors = [
105
{name = "scverse"},
116
]
127
maintainers = [
138
{name = "scverse", email = "[email protected]"},
149
]
15-
urls.Documentation = "https://spatialdata.scverse.org/projects/plot/en/latest/"
10+
urls.Documentation = "https://spatialdata.readthedocs.io/"
1611
urls.Source = "https://github.com/scverse/spatialdata-plot.git"
1712
urls.Home-page = "https://github.com/scverse/spatialdata-plot.git"
13+
requires-python = ">=3.9"
1814
dynamic= [
1915
"version" # allow version to be set by git tags
2016
]
21-
requires-python = ">=3.9"
2217
license = {file = "LICENSE"}
2318
readme = "README.md"
2419
dependencies = [
@@ -51,14 +46,9 @@ test = [
5146
"pytest",
5247
"pytest-cov",
5348
]
54-
torch = [
55-
"torch"
56-
]
57-
extra = [
58-
]
5949

6050
[tool.coverage.run]
61-
source = ["spatialdata-plot"]
51+
source = ["spatialdata_plot"]
6252
omit = [
6353
"**/test_*.py",
6454
]
@@ -100,9 +90,6 @@ exclude = '''
10090
[tool.jupytext]
10191
formats = "ipynb,md"
10292

103-
[tool.hatch.metadata]
104-
allow-direct-references = true
105-
10693
[tool.hatch.build.targets.wheel]
10794
packages = ['src/spatialdata_plot']
10895

@@ -112,6 +99,9 @@ source = "vcs"
11299
[tool.hatch.build.hooks.vcs]
113100
version-file = "_version.py"
114101

102+
[tool.hatch.metadata]
103+
allow-direct-references = true
104+
115105
[tool.ruff]
116106
exclude = [
117107
".git",
@@ -173,4 +163,4 @@ target-version = "py39"
173163
convention = "numpy"
174164
[tool.ruff.pyupgrade]
175165
# Preserve types, even if a file imports `from __future__ import annotations`.
176-
keep-runtime-typing = true
166+
keep-runtime-typing = true

src/spatialdata_plot/pl/basic.py

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def _copy(
139139

140140
def render_shapes(
141141
self,
142-
element: str | None = None,
142+
elements: str | list[str] | None = None,
143143
color: str | None = None,
144144
groups: str | Sequence[str] | None = None,
145145
size: float = 1.0,
@@ -161,8 +161,8 @@ def render_shapes(
161161
162162
Parameters
163163
----------
164-
element
165-
The name of the shapes element to render. If `None`, the first
164+
elements
165+
The name of the shapes element(s) to render. If `None`, all
166166
shapes element in the `SpatialData` object will be used.
167167
color
168168
Key for annotations in :attr:`anndata.AnnData.obs` or variables/genes.
@@ -209,7 +209,7 @@ def render_shapes(
209209
)
210210
outline_params = _set_outline(size, outline, outline_width, outline_color)
211211
sdata.plotting_tree[f"{n_steps+1}_render_shapes"] = ShapesRenderParams(
212-
element=element,
212+
elements=elements,
213213
color=color,
214214
groups=groups,
215215
outline_params=outline_params,
@@ -219,13 +219,14 @@ def render_shapes(
219219
palette=palette,
220220
outline_alpha=outline_alpha,
221221
fill_alpha=fill_alpha,
222+
transfunc=kwargs.get("transfunc", None),
222223
)
223224

224225
return sdata
225226

226227
def render_points(
227228
self,
228-
element: str | None = None,
229+
elements: str | list[str] | None = None,
229230
color: str | None = None,
230231
groups: str | Sequence[str] | None = None,
231232
size: float = 1.0,
@@ -241,8 +242,8 @@ def render_points(
241242
242243
Parameters
243244
----------
244-
element
245-
The name of the points element to render. If `None`, the first
245+
elements
246+
The name of the points element(s) to render. If `None`, all
246247
shapes element in the `SpatialData` object will be used.
247248
color
248249
Key for annotations in :attr:`anndata.AnnData.obs` or variables/genes.
@@ -278,19 +279,21 @@ def render_points(
278279
**kwargs,
279280
)
280281
sdata.plotting_tree[f"{n_steps+1}_render_points"] = PointsRenderParams(
281-
element=element,
282+
elements=elements,
282283
color=color,
283284
groups=groups,
284285
cmap_params=cmap_params,
285286
palette=palette,
286287
alpha=alpha,
288+
transfunc=kwargs.get("transfunc", None),
289+
size=size,
287290
)
288291

289292
return sdata
290293

291294
def render_images(
292295
self,
293-
element: str | None = None,
296+
elements: str | list[str] | None = None,
294297
channel: list[str] | list[int] | int | str | None = None,
295298
cmap: Colormap | str | None = None,
296299
norm: Optional[Normalize] = None,
@@ -304,9 +307,9 @@ def render_images(
304307
305308
Parameters
306309
----------
307-
element
308-
The name of the image element to render. If `None`, the first
309-
shapes element in the `SpatialData` object will be used.
310+
elements
311+
The name of the image element(s) to render. If `None`, all
312+
shapes elements in the `SpatialData` object will be used.
310313
channel
311314
To select which channel to plot (all by default).
312315
cmap
@@ -335,7 +338,7 @@ def render_images(
335338
**kwargs,
336339
)
337340
sdata.plotting_tree[f"{n_steps+1}_render_images"] = ImageRenderParams(
338-
element=element,
341+
elements=elements,
339342
channel=channel,
340343
cmap_params=cmap_params,
341344
palette=palette,
@@ -346,7 +349,7 @@ def render_images(
346349

347350
def render_labels(
348351
self,
349-
element: str | None = None,
352+
elements: str | list[str] | None = None,
350353
color: str | None = None,
351354
groups: str | Sequence[str] | None = None,
352355
contour_px: int = 3,
@@ -366,9 +369,9 @@ def render_labels(
366369
367370
Parameters
368371
----------
369-
element
370-
The name of the labels element to render. If `None`, the first
371-
labels element in the `SpatialData` object will be used.
372+
elements
373+
The name of the labels element(s) to render. If `None`, all
374+
labels elements in the `SpatialData` object will be used.
372375
color
373376
Key for annotations in :attr:`anndata.AnnData.obs` or variables/genes.
374377
groups
@@ -417,7 +420,7 @@ def render_labels(
417420
**kwargs,
418421
)
419422
sdata.plotting_tree[f"{n_steps+1}_render_labels"] = LabelsRenderParams(
420-
element=element,
423+
elements=elements,
421424
color=color,
422425
groups=groups,
423426
contour_px=contour_px,
@@ -428,6 +431,7 @@ def render_labels(
428431
palette=palette,
429432
outline_alpha=outline_alpha,
430433
fill_alpha=fill_alpha,
434+
transfunc=kwargs.get("transfunc", None),
431435
)
432436

433437
return sdata
@@ -519,6 +523,15 @@ def show(
519523
# Simplicstic solution: If the images are multiscale, just use the first
520524
sdata = _multiscale_to_image(sdata)
521525

526+
# handle coordinate system
527+
coordinate_systems = sdata.coordinate_systems if coordinate_systems is None else coordinate_systems
528+
if isinstance(coordinate_systems, str):
529+
coordinate_systems = [coordinate_systems]
530+
531+
for cs in coordinate_systems:
532+
if cs not in sdata.coordinate_systems:
533+
raise ValueError(f"Unknown coordinate system '{cs}', valid choices are: {sdata.coordinate_systems}")
534+
522535
extent = _get_extent(
523536
sdata=sdata,
524537
has_images="render_images" in render_cmds,
@@ -528,11 +541,6 @@ def show(
528541
coordinate_systems=coordinate_systems,
529542
)
530543

531-
# handle coordinate system
532-
coordinate_systems = sdata.coordinate_systems if coordinate_systems is None else coordinate_systems
533-
if isinstance(coordinate_systems, str):
534-
coordinate_systems = [coordinate_systems]
535-
536544
# Use extent to filter out coordinate system without the relevant elements
537545
valid_cs = []
538546
for cs in coordinate_systems:
@@ -542,13 +550,18 @@ def show(
542550
logg.info(f"Dropping coordinate system '{cs}' since it doesn't have relevant elements.")
543551
coordinate_systems = valid_cs
544552

553+
# print(coordinate_systems)
554+
# cs_mapping = _get_coordinate_system_mapping(sdata)
555+
# print(cs_mapping)
556+
545557
# check that coordinate system and elements to be rendered match
546-
for cmd, params in render_cmds.items():
547-
if params.element is not None and len([params.element]) != len(coordinate_systems):
548-
raise ValueError(
549-
f"Number of coordinate systems ({len(coordinate_systems)}) does not match number of elements "
550-
f"({len(params.element)}) in command {cmd}."
551-
)
558+
# for cmd, params in render_cmds.items():
559+
# if params.elements is not None and len([params.elements]) != len(coordinate_systems):
560+
# print(params.elements)
561+
# raise ValueError(
562+
# f"Number of coordinate systems ({len(coordinate_systems)}) does not match number of elements "
563+
# f"({len(params.elements)}) in command {cmd}."
564+
# )
552565

553566
# set up canvas
554567
fig_params, scalebar_params = _prepare_params_plot(
@@ -679,8 +692,15 @@ def show(
679692
cs_contents.query(f"cs == '{cs}'")["has_shapes"][0],
680693
]
681694
):
682-
ax.set_xlim(extent[cs][0], extent[cs][1])
683-
ax.set_ylim(extent[cs][3], extent[cs][2]) # (0, 0) is top-left
695+
# If the axis already has limits, only expand them but not overwrite
696+
x_min, x_max = ax.get_xlim()
697+
y_min, y_max = ax.get_ylim()
698+
x_min = min(x_min, extent[cs][0])
699+
x_max = max(x_max, extent[cs][1])
700+
y_min = min(y_min, extent[cs][2])
701+
y_max = max(y_max, extent[cs][3])
702+
ax.set_xlim(x_min, x_max)
703+
ax.set_ylim(y_max, y_min) # (0, 0) is top-left
684704

685705
if fig_params.fig is not None and save is not None:
686706
save_fig(fig_params.fig, path=save)

0 commit comments

Comments
 (0)