Add additional tick to allow some space between the data points and the borders] - vega-lite

See the attached screenshot
Desire is to allow some offset between the data points and the border of the chart. Especially useful for user interactions such as brush to allow users to start brushing from the right side.
I think fall back plan is to manually compute the scale domain (min, max + some padding), but I was trying to see if there is already a prebuilt option available.
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A scatterplot showing horsepower and miles per gallons for various cars.",
"data": {
"values": [
{"Horsepower": 10, "Miles_per_Gallon": 100},
{"Horsepower": 10, "Miles_per_Gallon": 120},
{"Horsepower": 8, "Miles_per_Gallon": 77},
{"Horsepower": 6, "Miles_per_Gallon": 80},
{"Horsepower": 4, "Miles_per_Gallon": 20},
{"Horsepower": 2, "Miles_per_Gallon": 60},
{"Horsepower": 0, "Miles_per_Gallon": 150}
]
},
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"}
}
}

I don't know of a built-in configuration to add padding to the automatically-determined scale domain, but here's a hack that lets you achieve this by plotting a transparent point at a specified position past the maximum:
{
"data": {
"values": [
{"Horsepower": 10, "Miles_per_Gallon": 100},
{"Horsepower": 10, "Miles_per_Gallon": 120},
{"Horsepower": 8, "Miles_per_Gallon": 77},
{"Horsepower": 6, "Miles_per_Gallon": 80},
{"Horsepower": 4, "Miles_per_Gallon": 20},
{"Horsepower": 2, "Miles_per_Gallon": 60},
{"Horsepower": 0, "Miles_per_Gallon": 150}
]
},
"layer": [
{
"mark": {"type": "point", "opacity": 0},
"transform": [
{
"aggregate": [
{"field": "Horsepower", "op": "max", "as": "max_Horsepower"}
]
},
{"calculate": "datum.max_Horsepower + 2", "as": "max_Horsepower"}
],
"encoding": {"x": {"field": "max_Horsepower", "type": "quantitative"}}
},
{
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"}
}
}
]
}

Related

How to set different colors area chart depending on value Vega Lite

I want to create area chart in which area above y=0 will be one color anb below - another. I have a problem with setting conditional color in Vega-Lite. (I'm using guide from https://vega.github.io/vega-lite/docs/condition.html)
"color": {
"condition": {
"test": "datum['y'] < 0",
"value": {
"x1": 1,
"y1": 1,
"x2": 1,
"y2": 0,
"gradient": "linear",
"stops": [
{
"offset": 0,
"color": "white"
},
{
"offset": 1,
"color": "orange"
}
]
}
},
"value": {
// otherValue
}
Full code here:
https://codesandbox.io/s/interactive-vega-lite-bar-chart-forked-b0hnh?file=/index.html
The condition is not working on mark area. Tried the same for type bar or point and it worked. Still managed to get the gradient effect with colors red, white and orange. You can refer the below config or refer link:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Google's stock price over time.",
"data": {
"values": [
{"date": "2021-03-29", "value": -10, "rValue": 0},
{"date": "2021-03-28", "value": -20, "rValue": 0},
{"date": "2021-03-27", "value": 20, "rValue": 0},
{"date": "2021-03-26", "value": 40, "rValue": 0},
{"date": "2021-03-25", "value": 35, "rValue": 0}
]
},
"width": 400,
"height": 200,
"mark": {"type": "area"},
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"axis": {"format": "%d/%m/%Y", "labelPadding": 10}
},
"y": {"field": "value", "type": "quantitative"},
"fill": {
"value": {
"gradient": "linear",
"stops": [
{"offset": 0, "color": "red"},
{"offset": 0.5, "color": "white"},
{"offset": 1, "color": "orange"}
]
}
}
},
"config": {}
}
Also, I tried your mark area with a simple configuration and that didn't work. I have created a config having bar which works properly with condition but if the same is changed to area than it does not work.
One way to do this is to overlay a separate layer.
However I'm not sure how to color the bit before the first negative value.
Open the Chart in the Vega Editor

Sort the stack segments of barchart

