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

Performance issue when plotting spatialdata object with many samples

Open grst opened this issue 10 months ago • 2 comments

I have a spatialdata object with 49 Visium samples. It looks like this:

sdata
SpatialData object, with associated Zarr store: /cfs/<redacted>/02_nfcore_spatialvi/output/aggregation/data/merged_sdata.zarr
├── Images
│     ├── 'study1_sample1_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample1_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample2_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample2_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample3_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample3_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample4_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample4_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample5_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample5_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample6_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample6_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample7_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample7_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample8_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample8_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample9_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample9_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample10_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample10_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample11_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample11_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample12_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample12_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample13_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample13_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample14_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample14_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample15_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample15_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study1_sample16_hires_image': DataArray[cyx] (3, 2000, 2000)
│     ├── 'study1_sample16_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study2_sampleBI33_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study2_sampleBI33_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study2_sampleBI39_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study2_sampleBI39_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study2_sampleBI64_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study2_sampleBI64_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study2_sampleBI66_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study2_sampleBI66_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB1_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB1_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB2_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB2_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB3_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB3_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB4_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB4_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB5_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB5_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB6_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB6_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB7_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB7_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB8_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB8_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB9_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB9_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB10_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB10_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB11_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB11_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB12_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB12_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB13_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB13_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB14_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB14_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB15_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB15_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study3_sampleB16_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study3_sampleB16_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB1_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB1_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB2_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB2_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB5_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB5_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB6_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB6_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB7_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB7_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB9_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB9_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB10_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB10_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB11_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB11_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB12_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB12_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB13_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB13_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB14_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB14_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB15_hires_image': DataArray[cyx] (3, 3000, 3000)
│     ├── 'study4_sampleB15_lowres_image': DataArray[cyx] (3, 600, 600)
│     ├── 'study4_sampleB16_hires_image': DataArray[cyx] (3, 3000, 3000)
│     └── 'study4_sampleB16_lowres_image': DataArray[cyx] (3, 600, 600)
├── Shapes
│     ├── 'study1_sample1': GeoDataFrame shape: (245, 2) (2D shapes)
│     ├── 'study1_sample2': GeoDataFrame shape: (522, 2) (2D shapes)
│     ├── 'study1_sample3': GeoDataFrame shape: (320, 2) (2D shapes)
│     ├── 'study1_sample4': GeoDataFrame shape: (472, 2) (2D shapes)
│     ├── 'study1_sample5': GeoDataFrame shape: (823, 2) (2D shapes)
│     ├── 'study1_sample6': GeoDataFrame shape: (206, 2) (2D shapes)
│     ├── 'study1_sample7': GeoDataFrame shape: (192, 2) (2D shapes)
│     ├── 'study1_sample8': GeoDataFrame shape: (397, 2) (2D shapes)
│     ├── 'study1_sample9': GeoDataFrame shape: (122, 2) (2D shapes)
│     ├── 'study1_sample10': GeoDataFrame shape: (722, 2) (2D shapes)
│     ├── 'study1_sample11': GeoDataFrame shape: (271, 2) (2D shapes)
│     ├── 'study1_sample12': GeoDataFrame shape: (332, 2) (2D shapes)
│     ├── 'study1_sample13': GeoDataFrame shape: (472, 2) (2D shapes)
│     ├── 'study1_sample14': GeoDataFrame shape: (1272, 2) (2D shapes)
│     ├── 'study1_sample15': GeoDataFrame shape: (222, 2) (2D shapes)
│     ├── 'study1_sample16': GeoDataFrame shape: (274, 2) (2D shapes)
│     ├── 'study2_sampleBI33': GeoDataFrame shape: (6485, 2) (2D shapes)
│     ├── 'study2_sampleBI39': GeoDataFrame shape: (10255, 2) (2D shapes)
│     ├── 'study2_sampleBI64': GeoDataFrame shape: (9504, 2) (2D shapes)
│     ├── 'study2_sampleBI66': GeoDataFrame shape: (5764, 2) (2D shapes)
│     ├── 'study3_sampleB1': GeoDataFrame shape: (3202, 2) (2D shapes)
│     ├── 'study3_sampleB2': GeoDataFrame shape: (6127, 2) (2D shapes)
│     ├── 'study3_sampleB3': GeoDataFrame shape: (2859, 2) (2D shapes)
│     ├── 'study3_sampleB4': GeoDataFrame shape: (7092, 2) (2D shapes)
│     ├── 'study3_sampleB5': GeoDataFrame shape: (8514, 2) (2D shapes)
│     ├── 'study3_sampleB6': GeoDataFrame shape: (6704, 2) (2D shapes)
│     ├── 'study3_sampleB7': GeoDataFrame shape: (8184, 2) (2D shapes)
│     ├── 'study3_sampleB8': GeoDataFrame shape: (7764, 2) (2D shapes)
│     ├── 'study3_sampleB9': GeoDataFrame shape: (5941, 2) (2D shapes)
│     ├── 'study3_sampleB10': GeoDataFrame shape: (6814, 2) (2D shapes)
│     ├── 'study3_sampleB11': GeoDataFrame shape: (4438, 2) (2D shapes)
│     ├── 'study3_sampleB12': GeoDataFrame shape: (4798, 2) (2D shapes)
│     ├── 'study3_sampleB13': GeoDataFrame shape: (8419, 2) (2D shapes)
│     ├── 'study3_sampleB14': GeoDataFrame shape: (7236, 2) (2D shapes)
│     ├── 'study3_sampleB15': GeoDataFrame shape: (9298, 2) (2D shapes)
│     ├── 'study3_sampleB16': GeoDataFrame shape: (4689, 2) (2D shapes)
│     ├── 'study4_sampleB1': GeoDataFrame shape: (5475, 2) (2D shapes)
│     ├── 'study4_sampleB2': GeoDataFrame shape: (5765, 2) (2D shapes)
│     ├── 'study4_sampleB5': GeoDataFrame shape: (3165, 2) (2D shapes)
│     ├── 'study4_sampleB6': GeoDataFrame shape: (2332, 2) (2D shapes)
│     ├── 'study4_sampleB7': GeoDataFrame shape: (3461, 2) (2D shapes)
│     ├── 'study4_sampleB9': GeoDataFrame shape: (5700, 2) (2D shapes)
│     ├── 'study4_sampleB10': GeoDataFrame shape: (6566, 2) (2D shapes)
│     ├── 'study4_sampleB11': GeoDataFrame shape: (3704, 2) (2D shapes)
│     ├── 'study4_sampleB12': GeoDataFrame shape: (4223, 2) (2D shapes)
│     ├── 'study4_sampleB13': GeoDataFrame shape: (2828, 2) (2D shapes)
│     ├── 'study4_sampleB14': GeoDataFrame shape: (2050, 2) (2D shapes)
│     ├── 'study4_sampleB15': GeoDataFrame shape: (6022, 2) (2D shapes)
│     └── 'study4_sampleB16': GeoDataFrame shape: (4254, 2) (2D shapes)
└── Tables
      └── 'all': AnnData (196496, 11693)
