Drawing data points as interpolated image

97 views
Skip to first unread message

Patrick Meijers

unread,
Dec 17, 2019, 6:20:34 AM12/17/19
to vega-js
Hi 

Does anybody know an example of how to efficiently draw a table of data points like {"x": ..., "y": ..., "value": ...} as an image into the plot?
So instead of drawing rects or symbols for each row in the table (too slow), draw the values (using a color scale) at indicated x,y coordinates (using x/y scales) and interpolate in between. 

It sounds much like a heatmap. But the Vega documentation and examples on heatmap are not clear enough for me to understand how to get from a table with rows as shown above into something that is shown as a heatmap/image mark.

Thanks in advance, 

Patrick

Roy I

unread,
Dec 17, 2019, 5:45:26 PM12/17/19
to vega-js
This Vega heatmap example (before Nov 2019) draws a grid of colored rectangles:

Vega version 5.8.0 (released Nov 19, 2019):
"New transforms for more flexible 2D density estimation (kde2d), flexible isocontour generation (isocontour), and heatmap image rendering (heatmap).
...The contour transform is now deprecated and may be removed in a future major release. Instead, use the new, more expressive isocontour, kde2d, and heatmap transforms."

Documentation:

Examples:

Data files for Vega examples:

If you need more specific help, please post sample data and how you would like the plot to appear.

Patrick Meijers

unread,
Dec 18, 2019, 9:00:11 AM12/18/19
to vega-js
Thanks for quick response. 

The rect based heatmap I understood. That I tried and is too slow.
I don't want any post-processing (transform) on the data (except for applying a scale to color), like isocontour of kde2d.
Just want a data table such as: 
data [
{
"name": "...",
"values": [
{"x": -6.25, "y": -10.66, "c":
0.2},
{
"x": 6.25, "y": -10.66, "c": 0.1},
{
"x": -6.25, "y": 0, "c": 0.12},
{
"x": 6.25, "y": 0, "c": 0.123},
{
"x": -6.25, "y": 10.66, "c": 0.2},
{
"x": 6.25, "y": 10.66, "c": 0.12}
    ...
],
to be displayed as an interpolated image with x,y pixel positions of color values c.

Op dinsdag 17 december 2019 23:45:26 UTC+1 schreef Roy I:

Roy I

unread,
Dec 19, 2019, 8:39:33 AM12/19/19
to vega-js
New (v5.8) Vega heatmap transform:

"The heatmap transform ≥ 5.8 renders input raster grids (matrices) into output heatmap images.
 This transform can be used to visualize 2D input raster data, density estimates, 
or mathematical functions as color grids."

The "input raster grids (matrices)" requires a different format that needs more documention
but can be seen in these Vega example data files:


The input data "matrix" of cell values is an object with properties:
   "width" : number of columns
   "height" : number of rows
   "values" : linear array of cell values starting from top row, left column

The Vega transform kde2d can generate this dataset within the Vega spec
 given a source dataset with arbitrary x, y corodinates and point values. 

Note: If you do not wish to use kde2d, then you have to provide an input dataset in this "matrix" format.

Here is a working example of the new Vega heatmap transform (without kde2d and isocontour transforms):

screenshot_vega_v5_8_heatmap.png


Vega 5.9.0 spec
----------------

{
  "width": 400,
  "height": 300,
  "padding": 20,
  
  "data": [
    { "name": "data_heatmap",
      "values": [ { "width": 4, 
        "height": 3,
        "values":  [ 10, 20, 30, 40,
                                                  80, 60, 70, 30,
                          50, 90, 40, 20
                                 ]
  }
               ],
      "transform": [
        {
          "type": "heatmap",
          "color": {"expr": "scale('scale_color', datum.$value)"},
          "opacity": 0.8,
  "as": "heatmap_image"
        }
      ]
    }
  ],
  
  "scales": [
    { "name": "scale_x",
      "type": "linear",
      "domain": [0, 4],
      "range": "width"
    },

    { "name": "scale_y",
      "type": "linear",
     "domain": [0, 3],
      "range": "height"
    },

    {"name": "scale_color",
      "type": "linear",
      "domain": [0, 100],
      "range": {"scheme": "blues"}
    }
  ],
  
  "axes": [
    {
          "scale": "scale_x",
          "orient": "bottom",
          "tickCount": 5,
          "title": "x",
  "grid": true
    },

    {
      "scale": "scale_y",
      "orient": "left",
  "tickCount": 4,
      "title": "y",
  "grid": true
    }
  ],
 
    "marks": [
        {
          "type": "image",
          "from": {"data": "data_heatmap"},
          "encode": {
            "update": {
              "x": {"value": 0},
              "y": {"value": 0},
              "image": {"field": "heatmap_image"},
              "width": {"signal": "width"},
              "height": {"signal": "height"},
              "smooth": true
            }
          }
        }
    ]
}




On Tuesday, December 17, 2019 at 6:20:34 AM UTC-5, Patrick Meijers wrote:

Patrick Meijers

unread,
Dec 19, 2019, 8:43:44 AM12/19/19
to vega-js
OK, that looks like the missing info. I will try it out asap. Thanks!

Op donderdag 19 december 2019 14:39:33 UTC+1 schreef Roy I:

Patrick Meijers

unread,
Dec 20, 2019, 6:33:26 AM12/20/19
to vega-js
Works as a charm. Thanks!

Op donderdag 19 december 2019 14:43:44 UTC+1 schreef Patrick Meijers:
Reply all
Reply to author
Forward
0 new messages