Skip to content

Handling Annotations from QuPath #430

Closed

Description

@rushin682

Certain issues noticed:

  • Geometry type not validated from QuPath (i.e Polygons are sometimes just multi polygons. So analysis only considered first array of coords)
  • MultiPolygons are not being plotted (Possibly intersecting points issue.)

Attached test geojson file : test_geojson.txt

Fix possibilities:

  • Coordinate based Validator for geometry type
  • Recompute polygons in Multipolygon setting

All Polygons plot:

Image

Single Multipolygon plot error:

ValueError                                Traceback (most recent call last)
Cell In[116], [line 1](vscode-notebook-cell:?execution_count=116&line=1)
----> [1](vscode-notebook-cell:?execution_count=116&line=1) sdata.pl.render_images("he_image").pl.render_shapes(f"multipolygon_single", fill_alpha=0, outline_alpha=1.0, outlide_width=0.5).pl.show()

File ~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:918, in PlotAccessor.show(self, coordinate_systems, legend_fontsize, legend_fontweight, legend_loc, legend_fontoutline, na_in_legend, colorbar, wspace, hspace, ncols, frameon, figsize, dpi, fig, title, share_extent, pad_extent, ax, return_ax, save)
    [913](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:913)     wanted_elements, wanted_shapes_on_this_cs, wants_shapes = _get_wanted_render_elements(
    [914](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:914)         sdata, wanted_elements, params_copy, cs, "shapes"
    [915](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:915)     )
    [917](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:917)     if wanted_shapes_on_this_cs:
--> [918](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:918)         _render_shapes(
    [919](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:919)             sdata=sdata,
    [920](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:920)             render_params=params_copy,
    [921](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:921)             coordinate_system=cs,
    [922](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:922)             ax=ax,
    [923](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:923)             fig_params=fig_params,
    [924](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:924)             scalebar_params=scalebar_params,
    [925](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:925)             legend_params=legend_params,
    [926](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:926)         )
    [928](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:928) elif cmd == "render_points" and has_points:
    [929](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:929)     wanted_elements, wanted_points_on_this_cs, wants_points = _get_wanted_render_elements(
    [930](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:930)         sdata, wanted_elements, params_copy, cs, "points"
    [931](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/basic.py:931)     )

File ~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/spatialdata_plot/pl/render.py:312, in _render_shapes(sdata, render_params, coordinate_system, ax, fig_params, scalebar_params, legend_params)
...
    [140](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/matplotlib/path.py:140)     raise ValueError("The first element of 'code' must be equal "
    [141](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/matplotlib/path.py:141)                      f"to 'MOVETO' ({self.MOVETO}).  "
    [142](https://file+.vscode-resource.vscode-cdn.net/Users/rushin.gindra/Documents/scverse_x_owkin/notebooks/~/miniforge3/envs/spatialdata/lib/python3.10/site-packages/matplotlib/path.py:142)                      f"Your first code is {codes[0]}")

ValueError: 'codes' must be a 1D list or array with the same length of 'vertices'. Your vertices have shape (168, 2) but your codes have shape (44,)

@LucaMarconato @timtreis

Activity

  1. quentinblampey commented on Jun 22, 2025

    @quentinblampey

    I have the same error, but with a shape generated from Sopa. To make it easier to reproduce, I share the shapes:
    https://drive.google.com/file/d/1dVAuPHGeiBKnb6MfFxAHirZtK48h8fP6/view?usp=sharing

    It's a valid shape, and GeoPandas has no issue plotting it:

    import geopandas as gpd
    import matplotlib.pyplot as plt
    from spatialdata import SpatialData
    from spatialdata.models import ShapesModel
    import spatialdata_plot
    
    # get only the first shape for simplicity
    gdf = gpd.read_parquet("shapes_reproduce.parquet").loc[:1]
    
    gdf.plot() # nicely plots the shape

    But spatialdata-plot throws an error:

    sdata = SpatialData(shapes={"tissue": ShapesModel.parse(gdf)})
    sdata.pl.render_shapes("tissue").pl.show()
    ValueError: 'codes' must be a 1D list or array with the same length of 'vertices'. Your vertices have shape (36981, 2) but your codes have shape (41748,)
    

    Note 1: It works if I do gdf.geometry = gdf.buffer(1), which indicates the issue must be related to the polygon holes.

    Note 2: I wonder why, more generally, the internal functions of GeoPandas are not used directly for plotting the polygons? It would also solve the issue related to plotting polygons with holes #333. Since it also use matplotlib internally, it seems natural to re-use them.

    from geopandas.plotting import _plot_polygon_collection
    
    fig, ax = plt.subplots(figsize=(2, 5))
    _plot_polygon_collection(ax, gdf)
    plt.axis("equal")

    Image

    @timtreis

  2. quentinblampey commented on Jul 18, 2025

    @quentinblampey

    Hi @timtreis, do you have any updates on this? Do you want me to have a look, or are you already working on this?

    I guess the fix is just to use _plot_polygon_collection from geopandas.plotting to replace the shapes rendering, but I'm not super familiar with the codebase of spatialdata-plot, so I don't know how easy it is to make this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions