Only show ticks at integer values in Vega Lite - vega

In a graph I'm making using Vega Lite, I'm seeing ticks at 0.5 steps, even though the data will only include integer values. Is there a way to set this in Vega Lite? I tried looking for something like "minimum tick step", or something similar in the docs, but I couldn't find anything like that.

There are a couple ways to do this, depending on what your situation is. For example, consider this chart:
{
"data": {
"values": [
{"x": 1, "y": 1},
{"x": 2, "y": 3},
{"x": 3, "y": 4},
{"x": 4, "y": 2}
]
},
"mark": "point",
"encoding": {
"x": {"type": "quantitative", "field": "x"},
"y": {"type": "quantitative", "field": "y"}
},
"width": 400
}
If all of your values are integers and you only care about integers, it might be that your data are better represented by ordinal values (i.e. ordered categorical data). If so, you can remove the ticks by specifying an ordinal type:
{
"data": {
"values": [
{"x": 1, "y": 1},
{"x": 2, "y": 3},
{"x": 3, "y": 4},
{"x": 4, "y": 2}
]
},
"mark": "point",
"encoding": {
"x": {"type": "ordinal", "field": "x"},
"y": {"type": "quantitative", "field": "y"}
},
"width": 400
}
If you want your data to be represented as quantitative, but just want to adjust the tick spacing, you can use the axis.tickMinStep property:
{
"data": {
"values": [
{"x": 1, "y": 1},
{"x": 2, "y": 3},
{"x": 3, "y": 4},
{"x": 4, "y": 2}
]
},
"mark": "point",
"encoding": {
"x": {"type": "quantitative", "field": "x", "axis": {"tickMinStep": 1}},
"y": {"type": "quantitative", "field": "y"}
},
"width": 400
}

Related

vega grouping difference for vertical and horizontal bar chart?