with coordinate systems:
    ▸ 'downscaled_hires', with elements:
        study1_sample1_hires_image (Images), study1_sample2_hires_image (Images), study1_sample3_hires_image (Images), study1_sample4_hires_image (Images), study1_sample5_hires_image (Images), study1_sample6_hires_image (Images), study1_sample7_hires_image (Images), study1_sample8_hires_image (Images), study1_sample9_hires_image (Images), study1_sample10_hires_image (Images), study1_sample11_hires_image (Images), study1_sample12_hires_image (Images), study1_sample13_hires_image (Images), study1_sample14_hires_image (Images), study1_sample15_hires_image (Images), study1_sample16_hires_image (Images), study2_sampleBI33_hires_image (Images), study2_sampleBI39_hires_image (Images), study2_sampleBI64_hires_image (Images), study2_sampleBI66_hires_image (Images), study3_sampleB1_hires_image (Images), study3_sampleB2_hires_image (Images), study3_sampleB3_hires_image (Images), study3_sampleB4_hires_image (Images), study3_sampleB5_hires_image (Images), study3_sampleB6_hires_image (Images), study3_sampleB7_hires_image (Images), study3_sampleB8_hires_image (Images), study3_sampleB9_hires_image (Images), study3_sampleB10_hires_image (Images), study3_sampleB11_hires_image (Images), study3_sampleB12_hires_image (Images), study3_sampleB13_hires_image (Images), study3_sampleB14_hires_image (Images), study3_sampleB15_hires_image (Images), study3_sampleB16_hires_image (Images), study4_sampleB1_hires_image (Images), study4_sampleB2_hires_image (Images), study4_sampleB5_hires_image (Images), study4_sampleB6_hires_image (Images), study4_sampleB7_hires_image (Images), study4_sampleB9_hires_image (Images), study4_sampleB10_hires_image (Images), study4_sampleB11_hires_image (Images), study4_sampleB12_hires_image (Images), study4_sampleB13_hires_image (Images), study4_sampleB14_hires_image (Images), study4_sampleB15_hires_image (Images), study4_sampleB16_hires_image (Images), study1_sample1 (Shapes), study1_sample2 (Shapes), study1_sample3 (Shapes), study1_sample4 (Shapes), study1_sample5 (Shapes), study1_sample6 (Shapes), study1_sample7 (Shapes), study1_sample8 (Shapes), study1_sample9 (Shapes), study1_sample10 (Shapes), study1_sample11 (Shapes), study1_sample12 (Shapes), study1_sample13 (Shapes), study1_sample14 (Shapes), study1_sample15 (Shapes), study1_sample16 (Shapes), study2_sampleBI33 (Shapes), study2_sampleBI39 (Shapes), study2_sampleBI64 (Shapes), study2_sampleBI66 (Shapes), study3_sampleB1 (Shapes), study3_sampleB2 (Shapes), study3_sampleB3 (Shapes), study3_sampleB4 (Shapes), study3_sampleB5 (Shapes), study3_sampleB6 (Shapes), study3_sampleB7 (Shapes), study3_sampleB8 (Shapes), study3_sampleB9 (Shapes), study3_sampleB10 (Shapes), study3_sampleB11 (Shapes), study3_sampleB12 (Shapes), study3_sampleB13 (Shapes), study3_sampleB14 (Shapes), study3_sampleB15 (Shapes), study3_sampleB16 (Shapes), study4_sampleB1 (Shapes), study4_sampleB2 (Shapes), study4_sampleB5 (Shapes), study4_sampleB6 (Shapes), study4_sampleB7 (Shapes), study4_sampleB9 (Shapes), study4_sampleB10 (Shapes), study4_sampleB11 (Shapes), study4_sampleB12 (Shapes), study4_sampleB13 (Shapes), study4_sampleB14 (Shapes), study4_sampleB15 (Shapes), study4_sampleB16 (Shapes)
    ▸ 'downscaled_lowres', with elements:
        study1_sample1_lowres_image (Images), study1_sample2_lowres_image (Images), study1_sample3_lowres_image (Images), study1_sample4_lowres_image (Images), study1_sample5_lowres_image (Images), study1_sample6_lowres_image (Images), study1_sample7_lowres_image (Images), study1_sample8_lowres_image (Images), study1_sample9_lowres_image (Images), study1_sample10_lowres_image (Images), study1_sample11_lowres_image (Images), study1_sample12_lowres_image (Images), study1_sample13_lowres_image (Images), study1_sample14_lowres_image (Images), study1_sample15_lowres_image (Images), study1_sample16_lowres_image (Images), study2_sampleBI33_lowres_image (Images), study2_sampleBI39_lowres_image (Images), study2_sampleBI64_lowres_image (Images), study2_sampleBI66_lowres_image (Images), study3_sampleB1_lowres_image (Images), study3_sampleB2_lowres_image (Images), study3_sampleB3_lowres_image (Images), study3_sampleB4_lowres_image (Images), study3_sampleB5_lowres_image (Images), study3_sampleB6_lowres_image (Images), study3_sampleB7_lowres_image (Images), study3_sampleB8_lowres_image (Images), study3_sampleB9_lowres_image (Images), study3_sampleB10_lowres_image (Images), study3_sampleB11_lowres_image (Images), study3_sampleB12_lowres_image (Images), study3_sampleB13_lowres_image (Images), study3_sampleB14_lowres_image (Images), study3_sampleB15_lowres_image (Images), study3_sampleB16_lowres_image (Images), study4_sampleB1_lowres_image (Images), study4_sampleB2_lowres_image (Images), study4_sampleB5_lowres_image (Images), study4_sampleB6_lowres_image (Images), study4_sampleB7_lowres_image (Images), study4_sampleB9_lowres_image (Images), study4_sampleB10_lowres_image (Images), study4_sampleB11_lowres_image (Images), study4_sampleB12_lowres_image (Images), study4_sampleB13_lowres_image (Images), study4_sampleB14_lowres_image (Images), study4_sampleB15_lowres_image (Images), study4_sampleB16_lowres_image (Images), study1_sample1 (Shapes), study1_sample2 (Shapes), study1_sample3 (Shapes), study1_sample4 (Shapes), study1_sample5 (Shapes), study1_sample6 (Shapes), study1_sample7 (Shapes), study1_sample8 (Shapes), study1_sample9 (Shapes), study1_sample10 (Shapes), study1_sample11 (Shapes), study1_sample12 (Shapes), study1_sample13 (Shapes), study1_sample14 (Shapes), study1_sample15 (Shapes), study1_sample16 (Shapes), study2_sampleBI33 (Shapes), study2_sampleBI39 (Shapes), study2_sampleBI64 (Shapes), study2_sampleBI66 (Shapes), study3_sampleB1 (Shapes), study3_sampleB2 (Shapes), study3_sampleB3 (Shapes), study3_sampleB4 (Shapes), study3_sampleB5 (Shapes), study3_sampleB6 (Shapes), study3_sampleB7 (Shapes), study3_sampleB8 (Shapes), study3_sampleB9 (Shapes), study3_sampleB10 (Shapes), study3_sampleB11 (Shapes), study3_sampleB12 (Shapes), study3_sampleB13 (Shapes), study3_sampleB14 (Shapes), study3_sampleB15 (Shapes), study3_sampleB16 (Shapes), study4_sampleB1 (Shapes), study4_sampleB2 (Shapes), study4_sampleB5 (Shapes), study4_sampleB6 (Shapes), study4_sampleB7 (Shapes), study4_sampleB9 (Shapes), study4_sampleB10 (Shapes), study4_sampleB11 (Shapes), study4_sampleB12 (Shapes), study4_sampleB13 (Shapes), study4_sampleB14 (Shapes), study4_sampleB15 (Shapes), study4_sampleB16 (Shapes)
    ▸ 'global', with elements:
        study1_sample1 (Shapes), study1_sample2 (Shapes), study1_sample3 (Shapes), study1_sample4 (Shapes), study1_sample5 (Shapes), study1_sample6 (Shapes), study1_sample7 (Shapes), study1_sample8 (Shapes), study1_sample9 (Shapes), study1_sample10 (Shapes), study1_sample11 (Shapes), study1_sample12 (Shapes), study1_sample13 (Shapes), study1_sample14 (Shapes), study1_sample15 (Shapes), study1_sample16 (Shapes), study2_sampleBI33 (Shapes), study2_sampleBI39 (Shapes), study2_sampleBI64 (Shapes), study2_sampleBI66 (Shapes), study3_sampleB1 (Shapes), study3_sampleB2 (Shapes), study3_sampleB3 (Shapes), study3_sampleB4 (Shapes), study3_sampleB5 (Shapes), study3_sampleB6 (Shapes), study3_sampleB7 (Shapes), study3_sampleB8 (Shapes), study3_sampleB9 (Shapes), study3_sampleB10 (Shapes), study3_sampleB11 (Shapes), study3_sampleB12 (Shapes), study3_sampleB13 (Shapes), study3_sampleB14 (Shapes), study3_sampleB15 (Shapes), study3_sampleB16 (Shapes), study4_sampleB1 (Shapes), study4_sampleB2 (Shapes), study4_sampleB5 (Shapes), study4_sampleB6 (Shapes), study4_sampleB7 (Shapes), study4_sampleB9 (Shapes), study4_sampleB10 (Shapes), study4_sampleB11 (Shapes), study4_sampleB12 (Shapes), study4_sampleB13 (Shapes), study4_sampleB14 (Shapes), study4_sampleB15 (Shapes), study4_sampleB16 (Shapes)