I played with stacked bar charts and wanted to create the Spanish flag with Vega Lite.
I specified the stripes height and color in the data but don't manage to sort the individual stacks:
I set the scale to null, so that the color is taken from the specified field.
I encoded the position of the stripe in the pos attribute, and want to sort the segements by that.
I've also tried to slightly vary the color of the red stripes, but that didn't help.
Spec:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Fun with Flags",
"data": {
"values": [
{"h": 5, "color": "#aa151b", "pos": 6, "country": "spain"},
{"h": 5, "color": "#f1bf00", "pos": 4, "country": "spain"},
{"h": 5, "color": "#aa152b", "pos": 2, "country": "spain"}
]
},
"width": {"step": 300},
"mark": {"type": "bar"},
"encoding": {
"x": {"field": "country", "type": "nominal"},
"y": {"field": "h", "type": "quantitative"},
"color": {
"field": "color",
"scale": null,
"type": "nominal",
"sort": {"field": "pos", "op": "min", "order": "descending"}
}
}
}
Here's a link to the Vega Editor with the Spec.
Instead of sorting the color encoding, I had to specify the order channel, as described in the docs.
This gives me the following spec:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Fun with Flags",
"data": {
"values": [
{"h": 5, "color": "#aa152b", "pos": 6, "country": "spain"},
{"h": 5, "color": "#f1bf00", "pos": 4, "country": "spain"},
{"h": 5, "color": "#aa152b", "pos": 2, "country": "spain"}
]
},
"width": {"step": 300},
"mark": {"type": "bar"},
"encoding": {
"x": {"field": "country", "type": "nominal"},
"y": {"field": "h", "type": "quantitative"},
"color": {
"field": "color",
"scale": null,
"type": "nominal"
},
"order": {
"field": "pos",
"type": "quantitative"
}
}
}
And correct Spanish flag:
Link to Vega Editor

Plot multiple "columns" with VEGA-LITE and include a legend

I have the following minimal data:
[
{"date": "2019-01-01", "foo": 10000, "bar": 10, "goo": 30},
{"date": "2019-01-02", "foo": 30000, "bar": 20, "goo": 20},
{"date": "2019-01-03", "foo": 40000, "bar": 20, "goo": 10},
{"date": "2019-01-04", "foo": 1000, "bar": 60, "goo": 20}
]
Which I plot using VEGA-LITE:
<!DOCTYPE html>
<html>
<head>
<title>Embedding Vega-Lite</title>
<script src="https://cdn.jsdelivr.net/npm/vega#5.4.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#3.3.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#4.2.0"></script>
</head>
<body>
<div id="vis"></div>
<script type="text/javascript">
var yourVlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"Title": "Insights stats",
"description": "Overview of insights stats",
"width": 1000,
"height": 450,
"data": {
"url": "./data.json"
},
"layer": [
{
"mark": "line",
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"title": "Date"
},
"y": {
"field": "foo",
"type": "quantitative",
"title": "Some Foo"
}
}
},
{
"mark": {
"type": "line",
"stroke": "firebrick"
},
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {
"field": "bar",
"type": "quantitative",
"title": null,
"scale": { "domain": [0, 100] }
}
}
},
{
"mark": {
"type": "line",
"stroke": "red"
},
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {
"field": "goo",
"type": "quantitative",
"title": "Ratio (%)",
"scale": { "domain": [0, 100] }
}
}
}
],
"resolve": { "scale": { "y": "independent" } }
};
vegaEmbed('#vis', yourVlSpec);
</script>
</body>
</html>
I fail to have a proper legend for each line. What am I missing?
Vega-Lite will generate a legend for a chart if there is an encoding that warrants it, such as color, shape, etc.
In the case of plotting multiple columns, a useful pattern is to use the Fold Transform in order to specify your colors via an encoding rather than by manual layering. The result looks something like this (vega editor link):
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"title": "Insights stats",
"description": "Overview of insights stats",
"width": 1000,
"height": 450,
"data": {
"values": [
{"date": "2019-01-01", "foo": 10, "bar": 10, "goo": 30},
{"date": "2019-01-02", "foo": 30, "bar": 20, "goo": 20},
{"date": "2019-01-03", "foo": 40, "bar": 20, "goo": 10},
{"date": "2019-01-04", "foo": 1, "bar": 60, "goo": 20}
]
},
"transform": [
{"fold": ["foo", "bar", "goo"]}
],
"mark": "line",
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "value", "type": "quantitative"},
"color": {"field": "key", "type": "nominal"}
}
}

Plot two "columns" of data having two different orders of magnitude using vega-lite

