Can you have facets & layers in single Vegalite plot? - vega-lite

I am struggling to understand why a layer spec like the below:
"layer": [
{"encoding": {
"facet": {"field": "FEATURE_VALUE"},
"x": {
"field": "DATE",
"type": "temporal"
},
"y": {
"field": "VALUE",
"type": "quantitative"
}
},
"mark": {
"type": "line"
}}
]
Throws an error to the effect of: Cannot read property 'push' of undefined
Meanwhile, the unit spec:
"encoding": {
"facet": {"field": "FEATURE_VALUE"},
"x": {
"field": "DATE",
"type": "temporal"
},
"y": {
"field": "VALUE",
"type": "quantitative"
}
},
"mark": {
"type": "line"
}
}
works just fine.
I can tell this has something to do with: Altair: Can't facet layered plots
However, can't quite seem to answer the principle question: can I have a trellis plot using facet as well as have layers on top of that (for say tooltips, rulers, etc.)
Thank you!

Vega-Lite provides two ways to specify facets: as an encoding (See Facet, Row, and Column Encoding Channels) and as an operator (See Facet Operator).
A layer chart is not allowed to contain a facet encoding, however a facet operator can contain a layer chart (the reason for this is that the semantics of layers containing incompatible facets is unclear).
So, instead of something like this:
"layer": [
{"encoding": {
"facet": {"field": "FEATURE_VALUE"},
"x": {
"field": "DATE",
"type": "temporal"
},
"y": {
"field": "VALUE",
"type": "quantitative"
}
},
"mark": {
"type": "line"
}}
]
you can do something like this:
"facet": {"field": "FEATURE_VALUE"},
"spec": {
"layer": [
{"encoding": {
"x": {
"field": "DATE",
"type": "temporal"
},
"y": {
"field": "VALUE",
"type": "quantitative"
}
},
"mark": {
"type": "line"
}}
]
}

Related

How to share labels in faceted nested charts of "Vega Lite"?

I want to use "Vega Lite" to achieve the faceted nesting effect similar to tableau. Although "Vega Lite" can also be achieved, the display effect is not satisfactory, which is mainly reflected in that each sub chart has its own coordinate axis label, and the information density is not high. Tableau is much more compact.
This is an example of tableau:
This is an example of vega-lite:
{
"data": {"url": "https://uniplore-source.oss-cn-chengdu.aliyuncs.com/other/orders2.csv"},
"spacing": 0,
"facet": {"row": {"field": "快递方式","type": "nominal",
"header":{"labelExpr": "null"}
}},
"spec": {
"facet": {"column": {"field": "类别","type": "nominal","header":{"labelExpr": "null"}}},
"spacing": 0,
"spec": {
"spacing": 0,
"facet": {
"column": {
"field": "子类别","type": "nominal"
}
},
"spec": {
"facet": {
"column": {
"field": "细分","type": "nominal"
}
},
"spec": {
"mark": "bar",
"spacing": 0,
"encoding": {
"x": {
"field": "细分","type": "nominal"
},
"y": {"aggregate": "sum","field":"销售额"}
}
}
}
}
}
}
You can view my example here.
In fact, the same amount of information can not be displayed on one screen with Vega Lite.
I have tried some configurations, but the effect is not obvious.
I want to know if there is any way Vega Lite can achieve the display effect of tableau.
The most important of these is shared labels.
Thank you.
If you mean shared axes, then you can do this using facet.
https://vega.github.io/vega-lite/docs/facet.html
Edit 1
Editor
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"name": "trellis_barley",
"description": "The Trellis display by Becker et al. helped establish small multiples as a “powerful mechanism for understanding interactions in studies of how a response depends on explanatory variables”. Here we reproduce a trellis of Barley yields from the 1930s, complete with main-effects ordering to facilitate comparison.",
"data": {"url": "data/barley.json"},
"mark": "point",
"height": {"step": 12},
"encoding": {
"facet": {
"spacing": {"row": -40},
"field": "site",
"type": "ordinal",
"columns": 2,
"sort": {"op": "median", "field": "yield"},
"header":{"labelExpr": "null"}
},
"x": {
"aggregate": "median",
"field": "yield",
"type": "quantitative",
"scale": {"zero": false}
},
"y": {"field": "variety", "type": "ordinal", "sort": "-x"},
"color": {"field": "year", "type": "nominal"}
}
}

how to make marker for tooltip bigger