thanks in advance! I am trying to make a grouped bar chart with Vega. So I took the "stacked bar chart example" data (removed the stacking transform), and made a vertical one and horizontal one. The strange thing is, the horizontal one worked as I expected, but the vertical one has duplicated overlapping bars on each individual groups. I made them exactly the same way, only switching the properties. I will post my json file below.
Vertical bar chart:
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A basic stacked bar chart example.",
"width": 500,
"height": 200,
"padding": 5,
"data": [
{
"name": "table",
"values": [
{"x": 0, "y": 28, "c": 0}, {"x": 0, "y": 55, "c": 1},
{"x": 1, "y": 43, "c": 0}, {"x": 1, "y": 91, "c": 1},
{"x": 2, "y": 81, "c": 0}, {"x": 2, "y": 53, "c": 1},
{"x": 3, "y": 19, "c": 0}, {"x": 3, "y": 87, "c": 1},
{"x": 4, "y": 52, "c": 0}, {"x": 4, "y": 48, "c": 1},
{"x": 5, "y": 24, "c": 0}, {"x": 5, "y": 49, "c": 1},
{"x": 6, "y": 87, "c": 0}, {"x": 6, "y": 66, "c": 1},
{"x": 7, "y": 17, "c": 0}, {"x": 7, "y": 27, "c": 1},
{"x": 8, "y": 68, "c": 0}, {"x": 8, "y": 16, "c": 1},
{"x": 9, "y": 49, "c": 0}, {"x": 9, "y": 15, "c": 1}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"range": "width",
"domain": {"data": "table", "field": "c"}
},
{
"name": "yscale",
"type": "linear",
"range": "height",
"domain": {"data": "table", "field": "y"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "table", "field": "c"}
}
],
"axes": [
{"orient": "bottom", "scale": "xscale", "zindex": 1},
{"orient": "left", "scale": "yscale", "zindex": 1}
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "facet",
"data": "table",
"groupby": "c"
}
},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "c"}
}
},
"signals": [
{"name": "width", "update": "bandwidth('xscale')"}
],
"scales": [
{
"name": "inner",
"type": "band",
"range": "width",
"domain": {"data": "facet", "field": "x"}
}
],
"axes": [
{"orient": "top", "scale": "inner", "tickSize": 0, "labelPadding": 10, "zindex": 2, "title": "x"}
],
"marks": [
{
"type": "rect",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"scale": "inner", "field": "x"},
"width": {"scale": "inner", "band": 1, "offset": -1},
"y": {"scale": "yscale", "field": "y"},
"y2": {"scale": "yscale", "value": 0},
"fill": {"scale": "color", "field": "c"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
}
]
}]
}
Horizontal bar chart:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A basic stacked bar chart example.",
"width": 500,
"height": 200,
"padding": 5,
"data": [
{
"name": "table",
"values": [
{"x": 0, "y": 28, "c": 0}, {"x": 0, "y": 55, "c": 1},
{"x": 1, "y": 43, "c": 0}, {"x": 1, "y": 91, "c": 1},
{"x": 2, "y": 81, "c": 0}, {"x": 2, "y": 53, "c": 1},
{"x": 3, "y": 19, "c": 0}, {"x": 3, "y": 87, "c": 1},
{"x": 4, "y": 52, "c": 0}, {"x": 4, "y": 48, "c": 1},
{"x": 5, "y": 24, "c": 0}, {"x": 5, "y": 49, "c": 1},
{"x": 6, "y": 87, "c": 0}, {"x": 6, "y": 66, "c": 1},
{"x": 7, "y": 17, "c": 0}, {"x": 7, "y": 27, "c": 1},
{"x": 8, "y": 68, "c": 0}, {"x": 8, "y": 16, "c": 1},
{"x": 9, "y": 49, "c": 0}, {"x": 9, "y": 15, "c": 1}
]
}
],
"scales": [
{
"name": "y",
"type": "band",
"range": "height",
"domain": {"data": "table", "field": "c"}
},
{
"name": "x",
"type": "linear",
"range": "width",
"domain": {"data": "table", "field": "y"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "table", "field": "c"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{"type": "group",
"from": {
"facet": {
"name": "facet",
"data": "table",
"groupby": "c"
}
},
"encode": {
"enter": {
"y": {"scale": "y", "field": "c"}
}
},
"signals": [
{"name": "height", "update": "bandwidth('y')"}
],
"scales": [
{
"name": "pos",
"type": "band",
"range": "height",
"domain": {"data": "facet", "field": "x"}
}
],
"axes": [
{"orient": "right", "scale": "pos", "tickSize": 0, "labelPadding": 10, "zindex": 3}
],
"marks": [{
"type": "rect",
"from": {"data": "facet"},
"encode": {
"enter": {
"y": {"scale": "pos", "field": "x"},
"height": {"scale": "pos", "band": 1, "offset":-1},
"x": {"scale": "x", "field": "y"},
"x2": {"scale": "x", "value": 0},
"fill": {"scale": "color", "field": "c"}
}
}
}]
}]
}
Images:
Is this something I didn't setup correctly in the specs? Thanks.
I figured it out. The inner chart marks needs to be sourced from facet instead of the original table
"from": {"data": "facet"}
That fixed it.

multi-histogram plot with Vegalite

I would like to create single visual showing multiple histograms on it. I have simple arrays of values, like so:
"data": {"values": {"foo": [0,0,0,1,1,1,2,2,2], "baz": [2,2,2,3,3,3,4,4,4]}}
I want to use different color bars to show the spread of values for "foo" and "baz". I am able to make a single histogram for "foo" like so:
{
"data": {"values": {"foo": [0,0,0,1,1,1,2,2,2]}},
"mark": "bar",
"transform": [{"flatten": ["foo"]}],
"encoding": {
"x": {"field": "foo", "type": "quantitative"},
"y": {"field": "foo", "type": "quantitative", "aggregate": "count"}
}
}
However, I cannot find the correct way to flatten out the arrays. This doesn't work:
{
"data": {"values": {"foo": [0,0,0,1,1,1,2,2,2], "bar": [0,0,0,1,1,1,2,2,2]}},
"mark": "bar",
"transform": [{"flatten": ["foo", "baz"]}],
"encoding": {
"x": {"field": "foo", "type": "quantitative"},
"y": {"field": "foo", "type": "quantitative", "aggregate": "count"}
},
"layer": [{
"mark": "bar",
"encoding": {
"y": {"field": "baz", "type": "quantitative", "aggregate": "count"}
}
}]
}
https://vega.github.io/editor/#/url/vega-lite/N4IgJghgLhIFygG4QDYFcCmBneoBmA9gfANoAMANJZQIwV10BMFzjAuhSAEYQBep1KvWFMWLNgF8JnALYQATgGt43BSE5R5EAHZZC8maXwpoUDNtIhCxTj36SOIcwGMCYAJbaA5rhAAPXzx3DBQwFWt1ECgATwAHDBUARzQdKHcYNMQE6RBowODQ8KJImPiklO00jPcsyIgvL3kML2gEuBBXNEqQKU4TaIx5IxA5JRUeIc4XN08fBFz8kLD2uxK4tpBk1PToGoTOesbm1pVO7qkJSSA
Inspecting data_0, there is are columns for foo and its counts, but nothing for baz.
This doesn't work, either:
{
"data": {
"values": {
"foo": [0, 0, 0, 1, 1, 1, 2, 2, 2],
"baz": [0, 0, 0, 1, 1, 1, 2, 2, 2]
}
},
"mark": "bar",
"transform": [{"flatten": ["foo"]},{"flatten": ["baz"]}],
"encoding": {
"x": {"field": "foo", "type": "quantitative"},
"y": {"field": "foo", "type": "quantitative", "aggregate": "count"}
},
"layer": [
{
"mark": "bar",
"encoding": {
"y": {"field": "baz", "type": "quantitative", "aggregate": "count"}
}
}
]
}
https://vega.github.io/editor/#/url/vega-lite/N4IgJghgLhIFygG4QDYFcCmBneoBmA9gfANoAMANJZQIwV10BMFzjAuhSAEYQBep1KvWFMWLNgF8JnALYQATgGt43BSE5R5EAHZZC8maXwpoUDNtIhCxSRWOnzlnv0kcQ5gMYEwAS20BzXBAADyC8HwwUMBVrdRAoAE8ABwwVAEc0HSgfGGzEVOkQBLCIqJiiOMSU9MztbNyffLiIf395DH9oVLgQLzQ6kClOEwSMeSMQOSUVHnHOT28-QIQiksjonudK5O6QDKyc6EbUzha2jq6VPoGpCUkgA
That still only gives columns for foo and its count, but now the count is 27 for each bucket!
How can I accomplish a multi-histogram graphic starting with array data?
You can do this using a flatten transform followed by a fold transform, and then use a color encoding to separate the two datasets. For example (open in editor):
{
"data": {
"values": {
"foo": [0, 0, 1, 1, 1, 1, 2, 2, 2],
"baz": [4, 4, 5, 5, 6, 6, 6, 6, 7]
}
},
"transform": [{"flatten": ["foo", "baz"]}, {"fold": ["foo", "baz"]}],
"mark": "bar",
"encoding": {
"x": {"field": "value", "type": "quantitative"},
"y": {
"field": "value",
"type": "quantitative",
"aggregate": "count",
"stack": null
},
"color": {"field": "key", "type": "nominal"}
}
}
As an aside, your layer approach also works if you put the encodings in separate layers, so that the outer foo aggregate doesn't clobber the baz data, but it's a bit more verbose than the approach based on fold:
{
"data": {
"values": {
"foo": [0, 0, 1, 1, 1, 1, 2, 2, 2],
"baz": [4, 4, 5, 5, 6, 6, 6, 6, 7]
}
},
"transform": [{"flatten": ["foo", "baz"]}],
"layer": [
{
"mark": {"type": "bar", "color": "orange"},
"encoding": {
"x": {"field": "foo", "type": "quantitative"},
"y": {"field": "foo", "type": "quantitative", "aggregate": "count"}
}
},
{
"mark": "bar",
"encoding": {
"x": {"field": "baz", "type": "quantitative"},
"y": {"field": "baz", "type": "quantitative", "aggregate": "count"}
}
}
]
}

How to start bar from 1 instead of 0 in Vega Lite?

I'm plotting the diff time series [1.1, 0.9, 1.2, ...].
And as the values are relative multipliers, the middle is 1 and not 0.
Is there a way to tell Vega Lite to start bar with 1?
So for the value 1.1 the bar will be start: 1, end: 1.1 and for 0.9 it will be start: 1, end: 0.9?
You can use a y2 encoding with datum set to 1. For example (vega editor):
{
"data": {
"values": [
{"x": "A", "y": 0.9},
{"x": "B", "y": 0.8},
{"x": "C", "y": 1.1},
{"x": "D", "y": 1.2},
{"x": "E", "y": 0.9},
{"x": "F", "y": 1.3}
]
},
"mark": "bar",
"encoding": {
"x": {"type": "nominal", "field": "x"},
"y": {
"type": "quantitative",
"field": "y",
"scale": {"domain": [0.6, 1.4]}
},
"y2": {"datum": 1}
}
}

Highlight/bold label on vega chart axis

Is it possible to highlight certain labels on an axis?
My current encoding is:
"encoding": {
"x": { "field": "date", "type": "temporal", "axis": { "title": "Date", "grid": false } },
"y": { "field": "value", "type": "quantitative", "axis": { "format": "d" }
}
And I would like the days of the month (as opposed to the times) to be highlighted/bold so that they easily stand out. Would also like all of these day labels to include the month, rather than the day of the week, so instead of 'Mon 07' I get want 'Oct 07' as it is for 'Oct 06'. Is this possible?
You cannot change the font style conditioned on the label value, but you can use axis.labelExpr to change the value of the label depending on a condition.
The Line Chart With Conditional Axis Properties example in the Vega-Lite documentation shows one possible approach that is relevant to your question.
Here is an example of what you might do specifically for multi-day hourly data like yours (editor):
{
"mark": "line",
"encoding": {
"x": {
"type": "temporal",
"field": "x",
"axis": {
"tickCount": 12,
"labelAlign": "left",
"labelOffset": 2,
"labelExpr": "[timeFormat(datum.value, '%H:%M'), timeFormat(datum.value, '%H') == '00' ? timeFormat(datum.value, '%b %d') : '']"
}
},
"y": {"type": "quantitative", "field": "y"}
},
"width": 800,
"data": {
"values": [
{"x": "2020-01-01T00:00:00", "y": -0.29},
{"x": "2020-01-01T02:00:00", "y": -0.59},
{"x": "2020-01-01T04:00:00", "y": 0.12},
{"x": "2020-01-01T06:00:00", "y": -0.24},
{"x": "2020-01-01T08:00:00", "y": -0.34},
{"x": "2020-01-01T10:00:00", "y": -0.55},
{"x": "2020-01-01T12:00:00", "y": -0.02},
{"x": "2020-01-01T14:00:00", "y": 0.66},
{"x": "2020-01-01T16:00:00", "y": 1.51},
{"x": "2020-01-01T18:00:00", "y": 0.98},
{"x": "2020-01-01T20:00:00", "y": 0.06},
{"x": "2020-01-01T22:00:00", "y": 0.31},
{"x": "2020-01-02T00:00:00", "y": 0.42},
{"x": "2020-01-02T02:00:00", "y": 0.56},
{"x": "2020-01-02T04:00:00", "y": 1.05},
{"x": "2020-01-02T06:00:00", "y": 1.1},
{"x": "2020-01-02T08:00:00", "y": 1.93},
{"x": "2020-01-02T10:00:00", "y": 2.12},
{"x": "2020-01-02T12:00:00", "y": 1.41},
{"x": "2020-01-02T14:00:00", "y": 2.22},
{"x": "2020-01-02T16:00:00", "y": 2.99},
{"x": "2020-01-02T18:00:00", "y": 3.51},
{"x": "2020-01-02T20:00:00", "y": 4.02},
{"x": "2020-01-02T22:00:00", "y": 1.92},
{"x": "2020-01-03T00:00:00", "y": 2.05},
{"x": "2020-01-03T02:00:00", "y": 2.19},
{"x": "2020-01-03T04:00:00", "y": 2.28},
{"x": "2020-01-03T06:00:00", "y": 3.15},
{"x": "2020-01-03T08:00:00", "y": 2.8},
{"x": "2020-01-03T10:00:00", "y": 2.66},
{"x": "2020-01-03T12:00:00", "y": 3.16},
{"x": "2020-01-03T14:00:00", "y": 3.28},
{"x": "2020-01-03T16:00:00", "y": 3.06},
{"x": "2020-01-03T18:00:00", "y": 2.63},
{"x": "2020-01-03T20:00:00", "y": 1.53},
{"x": "2020-01-03T22:00:00", "y": 1.16},
{"x": "2020-01-04T00:00:00", "y": 1.45},
{"x": "2020-01-04T02:00:00", "y": -0.51},
{"x": "2020-01-04T04:00:00", "y": -1.04},
{"x": "2020-01-04T06:00:00", "y": -1.95},
{"x": "2020-01-04T08:00:00", "y": -2.57},
{"x": "2020-01-04T10:00:00", "y": -2.65},
{"x": "2020-01-04T12:00:00", "y": -3.39},
{"x": "2020-01-04T14:00:00", "y": -3.296},
{"x": "2020-01-04T16:00:00", "y": -2.45},
{"x": "2020-01-04T18:00:00", "y": -2.44},
{"x": "2020-01-04T20:00:00", "y": -2.14},
{"x": "2020-01-04T22:00:00", "y": -0.82},
{"x": "2020-01-05T00:00:00", "y": 0.3},
{"x": "2020-01-05T02:00:00", "y": 1.04}
]
}
}

Vega Visualization Custom Axis orientation

I am making the following graph of temperature over time using Vega Visualization Grammar. I am currently using area plot.
X-axis - time
y-axis - temperature (Starting from -40 to 80)
I need the x-axis to start from 0 instead of -40.
Following is the vega Json:
var tempdata = {
"width": 250,
"height": 150,
"background": "#FFF",
"padding": {"top": 10, "left": 30, "bottom": 30, "right": 10},
"data": [
{
"name": "table",
"values": [
{"x": 1, "y": -40}, {"x": 2, "y": -30},
{"x": 3, "y": -10}, {"x": 4, "y": -4},
{"x": 5, "y": -1}, {"x": 6, "y": 0},
{"x": 7, "y": -5}, {"x": 8, "y": -2},
{"x": 9, "y": 20}, {"x": 10, "y": 20},
{"x": 11, "y": 24}, {"x": 12, "y": 12},
{"x": 13, "y": 50}, {"x": 14, "y": 30},
{"x": 15, "y": 15}, {"x": 16, "y": 60},
{"x": 17, "y": 60}, {"x": 18, "y": 80},
{"x": 19, "y": 70}, {"x": 20, "y": 70},
{"x": 21, "y": 72}, {"x": 22, "y": 75},
{"x": 23, "y": 60}, {"x": 24, "y": 60}
]
}
],
"scales": [
{
"name": "x",
"type": "linear",
"range": "width",
"zero": false,
"domain": {"data": "table", "field": "x"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"domain": {"data": "table", "field": "y"}
}
],
"axes": [
{
"type": "x",
"scale": "x",
"properties": {
"ticks": {
"stroke": {"value": "#000"}
},
"labels": {
"fill": {"value": "#000"}
},
"axis": {
"stroke": {"value": "#000"},
"strokeWidth": {"value": 1.5}
}
}
},
{
"type": "y",
"scale": "y",
"properties": {
"ticks": {
"stroke": {"value": "#000"}
},
"labels": {
"fill": {"value": "#000"}
},
"axis": {
"stroke": {"value": "#000"},
"strokeWidth": {"value": 1.5}
}
}
}
],
"marks": [
{
"type": "area",
"from": {"data": "table"},
"properties": {
"enter": {
"interpolate": {"value": "monotone"},
"x": {"scale": "x", "field": "x"},
"y": {"scale": "y", "field": "y"},
"y2": {"scale": "y", "value": 0},
"fill": {"value": "#A41600"},
"stroke": {"value": "#FFF"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
}
]
};
From what you've written I suppose you want the y-Axis to start from 0 to 80, not the x-Axis, as you have stated (because the x-Axis does not include -40).
A possible approach would be to remove the data which violates your condition, so in other words: Removing every datum which has a y-Value smaller than 0.
You can achieve this by adding a data transform of type filter to the toplevel data-property in the following way:
"transform":
[
{
"type": "filter",
"test": "datum.y >= 0"
}
]
This will remove every datum which has a y-Value smaller than 0 and then you can proceed normally.
Make sure to enter above code in the toplevel-property data.
P.S. Feel free to edit by highlighting/ underlining anything as this is my first post and eventually will contain flaws :).