with the following elements not in the Zarr store:
    ▸ all (Tables)
with the following elements in the Zarr store but not in the SpatialData object:
    ▸ study1_sample5_table (Tables)
    ▸ study1_sample6_table (Tables)
    ▸ study3_sampleB14_table (Tables)
    ▸ study1_sample1_table (Tables)
    ▸ study1_sample7_table (Tables)
    ▸ study1_sample2_table (Tables)
    ▸ study4_sampleB2_table (Tables)
    ▸ study1_sample4_table (Tables)
    ▸ study3_sampleB11_table (Tables)
    ▸ study3_sampleB15_table (Tables)
    ▸ study1_sample9_table (Tables)
    ▸ study3_sampleB6_table (Tables)
    ▸ study4_sampleB13_table (Tables)
    ▸ study4_sampleB12_table (Tables)
    ▸ study3_sampleB2_table (Tables)
    ▸ study1_sample10_table (Tables)
    ▸ study3_sampleB8_table (Tables)
    ▸ study1_sample13_table (Tables)
    ▸ study4_sampleB1_table (Tables)
    ▸ study4_sampleB11_table (Tables)
    ▸ study4_sampleB5_table (Tables)
    ▸ study1_sample8_table (Tables)
    ▸ study3_sampleB16_table (Tables)
    ▸ study4_sampleB16_table (Tables)
    ▸ study4_sampleB14_table (Tables)
    ▸ study3_sampleB1_table (Tables)
    ▸ study4_sampleB15_table (Tables)
    ▸ study2_sampleBI39_table (Tables)
    ▸ study1_sample14_table (Tables)
    ▸ study4_sampleB10_table (Tables)
    ▸ study2_sampleBI64_table (Tables)
    ▸ study1_sample15_table (Tables)
    ▸ study3_sampleB12_table (Tables)
    ▸ study3_sampleB4_table (Tables)
    ▸ study1_sample11_table (Tables)
    ▸ study1_sample3_table (Tables)
    ▸ study3_sampleB13_table (Tables)
    ▸ study3_sampleB7_table (Tables)
    ▸ study3_sampleB5_table (Tables)
    ▸ study4_sampleB6_table (Tables)
    ▸ study2_sampleBI33_table (Tables)
    ▸ study1_sample12_table (Tables)
    ▸ study3_sampleB9_table (Tables)
    ▸ study3_sampleB3_table (Tables)
    ▸ study4_sampleB7_table (Tables)
    ▸ study3_sampleB10_table (Tables)
    ▸ study2_sampleBI66_table (Tables)
    ▸ study1_sample16_table (Tables)
    ▸ study4_sampleB9_table (Tables)

