Set domainMax to max of brushed values - vega-lite

I am working with the Overview and Detail Vega-Lite sample at https://vega.github.io/vega-lite/examples/interactive_overview_detail.html
I would like the Detail chart to dynamically adjust the y-axis to reflect the brushed values in the Overview chart, not the entire dataset. So when I select this valley in 2009, I want the y-axis on the Detail chart to be more like 1000 than 1500.
So for this modified sample, how do I dynamically set domainMax based on the brushed data?
"y": {
"field": "price",
"type": "quantitative",
"scale": {"domainMax": 1000}
}
Open the Chart in the Vega Editor

The right way to zoom in is to use "scale": {"zero": false} but you also have to set "stack": false. According to guru #jakevdp here, each area has an implicit stacked zero-height area for the group that does not appear but affects the automatically chosen axis limits.
"y": {
"field": "price",
"type": "quantitative",
"stack": false,
"scale": {
"zero": false
}
}
Open the Chart in the Vega Editor

Related

How to draw vertical lines based on a different quantity than that for the x channel in charts by row channel?

I'd like to have multiple time series drawn by row channel ("field": "PLATFORM"), x channel: ("field": "estimating-date-time"), and y channel ("field": "eta-variance").
Besides the lines of time series, I'd like to draw a vertical line at x = arrvial-time which is another field, conditioned by the value of "PLATFORM".
The following is a working example of the charts except the desirable vertical line in each chart:
vega-lite for multiple time series
Below is the desired effect with manual illustration:
My question is how to add the vertical line for each chart to the specifications?
The challenge to me is that the field "arrival-time" from which the value used to draw the vertical line is not the same as the chart's x channel "estimating-data-time". I've found examples of drawing such a line using a value related to the same x channel.
You can do this by nesting a layer specification within a facet operator; something like this (open in editor):
{
"facet": {"row": {"field": "PLATFORM"}},
"spec": {
"height": 80,
"width": 300,
"layer": [
{
"mark": "line",
"encoding": {
"x": {"field": "estimating-date-time", "type": "temporal"},
"y": {"field": "ETA-variance", "type": "quantitative"}
}
},
{
"mark": "rule",
"encoding": {"x": {"field": "arrival-time", "type": "temporal"}}
}
]
},
"data": {...}
}

Vega lite: How to change value labels

I could not found out way how to change labels of X axis.
I have this data and I need to show bars which have title taken from field label. Currently bars are aggregated by id and goals is to label bars with label even if the texts are same. I'm confused by examples what to do. Whether I should create layer or some signals. Could someone help me? IMHO this should be trivial, but I did not found anything useful.
{
"id": 15971,
"label": "Click Next to continue",
"result": "Success",
"value": 2
},
{
"id": 15972,
"label": "Click Next to continue",
"result": "No data",
"value": 0
},
There's not really any way to do this in the Vega-Lite grammar, because what you want to do is semantically inconsistent: if you group values by one column, there is no guarantee that the values in another column will match within that grouping.
One option you have is to use labelExpr to define the desired label manually, e.g.
"x": {
"field": "id",
"type": "nominal",
"axis": {"title": "x", "labelExpr": "'Click Next to continue'"},
"scale": {"type": "point"}
},

Data-layout, layers and legends in vega-lite

I have a very simple situation, and I believe my solution is too complicated and there's a good chance I'm missing something. Say I have measures of time, positions (x,y,z), angles (roll, pitch, yaw) and speed. I want a simple visualization like I currently have where the speed plot can be used as "brush" to zoom dynamically into the first two graphs.
A small example of my plot in the vega-editor can be found here.
1. Can I use a different data-layout?
Right now, each point is an object
{
"pitch": -0.006149084584096612,
"roll": 0.0007914191778949736,
"speed": 4.747345444390669,
"time": 0.519741,
"x": -0.01731604791076788,
"y": 0.020068310429957575,
"yaw": 0.0038123065311157552,
"z": -0.016005977140476142
}
With many data-points, this is a lot of memory just for repeating column names. Much better would be to have the data in the form
{
"time": [t1, t2, t3, ...],
"x": [...],
...
}
but vega's "row first" representation doesn't allow for that. I already asked on Slack where someone suggested to use Fold and Pivot, but I'm not sure how to implement this. Is it possible to use data that are stored as arrays? I'm creating the data myself from a C++ program and I'm free to export a different representation easily. The only question is how do I make vega-lite understand?
2. Layers and legends.
If I had time-series data with an "indicator column", I could create plots that combine several graphs easily. Unfortunately, I don't have that and the only solution I found is to use layers. With this, I have to set the colours for different graphs explicitly (instead of using schemes) and I don't get a legend.
If layers are really to only option here to combine, e.g. x,y,z into one "Movement" plot, how can I get a legend for this plot that tells me red -> x, green -> y, and blue -> z?
The answer is "yes" to both of your questions.
The key to the first question is to pass the data in a dense format and use the Flatten Transform to expand it.
The key to the second question is to use a Fold Transform to turn multiple columns into an indicator plus a value.
Here is a demonstration of this for a single chart (open in editor):
{
"data": {
"values": [
{
"time": [1, 2, 3, 4],
"x": [5, 4, 5, 2],
"y": [2, 3, 2, 4],
"z": [1, 2, 1, 0]
}
]
},
"transform": [
{"flatten": ["time", "x", "y", "z"]},
{"fold": ["x", "y", "z"], "as": ["column", "value"]}
],
"mark": "line",
"encoding": {
"x": {"field": "time", "type": "quantitative"},
"y": {"field": "value", "type": "quantitative"},
"color": {"field": "column", "type": "nominal"}
}
}

