Skip to content

Commit

Permalink
Merge branch 'main' into pre-commit-ci-update-config
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaMarconato committed Dec 26, 2024
2 parents f4a3f70 + 16d057e commit f922e17
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 69 deletions.
126 changes: 64 additions & 62 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,167 +12,169 @@ and this project adheres to [Semantic Versioning][].

### Fixed

- Transformations of Points and Shapes are now applied before rendering with datashader (#378)
- Fix bug due to `sc.get.obs_df()` returning a different type (#393)
- Transformations of Points and Shapes are now applied before rendering with datashader (#378)
- Fix bug due to `sc.get.obs_df()` returning a different type (#393)
- Allowing instance mismatch between shapes and tables (#396)
- Fix bug when plotting categorical points with datashader (#395)

## [0.2.8] - 2024-11-26

### Changed

- Support for `xarray.DataTree` (which moved from `datatree.DataTree`) (#380)
- Support for `xarray.DataTree` (which moved from `datatree.DataTree`) (#380)

## [0.2.7] - 2024-10-24

### Added

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

### Fixed

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

## [0.2.6] - 2024-09-04

### Changed

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

### Fixed

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

## [0.2.5] - 2024-08-23

### Changed

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

### Fixed

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

## [0.2.4] - 2024-08-07

### Added

- Added utils function for 0-transparent cmaps (#302)
- Added utils function for 0-transparent cmaps (#302)

### Fixed

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

## [0.2.3] - 2024-07-03

### Added

- Datashader support for points and shapes (#244)
- Datashader support for points and shapes (#244)

### Changed

- All parameters are now provided for a single element (#272)
- All parameters are now provided for a single element (#272)

### Fixed

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

## [0.2.2] - 2024-05-02

### Fixed

- Fixed `fill_alpha` ignoring `alpha` channel from custom cmap (#236)
- Fix channel str support (#221)
- Fixed `fill_alpha` ignoring `alpha` channel from custom cmap (#236)
- Fix channel str support (#221)

## [0.2.1] - 2024-03-26

### Minor

- Adjusted GitHub worklows
- Adjusted GitHub worklows

## [0.2.0] - 2024-03-24

### Added

- Support for plotting multiple tables @melonora
- Support for plotting multiple tables @melonora

### Fixed

- Several bugfixes, especially for colors and palettes @melonora
- Several bugfixes, especially for colors and palettes @melonora

## [0.1.0] - 2024-01-17

### Added

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

### Fixed

- Now dropping index when plotting shapes after spatial query (#177)
- Points are now being correctly rotated (#198)
- 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)
- Now dropping index when plotting shapes after spatial query (#177)
- Points are now being correctly rotated (#198)
- 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)

## [0.0.6] - 2023-11-06

### Added

- Pushed `get_extent` functionality upstream to `spatialdata` (#162)
- Pushed `get_extent` functionality upstream to `spatialdata` (#162)

## [0.0.5] - 2023-10-02

### Added

- Can now scale shapes (#152)
- Can now plot columns from GeoDataFrame (#149)
- Can now scale shapes (#152)
- Can now plot columns from GeoDataFrame (#149)

### Fixed

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

## [0.0.4] - 2023-08-11

### Fixed

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

## [0.0.2] - 2023-06-25

### Fixed

- Multiple bugfixes of which I didn't keep track of.
- Multiple bugfixes of which I didn't keep track of.

## [0.0.1] - 2023-04-04

### Added

- Initial release of `spatialdata-plot` with support for `images`, `labels`, `points` and `shapes`.
- Initial release of `spatialdata-plot` with support for `images`, `labels`, `points` and `shapes`.
22 changes: 16 additions & 6 deletions src/spatialdata_plot/pl/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from matplotlib.cm import ScalarMappable
from matplotlib.colors import ListedColormap, Normalize
from scanpy._settings import settings as sc_settings
from spatialdata import get_extent
from spatialdata import get_extent, join_spatialelement_table
from spatialdata.models import PointsModel, ShapesModel, get_table_keys
from spatialdata.transformations import get_transformation, set_transformation
from spatialdata.transformations.transformations import Identity
Expand Down Expand Up @@ -76,13 +76,18 @@ def _render_shapes(
filter_tables=bool(render_params.table_name),
)

shapes = sdata[element]

if (table_name := render_params.table_name) is None:
table = None
shapes = sdata_filt[element]
else:
_, region_key, _ = get_table_keys(sdata[table_name])
table = sdata[table_name][sdata[table_name].obs[region_key].isin([element])]
element_dict, joined_table = join_spatialelement_table(
sdata, spatial_element_names=element, table_name=table_name, how="inner"
)
sdata_filt[element] = shapes = element_dict[element]
joined_table.uns["spatialdata_attrs"]["region"] = (
joined_table.obs[joined_table.uns["spatialdata_attrs"]["region_key"]].unique().tolist()
)
sdata_filt[table_name] = table = joined_table

if (
col_for_color is not None
Expand Down Expand Up @@ -520,7 +525,12 @@ def _render_points(
# use datashader for the visualization of points
cvs = ds.Canvas(plot_width=plot_width, plot_height=plot_height, x_range=x_ext, y_range=y_ext)

color_by_categorical = col_for_color is not None and points[col_for_color].values.dtype == object
color_by_categorical = col_for_color is not None and transformed_element[col_for_color].values.dtype in (
object,
"categorical",
)
if color_by_categorical and transformed_element[col_for_color].values.dtype == object:
transformed_element[col_for_color] = transformed_element[col_for_color].astype("category")
aggregate_with_reduction = None
if col_for_color is not None and (render_params.groups is None or len(render_params.groups) > 1):
if color_by_categorical:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions tests/pl/test_render_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ def test_plot_datashader_continuous_color(self, sdata_blobs: SpatialData):
element="blobs_points", size=40, color="instance_id", alpha=0.6, method="datashader"
).pl.show()

def test_plot_points_categorical_color_column_matplotlib(self, sdata_blobs: SpatialData):
sdata_blobs.pl.render_points("blobs_points", color="genes", method="matplotlib").pl.show()

def test_plot_points_categorical_color_column_datashader(self, sdata_blobs: SpatialData):
sdata_blobs.pl.render_points("blobs_points", color="genes", method="datashader").pl.show()

def test_plot_points_continuous_color_column_matplotlib(self, sdata_blobs: SpatialData):
sdata_blobs.pl.render_points("blobs_points", color="instance_id", method="matplotlib").pl.show()

def test_plot_points_continuous_color_column_datashader(self, sdata_blobs: SpatialData):
sdata_blobs.pl.render_points("blobs_points", color="instance_id", method="datashader").pl.show()

def test_plot_datashader_matplotlib_stack(self, sdata_blobs: SpatialData):
sdata_blobs.pl.render_points(
element="blobs_points", size=40, color="red", method="datashader"
Expand Down
10 changes: 9 additions & 1 deletion tests/pl/test_render_shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ def test_plot_can_plot_shapes_after_spatial_query(self, sdata_blobs: SpatialData
cropped_blob.pl.render_shapes().pl.show()

def test_plot_can_plot_with_annotation_despite_random_shuffling(self, sdata_blobs: SpatialData):
new_table = sdata_blobs["table"].copy()
sdata_blobs["table"].obs["region"] = "blobs_circles"
new_table = sdata_blobs["table"][:5]
new_table.uns["spatialdata_attrs"]["region"] = "blobs_circles"
Expand Down Expand Up @@ -447,3 +446,12 @@ def test_plot_datashader_can_transform_circles(self, sdata_blobs: SpatialData):
_set_transformations(sdata_blobs["blobs_circles"], {"global": seq})

sdata_blobs.pl.render_shapes("blobs_circles", method="datashader", outline_alpha=1.0).pl.show()

def test_plot_can_do_non_matching_table(self, sdata_blobs: SpatialData):
table_shapes = sdata_blobs["table"][:3].copy()
table_shapes.obs.instance_id = list(range(3))
table_shapes.obs["region"] = "blobs_circles"
table_shapes.uns["spatialdata_attrs"]["region"] = "blobs_circles"
sdata_blobs["new_table"] = table_shapes

sdata_blobs.pl.render_shapes("blobs_circles", color="instance_id").pl.show()

0 comments on commit f922e17

Please sign in to comment.