I loaded it from a zarr store

sdata = sd.read_zarr(...)

And then added a new consolidated .table from an anndata object (obtained from cell2location)

adata = ad.read_h5ad(...)
for k in list(sdata.tables):
    del sdata.tables[k]
sdata.tables["all"] = adata

Plotting a single static image takes >10 seconds.

%%timeit
sdata.pl.render_images(f"{sample}_hires_image").pl.render_shapes(
        sample,
        color="training_batch",
        scale=1.5,
    ).pl.show("downscaled_hires", title=f"{sample}")
INFO     Rasterizing image for faster rendering.                                                                   
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Got range [-0.012448133..1.0].
/scratch/<redacted>/.venv/lib/python3.12/site-packages/spatialdata/_core/_elements.py:105: UserWarning: Key `study4_sampleB7` already exists. Overwriting it in-memory.
  self._check_key(key, self.keys(), self._shared_keys)
/scratch/<redacted>/.venv/lib/python3.12/site-packages/spatialdata/_core/_elements.py:125: UserWarning: Key `all` already exists. Overwriting it in-memory.
  self._check_key(key, self.keys(), self._shared_keys)
[...]
11.5 s ± 439 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

For comparison, these are the timings with the demo visium dataset only takes ~1 second

sdata2 = sd.read_zarr("visium_brain.zarr")
%%timeit
(sdata2.pl.render_images(elements="ST8059048_hires_image")
        .pl.render_shapes(elements="ST8059048", color="mt-Co3")
        .pl.show())
