diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b138c91..27fedfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,14 +12,15 @@ and this project adheres to [Semantic Versioning][]. ### Added -- Multipolygons are now handled correctly (#93) - 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) +- Colorbar no longer autoscales to [0, 1] (#155) ## [0.0.4] - 2023-08-11 diff --git a/src/spatialdata_plot/pl/basic.py b/src/spatialdata_plot/pl/basic.py index f09425b5..e228f2ac 100644 --- a/src/spatialdata_plot/pl/basic.py +++ b/src/spatialdata_plot/pl/basic.py @@ -152,7 +152,7 @@ def render_shapes( layer: str | None = None, palette: ListedColormap | str | None = None, cmap: Colormap | str | None = None, - norm: None | Normalize = None, + norm: bool | Normalize = False, na_color: str | tuple[float, ...] | None = "lightgrey", outline_alpha: float = 1.0, fill_alpha: float = 1.0, diff --git a/src/spatialdata_plot/pl/render.py b/src/spatialdata_plot/pl/render.py index 6e264532..c849be41 100644 --- a/src/spatialdata_plot/pl/render.py +++ b/src/spatialdata_plot/pl/render.py @@ -90,8 +90,10 @@ def _render_shapes( alpha=render_params.fill_alpha, ) + values_are_categorical = color_source_vector is not None + # color_source_vector is None when the values aren't categorical - if color_source_vector is None and render_params.transfunc is not None: + if values_are_categorical and render_params.transfunc is not None: color_vector = render_params.transfunc(color_vector) norm = copy(render_params.cmap_params.norm) @@ -113,6 +115,10 @@ def _render_shapes( # **kwargs, ) + # Sets the limits of the colorbar to the values instead of [0, 1] + if not norm and not values_are_categorical: + _cax.set_clim(min(color_vector), max(color_vector)) + cax = ax.add_collection(_cax) # Using dict.fromkeys here since set returns in arbitrary order @@ -120,8 +126,6 @@ def _render_shapes( ListedColormap(dict.fromkeys(color_vector)) if render_params.palette is None else render_params.palette ) - # print(len(set(color_vector)) == 1) - # print(set(color_source_vector[0]) == to_hex(render_params.cmap_params.na_color)) if not ( len(set(color_vector)) == 1 and list(set(color_vector))[0] == to_hex(render_params.cmap_params.na_color) ): @@ -190,7 +194,7 @@ def _render_points( key=render_params.color, palette=render_params.palette, ) - # print(p) + color_source_vector, color_vector, _ = _set_color_source_vec( sdata=sdata_filt, element=points, diff --git a/src/spatialdata_plot/pl/utils.py b/src/spatialdata_plot/pl/utils.py index d60e53a1..981701dd 100644 --- a/src/spatialdata_plot/pl/utils.py +++ b/src/spatialdata_plot/pl/utils.py @@ -564,7 +564,7 @@ def _get_scalebar( def _prepare_cmap_norm( cmap: Colormap | str | None = None, - norm: Normalize | Sequence[Normalize] | None = None, + norm: Normalize | bool = False, na_color: str | tuple[float, ...] = (0.0, 0.0, 0.0, 0.0), vmin: float | None = None, vmax: float | None = None, @@ -576,6 +576,8 @@ def _prepare_cmap_norm( if isinstance(norm, Normalize): pass # TODO + elif not norm: + pass elif vcenter is None: norm = Normalize(vmin=vmin, vmax=vmax) else: diff --git a/tests/_images/Shapes_can_color_from_geodataframe.png b/tests/_images/Shapes_can_color_from_geodataframe.png index c9718063..403d67c9 100644 Binary files a/tests/_images/Shapes_can_color_from_geodataframe.png and b/tests/_images/Shapes_can_color_from_geodataframe.png differ diff --git a/tests/_images/Shapes_colorbar_can_be_normalised.png b/tests/_images/Shapes_colorbar_can_be_normalised.png new file mode 100644 index 00000000..cd4ffd74 Binary files /dev/null and b/tests/_images/Shapes_colorbar_can_be_normalised.png differ diff --git a/tests/_images/Shapes_colorbar_respects_input_limits.png b/tests/_images/Shapes_colorbar_respects_input_limits.png new file mode 100644 index 00000000..d0c3cce0 Binary files /dev/null and b/tests/_images/Shapes_colorbar_respects_input_limits.png differ diff --git a/tests/pl/test_render_shapes.py b/tests/pl/test_render_shapes.py index 25379fb2..0a703b2f 100644 --- a/tests/pl/test_render_shapes.py +++ b/tests/pl/test_render_shapes.py @@ -100,3 +100,11 @@ def test_plot_can_color_from_geodataframe(self, sdata_blobs: SpatialData): def test_plot_can_scale_shapes(self, sdata_blobs: SpatialData): sdata_blobs.pl.render_shapes(elements="blobs_circles", scale=0.5).pl.show() + + def test_plot_colorbar_respects_input_limits(self, sdata_blobs: SpatialData): + sdata_blobs.shapes["blobs_polygons"]["cluster"] = [1, 2, 3, 5, 20] + sdata_blobs.pl.render_shapes("blobs_polygons", color="cluster", groups=["c1"]).pl.show() + + def test_plot_colorbar_can_be_normalised(self, sdata_blobs: SpatialData): + sdata_blobs.shapes["blobs_polygons"]["cluster"] = [1, 2, 3, 5, 20] + sdata_blobs.pl.render_shapes("blobs_polygons", color="cluster", groups=["c1"], norm=True).pl.show()