Vega-lite default bar width strange

I'm seeing the following oddly styled chart. I understand I can explicitly change the padding etc., but the default vega-lite layout is usually pretty good. I'm confused what I'm doing that's leading to this sub-normal behavior. Thanks! Here is the code in the vega-lite editor
I understand that I can also change x's type to ordinal to make the styling better, though I'm not sure I understand still why it is the difference I see. I need the type to be quantitative so I get the min/max brush bound, as opposed to the set.
Also I actually do not even know how to manually set the bar width after reading the documentation here https://vega.github.io/vega-lite/docs/scale.html. If anyone might have a working example that would be great.
Thanks.
As #marcprux mentioned, there is pre-binned support so you don't have to repeat the bin transform here. However, currently the prebinned support requires both bin_start and bin_end.
For now you could modify the spec to derive a new bin_end field and use it with x2.
{
"data": ...
"transform": [{
"calculate": "datum.ShareWomen_bin+0.1",
"as": "ShareWomen_bin_end"
}],
"mark": "bar",
"encoding": {
"x": {"bin": {"binned": true, "step": 0.1}, "field": "ShareWomen_bin", "type": "quantitative", "title": "ShareWomen_bin"},
"x2": {"field": "ShareWomen_bin_end"},
"y": {"field": "count", "type": "quantitative"}
}
}
like this spec.
I can see that we shouldn't require deriving bin_end and thus have created an issue to track this feature request: https://github.com/vega/vega-lite/issues/6086.
Btw, the quantitative scale only affects the bar position.
To set the bar size directly, you can use size property in a mark definition:
mark: {type: "bar", size: 5}
Since you declare "x" as a quantitative field, there's no assumption that the points along the axis are evenly distributed. E.g., you could add in some data points in between the others:
{"ShareWomen_bin": 0.83, "count": 40, "is_overview": true},
{"ShareWomen_bin": 0.87, "count": 70, "is_overview": true},
and you would see them rendered in between the other bars:
As you mention, you can specify that the bars should be encoded as ordinal values. Another solution is to leave it as quantitative, but specify that it is binned, in which case the bars will also be rendered as if they were ordinal:
"x": {"field": "ShareWomen_bin", "type": "quantitative", "bin": true},
Since it appears that your data is already binned, you should read about how vega-lite supports pre-binned data: https://vega.github.io/vega-lite/docs/bin.html#binned

Is it possible to use facets and repeat operator for histograms?

I want to combine facet operators (row, column) along with the repeat operator to create 'small multiple' charts that display different data variables. This works for some types of charts (e.g. simple bar charts) but not others (i.e. histograms). For example, below I have modified the 'Horizontally repeated charts' example (https://vega.github.io/vega-lite/examples/repeat_histogram.html).
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"repeat": {"column": ["Horsepower","Miles_per_Gallon", "Acceleration"]},
"spec": {
"data": {"url": "data/cars.json"},
"mark": "bar",
"encoding": {
"row":{"field":"Origin", "type":"nominal"},
"x": {
"field": {"repeat": "column"},
"bin": true,
"type": "quantitative"
},
"y": {"aggregate": "count","type": "quantitative"}
}
}
}
I expect three rows, with each row showing histograms of cars from different countries. However, this code results in the error :
'Error: Undefined data set name: "scale_child_Miles_per_Gallon_child_main"'
I'm reasonably sure that this worked with Vega-Lite v2. Is there some reason that the aggregate / bin operator can't work with a combination of facets and repeats?