Scatter Plot Null Values Example

A configurable scatter plot of movie statistics, including IMDB and Rotten Tomatoes review scores. Null values in one or more dimensions are depicted along the margins to better convey missing values. Tooltips are included for interactive inspection of individual movies.

Vega JSON Specification <>

{
  "$schema": "https://vega.github.io/schema/vega/v3.0.json",
  "width": 450,
  "height": 450,
  "padding": 5,
  "autosize": {"type": "fit", "resize": true},

  "signals": [
    { "name": "yField", "value": "IMDB_Rating",
      "bind": {"input": "select", "options": ["IMDB_Rating", "Rotten_Tomatoes_Rating", "US_Gross", "Worldwide_Gross"]} },
    { "name": "xField", "value": "Rotten_Tomatoes_Rating",
      "bind": {"input": "select", "options": ["IMDB_Rating", "Rotten_Tomatoes_Rating", "US_Gross", "Worldwide_Gross"]} },
    { "name": "nullSize", "value": 8 },
    { "name": "nullGap", "update": "nullSize + 10" }
  ],

  "data": [
    {
      "name": "movies",
      "url": "data/movies.json",
      "transform": [
        {
          "type": "formula",
          "expr": "datum.Title + ' (' + (year(datum.Release_Date) || '?') + ')'",
          "as":   "tooltip"
        }
      ]
    },
    {
      "name": "valid",
      "source": "movies",
      "transform": [
        {
          "type": "filter",
          "expr": "datum[xField] != null && datum[yField] != null"
        }
      ]
    },
    {
      "name": "nullXY",
      "source": "movies",
      "transform": [
        {
          "type": "filter",
          "expr": "datum[xField] == null && datum[yField] == null"
        },
        { "type": "aggregate" }
      ]
    },
    {
      "name": "nullY",
      "source": "movies",
      "transform": [
        {
          "type": "filter",
          "expr": "datum[xField] != null && datum[yField] == null"
        }
      ]
    },
    {
      "name": "nullX",
      "source": "movies",
      "transform": [
        {
          "type": "filter",
          "expr": "datum[xField] == null && datum[yField] != null"
        }
      ]
    }
  ],

  "scales": [
    {
      "name": "yscale",
      "type": "linear",
      "range": [{"signal": "height - nullGap"}, 0],
      "nice": true,
      "domain": {"data": "valid", "field": {"signal": "yField"}}
    },
    {
      "name": "xscale",
      "type": "linear",
      "range": [{"signal": "nullGap"}, {"signal": "width"}],
      "nice": true,
      "domain": {"data": "valid", "field": {"signal": "xField"}}
    }
  ],

  "axes": [
    {
      "orient": "bottom", "scale": "xscale", "offset": 5, "format": "s",
      "title": {"signal": "xField"}
    },
    {
      "orient": "left", "scale": "yscale", "offset": 5, "format": "s",
      "title": {"signal": "yField"}
    }
  ],

  "marks": [
    {
      "type": "symbol",
      "from": {"data": "valid"},
      "encode": {
        "enter": {
          "size": {"value": 50},
          "tooltip": {"field": "tooltip"}
        },
        "update": {
          "x": {"scale": "xscale", "field": {"signal": "xField"}},
          "y": {"scale": "yscale", "field": {"signal": "yField"}},
          "fill": {"value": "steelblue"},
          "fillOpacity": {"value": 0.5},
          "zindex": {"value": 0}
        },
        "hover": {
          "fill": {"value": "firebrick"},
          "fillOpacity": {"value": 1},
          "zindex": {"value": 1}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "nullY"},
      "encode": {
        "enter": {
          "size": {"value": 50},
          "tooltip": {"field": "tooltip"}
        },
        "update": {
          "x": {"scale": "xscale", "field": {"signal": "xField"}},
          "y": {"signal": "height - nullSize/2"},
          "fill": {"value": "#aaa"},
          "fillOpacity": {"value": 0.2}
        },
        "hover": {
          "fill": {"value": "firebrick"},
          "fillOpacity": {"value": 1}
        }
      }
    },
    {
      "type": "symbol",
      "from": {"data": "nullX"},
      "encode": {
        "enter": {
          "size": {"value": 50},
          "tooltip": {"field": "tooltip"}
        },
        "update": {
          "x": {"signal": "nullSize/2"},
          "y": {"scale": "yscale", "field": {"signal": "yField"}},
          "fill": {"value": "#aaa"},
          "fillOpacity": {"value": 0.2},
          "zindex": {"value": 0}
        },
        "hover": {
          "fill": {"value": "firebrick"},
          "fillOpacity": {"value": 1},
          "zindex": {"value": 1}
        }
      }
    },
    {
      "type": "text",
      "interactive": false,
      "from": {"data": "nullXY"},
      "encode": {
        "update": {
          "x": {"signal": "nullSize", "offset": -4},
          "y": {"signal": "height", "offset": 13},
          "text": {"signal": "datum.count + ' null'"},
          "align": {"value": "right"},
          "baseline": {"value": "top"},
          "fill": {"value": "#999"},
          "fontSize": {"value": 9}
        }
      }
    }
  ]
}