Skip to content

Which layer should I use? ​

Choose the representation for your scientific data and intended interaction. These recommendations are not automatic conversions or dataset-type restrictions. A collection of cells does not require a special “cell layer.”

Data / intentPython creationBrowser renderingTradeoff
Large centroids or detectionslayers.add_points(...)ScatterplotLayer; optional HeatmapLayer, GridLayer, ContourLayerCompact float32 positions/scores, no Feature per point.
Large generated boundarieslayers.add_polygons(...)Polygon renderer: binary SolidPolygonLayer fill + binary PathLayer ring outlinesPacked vertices/offsets/scores; triangulation still costs CPU and GPU memory.
Convenient moderate geometry with propertieslayers.add_geojson(...)GeoJsonLayerPortable, ordinary JSON properties; Feature objects carry memory overhead.
Small collection needing interactive editingannotations.add_polygon(...)GeoJsonLayer for display; EditableGeoJsonLayer in edit modeClasses, ROI styles/metadata, vertex editing; bounded annotation JSON.
Binary segmentationlayers.add_mask(...)BitmapLayer or TileLayerZero transparent; foreground uses the layer color.
Instance/label segmentationlayers.add_mask(..., labels=True)BitmapLayer or TileLayerInteger IDs preserved; zero transparent; repeating display colors do not define semantic classes.
Probability or scalar heatmaplayers.add_probability(...)BitmapLayer or TileLayerFinite values 0–1, fixed palette; distinguish this from smoothed point density.

Layer type and compatible renderer are explicit. Changing a point renderer to density/count aggregation keeps its point source. Generated polygons/GeoJSON are never made editable automatically. Model outputs are never silently replaced with centroids. To choose another representation, compute that conversion explicitly and add a new layer.

Points ​

add_points accepts (x,y) or (x,y,score) rows, or a numeric NumPy N×2/N×3 array. Unscored positions get weight 1; this is not a model confidence estimate. The persisted table is float32 N×3; scores range from 0 to 1. For large model outputs, pass a NumPy array. Float32 positions have finite precision; they are not lossless arbitrary-precision coordinates.

python
layer = slide.layers.add_points(centroids, name='detections')
slide.layers.update(layer['id'], settings={'radius': 4, 'opacity': .7})
slide.layers.update(layer['id'], settings={'renderer': 'HeatmapLayer'})

Point-density/count renderers currently count points; they do not weight counts by confidence. Scatter colors use the score. Grid and contour cell sizes use slide pixels; scatter and density radii use output/screen pixels.

Generated polygons ​

Input is an iterable of polygons, each a sequence of rings: outer ring first, then holes. Positions are level-0 (x,y). Open rings are explicitly closed by the constructor. Concave boundaries and holes use real triangulation in the browser; no convex-fan shortcut is used for model outputs.

python
slide.layers.add_polygons(
    [[outer_ring, hole_ring], [another_outer_ring]],
    scores=[.9, .7], name='boundaries',
)

The packed source carries offsets, float32 XY positions, and one score per polygon. It does not carry arbitrary per-polygon properties or MultiPolygon feature identity. A MultiPolygon can be represented as several explicit polygons; use GeoJSON when preserving that grouping and properties matters. No full polygon-topology repair is performed; provide valid non-self-intersecting rings and valid holes.

Ordinary GeoJSON versus editing ​

Ordinary GeoJSON supports Point/MultiPoint, LineString/MultiLineString, Polygon/MultiPolygon, with JSON properties. Coordinates are slide pixels, not geography. A numeric properties.score supplies palette color; otherwise the layer color is used. There is no arbitrary JavaScript accessor execution from files.

Editable geometry currently means the one per-project ROI collection, not an arbitrary number of EditableGeoJson layers. It supports Polygon/rectangle ROIs, classes, styles, and primitive metadata. Converting generated geometry into editable annotations is an explicit annotation operation; the annotation limits apply regardless of where it originated.

Rasters ​

Arrays cover the whole slide by default. bounds=(x,y,width,height) can describe a cropped field of view. Raster rows/columns map to this field's pixel edges; nearest sampling preserves labels and original values. Binary masks contain only 0/1. Label rasters contain integer IDs 0–16,777,215, represented exactly in float32. Semantic class tables and color mappings are not part of this V2 extension.

TileLayer creates visible display tiles from the loaded array. It is not out-of-core file streaming: the bounded array still loads in full. Tiled GeoJSON, pyramidal raster assets, and chunked spatial datasets are not implemented.

Other viewer renderers ​

GridCellLayer, standalone PathLayer/LineLayer/TextLayer, and the remaining approved renderers have synthetic preview recipes. They are not separate persisted model-output types in this release. Real lines/paths can use ordinary GeoJSON. The static Python renderer skips synthetic fixtures with an explicit warning; it does not present them as model data.

Limits: 1m points; 2m packed polygon vertices; 50k ordinary GeoJSON features/2m vertices; 8,388,608 raster values; ~32 MiB per asset; 128 MiB total assets; 64 layers. These are current file/memory bounds, not assurances of smooth interaction on every device. GPU scale needs representative measurements. See format, rendering, and measured limitations.