spatialdata-plot icon indicating copy to clipboard operation
spatialdata-plot copied to clipboard

Bug when plotting data with affine transformations and datashader

Open hspitzer opened this issue 10 months ago • 0 comments

Hi Spatialdata team! I have recently discovered a bug when plotting data with affine transformations applied and using method='datashader. Below is an example based on the mouse_liver dataset. To reproduce, download the dataset and read the zarr file.

import spatialdata
from spatialdata.transformations import (
    Affine,
    get_transformation,
    set_transformation,
)
from spatialdata import transform
import spatialdata_plot

sdata = spatialdata.read_zarr("/Users/hannah.spitzer/Downloads/mouse_liver.zarr")
# apply affine transformation to both points and labels
affine = Affine([
    [1, 0., -2000],
    [ 0., 1, 500],
    [0., 0. ,1.]], input_axes=('x','y'), output_axes=('x', 'y'))

set_transformation(sdata["transcripts"], affine)
set_transformation(sdata["nucleus_boundaries"], affine)

# subsample points for faster plotting
sdata['transcripts_sub'] = sdata['transcripts'].sample(frac=0.01)

print(get_transformation(sdata["nucleus_boundaries"]))
print(get_transformation(sdata["transcripts_sub"]))

# plotting using method='matplotlib' in render_shapes is correct
sdata.pl.render_shapes('nucleus_boundaries', color='black', method='matplotlib').pl.render_points('transcripts_sub', color='blue').pl.show()

This code results in the following correct plot:

Image

When using method='datashader', the points and shapes are shifted relative to each other:

# plotting using method='datashader' in render_shapes results in shift between points and polygons
sdata.pl.render_shapes('nucleus_boundaries', color='black', method='datashader').pl.render_points('transcripts_sub', color='blue').pl.show()

Image

When applying the transformation to the shapes, plotting works:

# apply transformation to shapes
transformed_polygons = transform(sdata["nucleus_boundaries"], to_coordinate_system="global")
sdata['nucleus_boundaries_transformed'] = transformed_polygons

# plotting using method='datashader' in render_shapes works after applying transformation
sdata.pl.render_shapes('nucleus_boundaries_transformed', color='black', method='datashader').pl.render_points('transcripts_sub', color='blue').pl.show()

Image

So this is a workaround, but in practice, I do not always want to explicitely transform my shapes, but would rather that the plotting would work regardless of the coordinate transform the I have defined.

I am using python version 3.10.16 and the git main version for spatialdata-plot (0.2.9.dev61+g51a1c76), and spatialdata 0.2.6

hspitzer avatar Jan 15 '25 10:01 hspitzer