(This is a follow up on this question)
Assume my data looks like:
[
{"date": "2019-01-01", "foo": 10000, "bar": 10, "goo": 30},
{"date": "2019-01-02", "foo": 30000, "bar": 20, "goo": 20},
{"date": "2019-01-03", "foo": 40000, "bar": 20, "goo": 10},
{"date": "2019-01-04", "foo": 20000, "bar": 60, "goo": 20}
]
And my plot is:
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"description": "Stock prices of 5 Tech Companies over Time.",
"width": 1200,
"height": 450,
"data": { "url": "data.json" },
"mark": {
"type": "line",
"point": true
},
"transform": [
{ "fold": ["foo", "bar", "goo"] }
],
"encoding": {
"x": { "field": "date", "type": "temporal" },
"y": { "field": "value", "type": "quantitative" },
"color": { "field": "key", "type": "nominal" },
"scale": {"zero": false}
},
"resolve": { "scale": { "y": "independent" } }
}
As you can see, due to the different order of magnitude of foo and the other two columns, the plot is not helpful. How can I have a secondary y-axis and (mention it in the legend)?
You can do that by combining layering with the fold transform. Here is how you might modify your example (vega editor link):
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"width": 1200,
"height": 450,
"data": {
"values": [
{"date": "2019-01-01", "foo": 10000, "bar": 10, "goo": 30},
{"date": "2019-01-02", "foo": 30000, "bar": 20, "goo": 20},
{"date": "2019-01-03", "foo": 40000, "bar": 20, "goo": 10},
{"date": "2019-01-04", "foo": 20000, "bar": 60, "goo": 20}
]
},
"transform": [{"fold": ["foo", "bar", "goo"]}],
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "value", "type": "quantitative"},
"color": {"field": "key", "type": "nominal"}
},
"layer": [
{
"mark": {"type": "line", "point": true},
"transform": [{"filter": "datum.key == 'foo'"}]
},
{
"mark": {"type": "line", "point": true},
"transform": [{"filter": "datum.key != 'foo'"}]
}
],
"resolve": {"scale": {"y": "independent"}}
}
You could then go on to modify the axis titles by specifying the y encoding & title within each layer. Here is an example (vega editor link):
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"width": 1200,
"height": 450,
"data": {
"values": [
{"date": "2019-01-01", "foo": 10000, "bar": 10, "goo": 30},
{"date": "2019-01-02", "foo": 30000, "bar": 20, "goo": 20},
{"date": "2019-01-03", "foo": 40000, "bar": 20, "goo": 10},
{"date": "2019-01-04", "foo": 20000, "bar": 60, "goo": 20}
]
},
"transform": [{"fold": ["foo", "bar", "goo"]}],
"encoding": {
"x": {"field": "date", "type": "temporal"},
"color": {"field": "key", "type": "nominal"}
},
"layer": [
{
"mark": {"type": "line", "point": true},
"encoding": {
"y": {"field": "value", "type": "quantitative", "title": "Foo Value"}
},
"transform": [{"filter": "datum.key == 'foo'"}]
},
{
"mark": {"type": "line", "point": true},
"encoding": {
"y": {
"field": "value",
"type": "quantitative",
"title": "Bar/Goo Value"
}
},
"transform": [{"filter": "datum.key != 'foo'"}]
}
],
"resolve": {"scale": {"y": "independent"}}
}

Why are tooltip values rounded?

For some reason my tooltips are rounded to the nearest integer?
Any help is appreciated.
Here is the link to chart in the VL editor (version 3.0.0-rc14).
(vega editor link)
{
"width": 300,
"height": 300,
"config": {
"title": {"fontSize": 15},
"numberFormat": ".0f",
"style": {
"bar": {"size": 20},
"guide-title": {"value": "asdf", "fontSize": 15},
"guide-label": {"fontSize": 15}
},
"scale": {"bandPaddingInner": 0.5, "bandPaddingOuter": 0.5},
"legend": {"symbolSize": 100, "titleFontSize": 15, "labelFontSize": 15},
"axis": {"titleFontSize": 15, "labelFontSize": 15, "labelLimit": 1000}
},
"data": {"name": "data-dba50c8bae540866b10e6763560b8ec9"},
"mark": "circle",
"encoding": {
"tooltip": [
{"type": "quantitative", "field": "expressiveness"},
{"type": "quantitative", "field": "customization"}
],
"x": {"type": "quantitative", "field": "expressiveness"},
"y": {"type": "quantitative", "field": "customization"}
},
"$schema": "https://vega.github.io/schema/vega-lite/v2.6.0.json",
"datasets": {
"data-dba50c8bae540866b10e6763560b8ec9": [
{"library": "A", "expressiveness": 0, "customization": 1},
{"library": "B", "expressiveness": 0.4, "customization": 0.7},
{"library": "C", "expressiveness": 1, "customization": 0.7},
{"library": "D", "expressiveness": 0.6, "customization": 0.7},
{"library": "E", "expressiveness": 0, "customization": 1}
]
}
}
Because you set "numberFormat": ".0f" in the config, and that's applied to the tooltip too.