Vega-lite: resolve within a facet leads to Unrecognized scale name

Created on 15 Dec 2018  路  14Comments  路  Source: vega/vega-lite

The following spec leads to an error (editor link)

Error: Unrecognized scale name: "child_layer_0_y"
{
  "data": {
    "url": "https://vega.github.io/vega-datasets/data/seattle-weather.csv"
  },
  "facet": {
    "column": {
      "field": "weather",
      "type": "nominal"
    }
  },
  "spec": {
    "layer": [
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "temp_max",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "salmon",
          "type": "line"
        }
      },
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "precipitation",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "steelblue",
          "type": "line"
        }
      }
    ],
    "resolve": {
      "scale": {
        "y": "independent"
      }
    }
  }
}

What I expect is that it would behave just like the following spec, except with independent y axis within each facet:

{
  "data": {
    "url": "https://vega.github.io/vega-datasets/data/seattle-weather.csv"
  },
  "facet": {
    "column": {
      "field": "weather",
      "type": "nominal"
    }
  },
  "spec": {
    "layer": [
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "temp_max",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "salmon",
          "type": "line"
        }
      },
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "precipitation",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "steelblue",
          "type": "line"
        }
      }
    ]
  }
}

(editor link)
visualization 18

Related to https://stackoverflow.com/questions/53787262/vega-lite-independent-scale-with-multiple-layers-and-facet

Area - View Composition Bug P2

Most helpful comment

[Summary: Got some of the goals ticked, but still not quite the graph that I'm after]

I managed to get the separate scales for each axis working for the 2 separate marks while keeping them in sync across all facets:
visualization

The trick is to specify 2 levels of resolve separately, one "inside" the spec of the facet (i.e. at the same level as the layer) and the other one "outside" (i.e. same level with) the spec of the facet:

image

Here is the full code:

{
    "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
    "data":{
        "url": "data/cars.json"
    },
    "facet":{
        "column": {
            "field":"Origin",
            "type": "nominal"
        }
    },
    "spec":{
        "layer": [
            {
                "mark": {
                    "type": "bar",
                    "clip": true,
                    "tooltip": true
                },
                "encoding": {

                    "x": {
                        "field": "Cylinders",
                        "type": "ordinal"
                    },
                    "y": {
                        "field": "Acceleration",
                        "type": "quantitative",
                        "aggregate":"average",
                        "axis": {
                            "title": "Acceleration",
                            "orient": "left"
                        }
                    },
                    "color": {
                        "field": "Cylinders",
                        "type": "nominal",
                        "legend":null
                    }
                }
            },
            {
                "mark": {
                    "type": "line",
                    "clip": true,
                    "color":"#ffde25",
                    "tooltip": true
                },
                "encoding": {
                    "x": {
                        "field": "Cylinders",
                        "type": "ordinal"
                    },
                    "y": {
                        "field": "Weight_in_lbs",
                        "type": "quantitative",
                        "aggregate":"average",
                        "axis": {
                            "title": "Weight (lbs)",
                            "orient": "right"
                        }
                    }

                }
            }
        ],
        "resolve": {
            "scale": {"y": "independent"}
        }
    },
    "resolve": {
        "scale": {"y": "shared"},
        "axis": {"y": "independent"}
    }

}

So it sort of works, but it is still not quite the right graph.

Would anyone have any idea on how to keep scales of the mark independent but have the axis shared? (i.e. what I want is similar to the graph I already shown above, but I only want 1 "Acceleration" axis on the left and 1 "Weight" axis on the right of the main plot area which contains all of the column facets)

I already tried to set the "axis" option of the outer "resolve" to be {"y": "shared"}, but it results in an error:
Error: Unrecognized scale name: "child_layer_0_y"

If that is not possible at this stage, then I hope what I listed above helps demonstrate the problem with this bug a little bit clearer.

Any help would be appreciated.

Thanks.

All 14 comments

This is a bug. Thanks for the report!

Ahh, so the problem is that the scales are defined inside each cell (which makes sense since they should be independent) but the header is defined outside and references a wrong scale.

Hmm, I wonder why Vega-Lite does not automatically also make the axes independent.

Something is wrong with layers inside facet. With just facet, it works.

{
  "data": {
    "url": "https://vega.github.io/vega-datasets/data/seattle-weather.csv"
  },
  "facet": {
    "column": {
      "field": "weather",
      "type": "nominal"
    }
  },
  "spec": {
    "encoding": {
      "x": {
        "field": "date",
        "timeUnit": "month",
        "type": "temporal"
      },
      "y": {
        "aggregate": "mean",
        "field": "precipitation",
        "type": "quantitative"
      }
    },
    "mark": {
      "color": "steelblue",
      "type": "line"
    }
  },
  "resolve": {
    "scale": {
      "y": "independent"
    }
  }
}

As soon as we use a layer, it breaks:

{
  "data": {
    "url": "https://vega.github.io/vega-datasets/data/seattle-weather.csv"
  },
  "facet": {
    "column": {
      "field": "weather",
      "type": "nominal"
    }
  },
  "spec": {
    "layer": [{
      "encoding": {
        "x": {
          "field": "date",
          "timeUnit": "month",
          "type": "temporal"
        },
        "y": {
          "aggregate": "mean",
          "field": "precipitation",
          "type": "quantitative"
        }
      },
      "mark": {
        "color": "steelblue",
        "type": "line"
      }
    }],
    "resolve": {
      "scale": {
        "y": "independent"
      }
    }
  }
}

Ahh, what you want is this (move the resolve one up).

{
  "data": {
    "url": "https://vega.github.io/vega-datasets/data/seattle-weather.csv"
  },
  "facet": {
    "column": {
      "field": "weather",
      "type": "nominal"
    }
  },
  "spec": {
    "layer": [
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "temp_max",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "salmon",
          "type": "line"
        }
      },
      {
        "encoding": {
          "x": {
            "field": "date",
            "timeUnit": "month",
            "type": "temporal"
          },
          "y": {
            "aggregate": "mean",
            "field": "precipitation",
            "type": "quantitative"
          }
        },
        "mark": {
          "color": "steelblue",
          "type": "line"
        }
      }
    ]
  },
  "resolve": {
    "scale": {
      "y": "independent"
    }
  }
}

