Search code examples
plotgraphvega-litevega

Vega-Lite: is it possible to plot a 3-layered graph with one Y-axis used only by 2 specific layers?


I'm wondering how I can plot a single graph with multiple Y axis in a more controlled way. My current graph has already 3 layers, they're in the same values ballpark, so should remain on one Y-axis. However, now I have to plot a vastly differently-scaled thing on top, and I need an independent Y-axis just for certain layers. Is it possible?

Right now, if I set resolve: scale: Y: independent, all layers try to fight for the second Y-axis it seems, and the whole plot dissolves.

Below is a minimal reproducible example that can be copy-pasted as-is to https://vega.github.io/editor/#/ . The goal here is to be able to tell slopes of all 3 lines with a naked eye; in other words, make "X-Y" and "X2-Y2" lines use the left Y-axis with one scale, and make "X3-Y3" use the right Y-axis with a different one.

Please note than in reality, I already have 6 layers with different mark types and will keep adding those. All of those, however, will fall into two scale categories (say, values from 1 to 10 and from 10000 to 20000). I'd like to be able to define for each layer which category it falls into and which Y-axis - left or right - it uses.

{
  "data": {
    "values": [
      {"x": 1, "y": 10},
      {"x": 2, "y": 7},
      {"x2": 1, "y2": 11},
      {"x2": 2, "y2": 12},
      {"x3": 1, "y3": 1000},
      {"x3": 2, "y3": 2500}
    ]
  },
  "encoding": {"x": {"type": "quantitative"}, "y": {"type": "quantitative"}},
  "layer": [
    {
      "mark": "line",
      "encoding": {"x": {"field": "x"}, "y": {"field": "y"}}
      
    },
    {
      "mark": {
        "type": "square",
        "size": 100
       },
      "encoding": {
        "x": {"field": "x2"},
        "y": {"field": "y2"},
        "color": {"value": "red"}
      }
      
    },
    {
      "mark": "line",
      "encoding": {
        "x": {"field": "x3"},
        "y": {"field": "y3"},
        "color": {"value": "black"}
      }
      
    }
  ],
  "mark": "line",
  "config": {},
  "resolve": {"scale": {"y": "independent"}}
}

Solution

  • In your sample code the resolve config was given at the wrong place, and since you wanted

    "X-Y" and "X2-Y2" lines use the left Y-axis with one scale, and make "X3-Y3" use the right Y-axis with a different one.

    I have placed the 1st two layers in a separate layer which share the x and y axis and a different layer which will have independent y axis using resolve.

    Check the below code or the editor link:

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"x": 1, "y": 10},
          {"x": 2, "y": 7},
          {"x2": 1, "y2": 11},
          {"x2": 2, "y2": 12},
          {"x3": 1, "y3": 1000},
          {"x3": 2, "y3": 2500}
        ]
      },
      "encoding": {"x": {"type": "quantitative"}, "y": {"type": "quantitative"}},
      "layer": [
        {
          "layer": [
            {
              "mark": "line",
              "encoding": {"x": {"field": "x"}, "y": {"field": "y"}}
            },
            {
              "mark": "line",
              "encoding": {
                "x": {"field": "x2"},
                "y": {
                  "field": "y2",
                  "type": "quantitative",
                  "axis": {"orient": "left"}
                },
                "color": {"value": "red"}
              }
            }
          ]
        },
        {
          "mark": "line",
          "encoding": {
            "x": {"field": "x3"},
            "y": {"field": "y3"},
            "color": {"value": "black"}
          }
        }
      ],
      "resolve": {"scale": {"y": "independent"}},
      "config": {}
    }
    

    Let me know if this was your expected outcome.