INFO     Dropping coordinate system 'ST8059050' since it doesn't have relevant elements.                           
INFO     Dropping coordinate system 'ST8059052' since it doesn't have relevant elements.                           
<magic-timeit>:1: DeprecationWarning: `elements` is being deprecated as an argument to `PlotAccessor.render_images.render_images` in spatialdata_plot version version 0.3.0, switch to `element` instead.
<magic-timeit>:2: DeprecationWarning: `elements` is being deprecated as an argument to `PlotAccessor.render_shapes.render_shapes` in spatialdata_plot version 0.3.0, switch to `element` instead.
/scratch/sturmgre/projects/scverse/spatialdata-plot/.venv/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:185: UserWarning: The table is annotating 'ST8059050', which is not present in the SpatialData object.
  self.validate_table_in_spatialdata(v)
INFO     Rasterizing image for faster rendering.                                                                   
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers). Got range [-0.03797468..1.0].
/scratch/sturmgre/projects/scverse/spatialdata-plot/.venv/lib/python3.12/site-packages/spatialdata/_core/_elements.py:105: UserWarning: Key `ST8059048` already exists. Overwriting it in-memory.
  self._check_key(key, self.keys(), self._shared_keys)
/scratch/sturmgre/projects/scverse/spatialdata-plot/.venv/lib/python3.12/site-packages/spatialdata/_core/_elements.py:125: UserWarning: Key `table` already exists. Overwriting it in-memory.
  self._check_key(key, self.keys(), self._shared_keys)