@jakevdp Your original spec would result in dual-axis charts for each facet. I don't think we should crash but at least we know what the right spec is.

I don't think I really want to support faceted dual-axis charts so I'm inclined to just add a warning and drop the resolve in the original spec.

@kanitw @arvind what do you think?

@jakevdp Your original spec would result in dual-axis charts for each facet.

As I read it, that was the intent of the person asking the SO question.

I see. Maybe it's not too hard to support it. It just wasn't one of the things I had tested when I wrote the resolve code.

Perhaps an hconcat + filter would be a good workaround? I haven't checked if that works.

Yeah, the concat workaround is fine here: vega editor

I don't think I really want to support faceted dual-axis charts so I'm inclined to just add a warning and drop the resolve in the original spec.

May I know if this decision has remain unchanged? Will faceted dual axis charts be supported in the future?

Will faceted dual axis charts be supported in the future?

Yes, after the 4.0 release, I plan to spend some time on the dataflow code to fix issues like this. If anyone wants to help, please do.

[Summary: Got some of the goals ticked, but still not quite the graph that I'm after]

I managed to get the separate scales for each axis working for the 2 separate marks while keeping them in sync across all facets:
visualization

The trick is to specify 2 levels of resolve separately, one "inside" the spec of the facet (i.e. at the same level as the layer) and the other one "outside" (i.e. same level with) the spec of the facet:

image

Here is the full code:

{
    "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
    "data":{
        "url": "data/cars.json"
    },
    "facet":{
        "column": {
            "field":"Origin",
            "type": "nominal"
        }
    },
    "spec":{
        "layer": [
            {
                "mark": {
                    "type": "bar",
                    "clip": true,
                    "tooltip": true
                },
                "encoding": {

                    "x": {
                        "field": "Cylinders",
                        "type": "ordinal"
                    },
                    "y": {
                        "field": "Acceleration",
                        "type": "quantitative",
                        "aggregate":"average",
                        "axis": {
                            "title": "Acceleration",
                            "orient": "left"
                        }
                    },
                    "color": {
                        "field": "Cylinders",
                        "type": "nominal",
                        "legend":null
                    }
                }
            },
            {
                "mark": {
                    "type": "line",
                    "clip": true,
                    "color":"#ffde25",
                    "tooltip": true
                },
                "encoding": {
                    "x": {
                        "field": "Cylinders",
                        "type": "ordinal"
                    },
                    "y": {
                        "field": "Weight_in_lbs",
                        "type": "quantitative",
                        "aggregate":"average",
                        "axis": {
                            "title": "Weight (lbs)",
                            "orient": "right"
                        }
                    }

                }
            }
        ],
        "resolve": {
            "scale": {"y": "independent"}
        }
    },
    "resolve": {
        "scale": {"y": "shared"},
        "axis": {"y": "independent"}
    }

}

So it sort of works, but it is still not quite the right graph.

Would anyone have any idea on how to keep scales of the mark independent but have the axis shared? (i.e. what I want is similar to the graph I already shown above, but I only want 1 "Acceleration" axis on the left and 1 "Weight" axis on the right of the main plot area which contains all of the column facets)

I already tried to set the "axis" option of the outer "resolve" to be {"y": "shared"}, but it results in an error:
Error: Unrecognized scale name: "child_layer_0_y"

If that is not possible at this stage, then I hope what I listed above helps demonstrate the problem with this bug a little bit clearer.

Any help would be appreciated.

Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mcnuttandrew picture mcnuttandrew  路  3Comments

mcnuttandrew picture mcnuttandrew  路  3Comments

kanitw picture kanitw  路  3Comments

learnwithratnesh picture learnwithratnesh  路  4Comments

ijlyttle picture ijlyttle  路  3Comments