Skip to content

Commit 3112d15

Browse files
committed
added missing artifacts; one test still failing
2 parents db06a99 + e4a0170 commit 3112d15

9 files changed

Lines changed: 134 additions & 70 deletions

CHANGELOG.md

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -12,166 +12,167 @@ and this project adheres to [Semantic Versioning][].
1212

1313
### Fixed
1414

15-
- Transformations of Points and Shapes are now applied before rendering with datashader (#378)
15+
- Transformations of Points and Shapes are now applied before rendering with datashader (#378)
16+
- Fix bug due to `sc.get.obs_df()` returning a different type (#393)
1617

1718
## [0.2.8] - 2024-11-26
1819

1920
### Changed
2021

21-
- Support for `xarray.DataTree` (which moved from `datatree.DataTree`) (#380)
22+
- Support for `xarray.DataTree` (which moved from `datatree.DataTree`) (#380)
2223

2324
## [0.2.7] - 2024-10-24
2425

2526
### Added
2627

27-
- The user can now specify `datashader_reduction` to control the rendering behaviour (#309)
28-
- Rendering outlines of shapes with datashader works now (#309)
28+
- The user can now specify `datashader_reduction` to control the rendering behavior (#309)
29+
- Rendering outlines of shapes with datashader works now (#309)
2930

3031
### Fixed
3132

32-
- datashader now uses canvas size = image size which speeds up the rendering (#309)
33-
- datashader now uses the `linear` as interpolation method for colormaps instead of the default `eq_hist` to make it equivalent to matplotlib (#309)
34-
- point sizes of datashader now agree with matplotlib also when dpi != 100 (#309)
35-
- Giving a custom colormap when rendering a multiscale image now works (#586)
33+
- datashader now uses canvas size = image size which speeds up the rendering (#309)
34+
- datashader now uses the `linear` as interpolation method for colormaps instead of the default `eq_hist` to make it equivalent to matplotlib (#309)
35+
- point sizes of datashader now agree with matplotlib also when dpi != 100 (#309)
36+
- Giving a custom colormap when rendering a multiscale image now works (#586)
3637

3738
## [0.2.6] - 2024-09-04
3839

3940
### Changed
4041

41-
- Lowered RMSE-threshold for plot-based tests from 45 to 15 (#344)
42-
- When subsetting to `groups`, `NA` isn't automatically added to legend (#344)
43-
- When rendering a single image channel, a colorbar is now shown (#346)
44-
- Removed `percentiles_for_norm` parameter (#346)
45-
- Changed `norm` to no longer accept bools, only `mpl.colors.Normalise` or `None` (#346)
42+
- Lowered RMSE-threshold for plot-based tests from 45 to 15 (#344)
43+
- When subsetting to `groups`, `NA` isn't automatically added to legend (#344)
44+
- When rendering a single image channel, a colorbar is now shown (#346)
45+
- Removed `percentiles_for_norm` parameter (#346)
46+
- Changed `norm` to no longer accept bools, only `mpl.colors.Normalise` or `None` (#346)
4647

4748
### Fixed
4849

49-
- Filtering with `groups` now preserves original cmap (#344)
50-
- Non-selected `groups` are now not shown in `na_color` (#344)
51-
- Several issues associated with `norm` and `colorbar` (#346)
50+
- Filtering with `groups` now preserves original cmap (#344)
51+
- Non-selected `groups` are now not shown in `na_color` (#344)
52+
- Several issues associated with `norm` and `colorbar` (#346)
5253

5354
## [0.2.5] - 2024-08-23
5455

5556
### Changed
5657

57-
- Replaced `outline` parameter in `render_labels` with alpha-based logic (#323)
58-
- Lowered RMSE-threshold for plot-based tests from 60 to 45 (#323)
59-
- Removed `preprocessing` (.pp) accessor (#329)
58+
- Replaced `outline` parameter in `render_labels` with alpha-based logic (#323)
59+
- Lowered RMSE-threshold for plot-based tests from 60 to 45 (#323)
60+
- Removed `preprocessing` (.pp) accessor (#329)
6061

6162
### Fixed
6263

63-
- Minor fixes for several tests as a result of the threshold change (#323)
64+
- Minor fixes for several tests as a result of the threshold change (#323)
6465

6566
## [0.2.4] - 2024-08-07
6667

6768
### Added
6869

69-
- Added utils function for 0-transparent cmaps (#302)
70+
- Added utils function for 0-transparent cmaps (#302)
7071

7172
### Fixed
7273

73-
- Took RNG out of categorical label test (#306)
74-
- Performance bug when plotting shapes (#298)
75-
- scale parameter was ignored for single-scale images (#301)
76-
- Changes to support for dask-expr (#283)
77-
- Added error handling for non-existent elements (#305)
78-
- Specifying vmin and vmax properly clips image data (#307)
79-
- import bug `get_cmap()` (8fd969c)
74+
- Took RNG out of categorical label test (#306)
75+
- Performance bug when plotting shapes (#298)
76+
- scale parameter was ignored for single-scale images (#301)
77+
- Changes to support for dask-expr (#283)
78+
- Added error handling for non-existent elements (#305)
79+
- Specifying vmin and vmax properly clips image data (#307)
80+
- import bug `get_cmap()` (8fd969c)
8081

8182
## [0.2.3] - 2024-07-03
8283

8384
### Added
8485

85-
- Datashader support for points and shapes (#244)
86+
- Datashader support for points and shapes (#244)
8687

8788
### Changed
8889

89-
- All parameters are now provided for a single element (#272)
90+
- All parameters are now provided for a single element (#272)
9091

9192
### Fixed
9293

93-
- Fix color assignment for NaN values (#257)
94-
- Zorder of rendering now strictly follows the order of the render_x calls (#244)
94+
- Fix color assignment for NaN values (#257)
95+
- Zorder of rendering now strictly follows the order of the render_x calls (#244)
9596

9697
## [0.2.2] - 2024-05-02
9798

9899
### Fixed
99100

100-
- Fixed `fill_alpha` ignoring `alpha` channel from custom cmap (#236)
101-
- Fix channel str support (#221)
101+
- Fixed `fill_alpha` ignoring `alpha` channel from custom cmap (#236)
102+
- Fix channel str support (#221)
102103

103104
## [0.2.1] - 2024-03-26
104105

105106
### Minor
106107

107-
- Adjusted GitHub worklows
108+
- Adjusted GitHub worklows
108109

109110
## [0.2.0] - 2024-03-24
110111

111112
### Added
112113

113-
- Support for plotting multiple tables @melonora
114+
- Support for plotting multiple tables @melonora
114115

115116
### Fixed
116117

117-
- Several bugfixes, especially for colors and palettes @melonora
118+
- Several bugfixes, especially for colors and palettes @melonora
118119

119120
## [0.1.0] - 2024-01-17
120121

121122
### Added
122123

123-
- Multiscale image handling: user can specify a scale, else the best scale is selected automatically given the figure size and dpi (#164)
124-
- Large images are automatically rasterized to speed up performance (#164)
125-
- Added better error message for mismatch in cs and ax number (#185)
126-
- Beter test coverage for correct plotting of elements after transformation (#198)
127-
- Can now stack render commands (#190, #192)
128-
- The `color` argument in render_shapes/points now accepts actual colors as well (#199)
129-
- Input arguments are now evaulated for their types in basic.py (#199)
124+
- Multiscale image handling: user can specify a scale, else the best scale is selected automatically given the figure size and dpi (#164)
125+
- Large images are automatically rasterized to speed up performance (#164)
126+
- Added better error message for mismatch in cs and ax number (#185)
127+
- Beter test coverage for correct plotting of elements after transformation (#198)
128+
- Can now stack render commands (#190, #192)
129+
- The `color` argument in render_shapes/points now accepts actual colors as well (#199)
130+
- Input arguments are now evaulated for their types in basic.py (#199)
130131

131132
### Fixed
132133

133-
- Now dropping index when plotting shapes after spatial query (#177)
134-
- Points are now being correctly rotated (#198)
135-
- User can now pass Colormap objects to the cmap argument in render_images. When only one cmap is given for 3 channels, it is now applied to each channel (#188, #194)
134+
- Now dropping index when plotting shapes after spatial query (#177)
135+
- Points are now being correctly rotated (#198)
136+
- User can now pass Colormap objects to the cmap argument in render_images. When only one cmap is given for 3 channels, it is now applied to each channel (#188, #194)
136137

137138
## [0.0.6] - 2023-11-06
138139

139140
### Added
140141

141-
- Pushed `get_extent` functionality upstream to `spatialdata` (#162)
142+
- Pushed `get_extent` functionality upstream to `spatialdata` (#162)
142143

143144
## [0.0.5] - 2023-10-02
144145

145146
### Added
146147

147-
- Can now scale shapes (#152)
148-
- Can now plot columns from GeoDataFrame (#149)
148+
- Can now scale shapes (#152)
149+
- Can now plot columns from GeoDataFrame (#149)
149150

150151
### Fixed
151152

152-
- Multipolygons are now handled correctly (#93)
153-
- Legend order is now deterministic (#143)
154-
- Images no longer normalised by default (#150)
155-
- Filtering of shapes and points using the `groups` argument is now possible, coloring by palette and cmap arguments works for shapes and points (#153)
156-
- Colorbar no longer autoscales to [0, 1] (#155)
157-
- Plotting shapes after a spatial query is now possible (#163)
153+
- Multipolygons are now handled correctly (#93)
154+
- Legend order is now deterministic (#143)
155+
- Images no longer normalised by default (#150)
156+
- Filtering of shapes and points using the `groups` argument is now possible, coloring by palette and cmap arguments works for shapes and points (#153)
157+
- Colorbar no longer autoscales to [0, 1] (#155)
158+
- Plotting shapes after a spatial query is now possible (#163)
158159

159160
## [0.0.4] - 2023-08-11
160161

161162
### Fixed
162163

163-
- Multi-scale images/labels are now correctly substituted and the action is logged (#131).
164-
- Empty geometries among the shapes can be handeled (#133).
165-
- `outline_width` parameter in render_shapes is now a float that actually determines the line width (#139).
164+
- Multi-scale images/labels are now correctly substituted and the action is logged (#131).
165+
- Empty geometries among the shapes can be handeled (#133).
166+
- `outline_width` parameter in render_shapes is now a float that actually determines the line width (#139).
166167

167168
## [0.0.2] - 2023-06-25
168169

169170
### Fixed
170171

171-
- Multiple bugfixes of which I didn't keep track of.
172+
- Multiple bugfixes of which I didn't keep track of.
172173

173174
## [0.0.1] - 2023-04-04
174175

175176
### Added
176177

177-
- Initial release of `spatialdata-plot` with support for `images`, `labels`, `points` and `shapes`.
178+
- Initial release of `spatialdata-plot` with support for `images`, `labels`, `points` and `shapes`.

docs/contributing.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ out to the developers of the dependency before the package is released to a wide
7878

7979
[scanpy-test-docs]: https://scanpy.readthedocs.io/en/latest/dev/testing.html#writing-tests
8080

81+
### Testing the correctness of the plots
82+
83+
Many tests will produce plots and check that they are correct by comparing them with a previously saved and serialized version of the same plots. The ground truth images are located in `tests/_images`. Different OS/versions may produce similar but not identical plots (for instance the ticks/padding could vary). To take into account for this please consider the following:
84+
85+
- you should not use locally generated plots as ground truth images, but you should commit images that have been generated by a GitHub Action. The recommended workflow is to go to the ["actions" page for the repo](https://github.com/scverse/spatialdata-plot/actions/workflows/test.yaml), download the artifacts, and upload them as ground truth (after having reviewed them).
86+
- the ground truth images need to be updated when a new test is passing, or when a test starts producing a slightly different (but consistent) plot.
87+
- please never replace the ground truth images without having manually reviewed them.
88+
- if you run the tests locally in macOS or Windows they will likely fail because the ground truth images are generated using Ubuntu. To overcome this you can use `act`, which will generate a Docker reproducing the environment used in the GitHub Action. After the Docker container is generated you can use it within IDEs to run tests and debug code.
89+
- in the case of PyCharm, it is easier to create a container from a `Dockerfile` instead of using `act`. Please in such case use the `Dockerfile` made availabel in the repository. If you encountering problems with `act` or `docker`, please [get in touch with the developers via Zulip](https://scverse.zulipchat.com/#narrow/channel/443514-spatialdata-dev) and we will help troubleshoot the issue. See also additional details [here](https://github.com/scverse/spatialdata-plot/pull/397).
90+
8191
## Publishing a release
8292

8393
### Updating the version number

src/spatialdata_plot/pl/basic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ def show(
950950

951951
if wanted_labels_on_this_cs:
952952
if (table := params_copy.table_name) is not None:
953-
colors = sc.get.obs_df(sdata[table], params_copy.color)
953+
assert isinstance(params_copy.color, str)
954+
colors = sc.get.obs_df(sdata[table], [params_copy.color])
954955
if isinstance(colors[params_copy.color].dtype, pd.CategoricalDtype):
955956
_maybe_set_colors(
956957
source=sdata[table],

src/spatialdata_plot/pl/render.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ def _render_points(
453453
)
454454

455455
if col_for_color is not None:
456-
cols = sc.get.obs_df(adata, col_for_color)
456+
assert isinstance(col_for_color, str)
457+
cols = sc.get.obs_df(adata, [col_for_color])
457458
# maybe set color based on type
458459
if isinstance(cols[col_for_color].dtype, pd.CategoricalDtype):
459460
_maybe_set_colors(

test.Dockerfile

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Dockerfile for Testing Plot Correctness
2+
#
3+
# This Dockerfile is used to create a consistent testing environment for
4+
# verifying the correctness of plot outputs against ground truth images.
5+
# The ground truth images are stored in `tests/_images` and are generated
6+
# using a GitHub Action on Ubuntu. This ensures consistency across different
7+
# environments, as local differences in OS or library versions can cause
8+
# slight variations in plot rendering (e.g., ticks or padding).
9+
10+
# Define a build argument for the target platform.
11+
# Default is set to linux/amd64 for x86_64 machines.
12+
ARG TARGETPLATFORM=linux/amd64
13+
14+
# Use the specified platform to pull the correct base image.
15+
# Override TARGETPLATFORM during build for different architectures, such as linux/arm64 for Apple Silicon.
16+
# For example, to build for ARM64 architecture (e.g., Apple Silicon),
17+
# use the following command on the command line:
18+
#
19+
# docker build --build-arg TARGETPLATFORM=linux/arm64 -t my-arm-image .
20+
#
21+
# Similarly, to build for the default x86_64 architecture, you can use:
22+
#
23+
# docker build --build-arg TARGETPLATFORM=linux/amd64 -t my-amd64-image .
24+
#
25+
FROM --platform=$TARGETPLATFORM ubuntu:latest
26+
LABEL authors="Luca Marconato"
27+
28+
ENV PYTHONUNBUFFERED=1
29+
ENV MPLBACKEND=agg
30+
31+
WORKDIR /spatialdata-plot
32+
COPY . /spatialdata-plot
33+
34+
RUN apt-get update && \
35+
apt-get install -y --no-install-recommends \
36+
build-essential \
37+
python3-venv \
38+
python3-dev \
39+
git \
40+
&& rm -rf /var/lib/apt/lists/*
41+
42+
RUN python3 -m venv /opt/venv
43+
ENV PATH="/opt/venv/bin:$PATH"
44+
RUN pip install --upgrade pip wheel
45+
46+
RUN pip install -e ".[dev,test]"
47+
48+
CMD ["pytest", "-v", "tests/pl/test_render.py"]
19.4 KB
Loading
21.5 KB
Loading
20.1 KB
Loading

tests/pl/test_render_points.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import matplotlib.pyplot as plt
66
import numpy as np
77
import pandas as pd
8-
import pytest
98
import scanpy as sc
109
from anndata import AnnData
1110
from spatialdata import SpatialData, deepcopy
@@ -112,13 +111,17 @@ def test_plot_datashader_continuous_color(self, sdata_blobs: SpatialData):
112111
element="blobs_points", size=40, color="instance_id", alpha=0.6, method="datashader"
113112
).pl.show()
114113

115-
@pytest.mark.parametrize("method", ["matplotlib", "datashader"])
116-
def test_plot_points_categorical_color_column(self, sdata_blobs: SpatialData, method: str):
117-
sdata_blobs.pl.render_points("blobs_points", color="genes", method=method).pl.show()
114+
def test_plot_points_categorical_color_column_matplotlib(self, sdata_blobs: SpatialData):
115+
sdata_blobs.pl.render_points("blobs_points", color="genes", method="matplotlib").pl.show()
118116

119-
@pytest.mark.parametrize("method", ["matplotlib", "datashader"])
120-
def test_plot_points_continuous_color_column(self, sdata_blobs: SpatialData, method: str):
121-
sdata_blobs.pl.render_points("blobs_points", color="instance_id", method=method).pl.show()
117+
def test_plot_points_categorical_color_column_datashader(self, sdata_blobs: SpatialData):
118+
sdata_blobs.pl.render_points("blobs_points", color="genes", method="datashader").pl.show()
119+
120+
def test_plot_points_continuous_color_column_matplotlib(self, sdata_blobs: SpatialData):
121+
sdata_blobs.pl.render_points("blobs_points", color="instance_id", method="matplotlib").pl.show()
122+
123+
def test_plot_points_continuous_color_column_datashader(self, sdata_blobs: SpatialData):
124+
sdata_blobs.pl.render_points("blobs_points", color="instance_id", method="datashader").pl.show()
122125

123126
def test_plot_datashader_matplotlib_stack(self, sdata_blobs: SpatialData):
124127
sdata_blobs.pl.render_points(

0 commit comments

Comments
 (0)