[...]
1.16 s ± 34.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

grst avatar Jan 29 '25 07:01 grst

Thanks for reporting. Proper profiling needs to be done, but if I have to make a guess I'd say that the reason is spatialdata.join_spatialelement_table().

LucaMarconato avatar Jan 30 '25 15:01 LucaMarconato

Replicated the issue by adding multiple time (50) the same table to the sdata.

Got this profiling top cumulative time :

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    160/4    0.103    0.001   99.816   24.954 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/matplotlib/text.py:358(_get_layout)
    325/9    0.005    0.000   99.571   11.063 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/matplotlib/text.py:65(_get_text_metrics_with_cache)
        1    0.024    0.024   96.804   96.804 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/spatialdata_plot/pl/render.py:61(_render_shapes)
      8/5    0.013    0.002   93.839   18.768 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/spatialdata/_utils.py:261(wrapper)
       52    0.303    0.006   93.829    1.804 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/anndata/_core/anndata.py:1430(copy)
        1    0.009    0.009   93.613   93.613 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:685(filter_by_coordinate_system)
        1    0.001    0.001   93.232   93.232 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/spatialdata/_core/spatialdata.py:735(_filter_tables)
       51    0.001    0.000   93.228    1.828 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/spatialdata/_core/query/relational_query.py:61(_filter_table_by_element_names)
2340/2328    0.021    0.000   90.641    0.039 /Users/ldumont/.pyenv/versions/3.12.9/lib/python3.12/functools.py:907(wrapper)
       52    0.001    0.000   88.833    1.708 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/anndata/_core/index.py:176(_subset_sparse)
       52    0.001    0.000   88.832    1.708 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/scipy/sparse/_index.py:29(__getitem__)
       52    0.000    0.000   88.829    1.708 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/scipy/sparse/_csr.py:273(_get_arrayXslice)
       52    0.060    0.001   88.828    1.708 /Users/ldumont/git/spatialdata-io/.venv/lib/python3.12/site-packages/scipy/sparse/_compressed.py:750(_major_index_fancy)
       52   88.744    1.707   88.744    1.707 {built-in method scipy.sparse._sparsetools.csr_row_index}
     9597    4.369    0.000    4.369    0.000 {method 'copy' of 'numpy.ndarray' objects}

seems like _filter_table_by_element_names() is called for each table in sdata.table. Thus filtering and copying a sparse matrix x 50

After talking with @LucaMarconato it seems like this function will be soon deprecated?

Otherwise one fix would be to return empty table if table.obs[region_key].isin(element_names).any() == False and thus avoid the copy and access to sparse data.


    table_mask = table.obs[region_key].isin(element_names)

    if table_mask.any() == False:
        return AnnData()

laudmt avatar Mar 18 '25 13:03 laudmt