Here's my wandb vega. The problem is, right now, it is very hard to mouse over my line and get the tooltip to show. It is like you must hover over the exact pixel of the line with your mouse. How do I make the activation radius larger, so my tooltip shows up if I am approximately on top of the point of my line?
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A plot for an arbitrary number of lines",
"data": {
"name": "wandb"
},
"transform": [
{"filter": {"field": "${field:lineVal}", "valid": true}},
{"filter": {"field": "${field:step}", "valid": true}}
],
"title": "${string:title}",
"layer": [
{
"selection": {
"grid": {
"type": "interval",
"bind": "scales"
}
},
"mark": {"type": "line", "strokeWidth": 5, "interpolate": "linear", "tooltip": true},
"encoding": {
"x":{
"field": "${field:step}",
"type": "quantitative",
"title": "${string:xname}"
},
"y": {
"field": "${field:lineVal}",
"title": "y",
"type": "quantitative"
},
"color": {
"type": "nominal",
"field": "${field:lineKey}"
},
"strokeDash": {
"type": "nominal",
"field": "name"
}
}
}
]
}
You haven't provided the data along with your schema so it is difficult to answer your specific case. However, you should be able to adapt the example code from https://vega.github.io/vega-lite/examples/interactive_multi_line_pivot_tooltip.html to achieve what you want.

how to layer multiple regression lines without repeating code?

I'm using Vega Lite to chart the times at which I eat my meals, and want a regression (loess) line showing the general time for each. By default, a regression uses the entire dataset and only shows one line; I want three lines, one for each meal (stored in the field extra_data.content).
I've achieved what I want to do my repeating the loess layer three times (screenshot) but am trying to find a solution in which the same layer is written once and repeats itself three times.
Edit after solving! Thanks very much to #jakevdp for the answer! Here is my working code; note that there is both a groupby on the loess and a color channel.
{
"mark": "line",
"transform": [
{
"loess": "hm",
"on": "ymd",
"groupby": ["extra_data.content"]
}
],
"encoding": {
"x": {
"field": "ymd",
"type": "temporal"
},
"y": {
"field": "hm",
"type": "temporal"
},
"color": {
"field": "extra_data.content",
"type": "nominal"
}
}
}
It sounds like you want the groupby argument of the loess transform, along with a color encoding. It might look something like this:
{
"mark": "line",
"transform": [
{
"loess": "hm",
"on": "ymd",
"groupby": ["extradata.content"]
}
],
"encoding": {
"x": {
"field": "ymd",
"type": "temporal"
},
"y": {
"field": "hm",
"type": "temporal"
},
"color": {
"field": "extradata.content",
"type": "nominal"
}
}
}

plot small multiples in vega-lite with gray background

I'm looking for a vega-lite configuration to show small multiples (using the facet operator row or column) with all other data points greyed out in the background.
Here is an example plot using the facet-operator:
facet plot
in vega-editor
"facet": {
"row": {
"field": "group",
"type": "nominal"
}
},
And here is an example using multiple charts with the concat operator and color channel to grey out other groups:
concat-plot
in vega-editor
"color": {"condition": {"test": "datum['group'] != 1", "value": "grey"}, "value": "red"}
I was wondering if there is a combination of transforms and repeat commands to achieve this for an unknown number of groups.
Here is one possible solution:
create an additional layer with new data
"facet": {"row": {"field": "group"}},
"spec": {
"layer": [
{
"data": {"name": "main"},
"mark": "circle",
"encoding": {
"y": {
"field": "y",
"type": "ordinal"
},
"x": {
"field": "x",
"type": "ordinal"
},
"color": {"value": "grey"}
},
"params": []
},
{
"mark": {"type": "circle", "opacity": 1, "color": "red"},
"encoding": {
"y": {
"field": "y",
"type": "ordinal"
},
"x": {
"field": "x",
"type": "ordinal"
}
}
}
]
}
full example in vega editor

Is there a way to pass the aggregated value to the tooltip encoding on a simple histogram in Vega Lite

I would like to add the value of the count to the tooltip in the simple way to a simple histogram plot in Vega Lite?
Something like this:
{
"data": {
"url": "data/movies.json"
},
"mark": "bar",
"encoding": {
"tooltip": [
{
"field": "Count of Records",
"type": "quantitative"
}
],
"x": {
"bin": true,
"field": "IMDB_Rating",
"type": "quantitative"
},
"y": {
"aggregate": "count",
"type": "quantitative"
}
}
}
There does not seem to be a way to reference the aggregated y encoding in the tooltip encoding.
Tooltips are encodings just like any other; you can pass the same arguments to the tooltip that you do to the y encoding:
{
"data": {
"url": "data/movies.json"
},
"mark": "bar",
"encoding": {
"tooltip": [
{
"aggregate": "count",
"type": "quantitative"
}
],
"x": {
"bin": true,
"field": "IMDB_Rating",
"type": "quantitative"
},
"y": {
"aggregate": "count",
"type": "quantitative"
}
}
}
See it in action here.