scverse / spatialdata-plot

Static plotting for spatialdata
BSD 3-Clause "New" or "Revised" License
37 stars 14 forks source link

Vega-like viewconfigurations #388

Open melonora opened 1 week ago

melonora commented 1 week ago

During the hackathon in Basel we have brainstormed on the specification that would allow for viewing data across the spatialdata visualization ecosystem with one viewconfig. This issue describes the current ideas of this viewconfiguration.

Data

The first field in the view configuration is related to the data and specifies the zarr store and the particular elements that we want to visualize. It also includes a filtering step. For example:

"schema": "https://spatialdata-plot.github.io/schema/viewconfig/v1.json"
"height": 15 # This is in inches
"width": 14
"data": [
        {
            "name": "{UUID1}",
            "url": "blobs.zarr"
            "format": "spatialdata",
            "version": "0.2.0"
        },
        {
          "name": "{UUID2}",
          "format": "spatialdata_image",
          "version": "0.1.0",
          "source": "UUID1",
          "transform": [
            {
              "type": "filter",
              "expr": "datum['images/blobs_image']"
            }
          ]
        },
  ]      

Here the first block contains the location of the zarr store. We specify the particular format of the zarr store and the version. The name is serving as a UUID in the document so that other blocks in the configuration can refer to a particular block. Typically, on the data a transform is applied. In most cases for SpatialData this would be a filter transform initially to get the particular element that we require. The height and width is the overall size in inches of the plot.

Scales

Scales provide a mapping of a series of values to a different series of values, whether that is axes limits and ticks or a mapping of values to color.

"scales": [
        { <!-- Example of scale for continuous variable-->
          "name": "color_0", <!-- can chain render_... calls that would use different normalize objects-->
          "type": "linear",
          "zero": true, <!-- Whether to include 0 value in the color mapping, useful for labels-->
          "domain": [0, 1],  <!-- this is the vmin vmax-->
          "clamp": true,  <!-- This is the clip of the normalize object in matplotlib-->
          "range": {"scheme": "gray"}
        },
        { <!-- Example of scale for categorical variable-->
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "UUID of spatial element", "field": "category"}, <!-- category here is column-->
      "range": {"scheme": "category20"} <!--This is only required if there are no hex strings specified before, in some cases a user can already have the hexstrings representing color. In this case the color encoding in marks must be used.-->
        },
        {
              "name": "X_SCALE",
              "type": "linear",
              "zero": true,
              "domain": [-180, 180], <!-- This is the extent of the axes after having applied the transform to coordinate system-->
              "range": "width" <!-- refers to plot width-->
            },
            {
              "name": "Y_SCALE",
              "type": "linear",
              "zero": true,
              "domain": [-81, 87],
              "range": "height" <!-- refers to plot height-->
            }
    ],

Marks

Marks define the actual plots of the particular elements.


"marks": [
        {
          "type": "raster", <!-- type of element -->
          "from": {"data": "UUID3"},
          "zindex": 0,
          "encode": {
              <!-- "channel": {"value": 0}, // with "data": "UUID2" -->
              "opacity": {"value": 1}, <!-- sdata-plot "alpha". Also, it was fillOpacity -->
              "color": {"scale": "normalize", "field": "channel_zero_name"}
              <!--"zindex": {"field": "point_importance"}-->
          }
        },
        {
          "type": "shape", <!-- type of element -->
          "from": {"data": "UUID5"},
          "zindex": 1,
          "encode": {
              <!-- "channel": {"value": 0},
              "opacity": {"value": 1}, <!-- sdata-plot "alpha". Also, it was fillOpacity -->
              "color": {hexstrings} <!-- in case of predetermined hexstrings --> 
              <!--"zindex": {"field": "point_importance"}-->
          }
        }
      ],
keller-mark commented 1 week ago

Documentation of conflicting terminology