Related
I am trying to make a stacked barchart in Vega and have hit a wall where I swear that my code should work, based on the several examples I've been cross referencing, but instead I keep getting perfect axes...with no bars.
The way it's supposed to work in this example is that Alamo's "Operations" "Debt" and "Below Cap" should stack, with State Average having the same categories of data stacked in the same order next to it. Both should sum to the same level (1). The transformed data looks to be in good shape, as the y0/y1 and order are correct.
I initially assumed the problem is in the marks section since that's where the bars are defined but I can't identify what the issue is there, so now I'm wondering if it's something else. But I don't know what else to try.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A stacked bar chart describing ad valorem taxes in Texas community college districts.",
"width": 300,
"height": 300,
"padding": 5,
"background": "white",
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{
"name": "Operations (MO)",
"amount": 0.1078,
"district": "Alamo",
"sort": 1,
"y0": 0,
"y1": 0.1078
},
{
"name": "Debt (IS)",
"amount": 0.0414,
"district": "Alamo",
"sort": 2,
"y0": 0.1078,
"y1": 0.1492
},
{
"name": "Below Cap",
"amount": 0.8508,
"district": "Alamo",
"sort": 3,
"y0": 0.1492,
"y1": 1
},
{
"name": "Operations (MO)",
"amount": 0.152,
"district": "State Average",
"sort": 1,
"y0": 0,
"y1": 0.152
},
{
"name": "Debt (IS)",
"amount": 0.027,
"district": "State Average",
"sort": 2,
"y0": 0.152,
"y1": 0.179
},
{
"name": "Below Cap",
"amount": 0.821,
"district": "State Average",
"sort": 3,
"y0": 0.179,
"y1": 1
}
],
"format": {"type": "json"},
"transform": [
{
"type": "stack",
"groupby": ["district"],
"sort": {"field": "sort"},
"field": "amount"
}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"range": "width",
"domain": {"data": "source_0", "field": "district"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": true,
"domain": {"data": "source_0", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "source_0", "field": "name"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{
"type": "rect",
"from": {"data": "source_0"},
"encode": {
"enter": {
"x": {"scale": "x", "field": "district"},
"width": {"scale": "x", "band": 1},
"y": {"scale": "y", "field": "y1"},
"y2": {"scale": "y", "value": "y0"},
"fill": {"scale": "color", "field": "name"}
}
}
}
]
}
Change your y2 from value to field. Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A stacked bar chart describing ad valorem taxes in Texas community college districts.",
"width": 300,
"height": 300,
"padding": 5,
"background": "white",
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{
"name": "Operations (MO)",
"amount": 0.1078,
"district": "Alamo",
"sort": 1,
"y0": 0,
"y1": 0.1078
},
{
"name": "Debt (IS)",
"amount": 0.0414,
"district": "Alamo",
"sort": 2,
"y0": 0.1078,
"y1": 0.1492
},
{
"name": "Below Cap",
"amount": 0.8508,
"district": "Alamo",
"sort": 3,
"y0": 0.1492,
"y1": 1
},
{
"name": "Operations (MO)",
"amount": 0.152,
"district": "State Average",
"sort": 1,
"y0": 0,
"y1": 0.152
},
{
"name": "Debt (IS)",
"amount": 0.027,
"district": "State Average",
"sort": 2,
"y0": 0.152,
"y1": 0.179
},
{
"name": "Below Cap",
"amount": 0.821,
"district": "State Average",
"sort": 3,
"y0": 0.179,
"y1": 1
}
],
"format": {"type": "json"},
"transform": [
{
"type": "stack",
"groupby": ["district"],
"sort": {"field": "sort"},
"field": "amount"
}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"range": "width",
"domain": {"data": "source_0", "field": "district"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": true,
"domain": {"data": "source_0", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "source_0", "field": "name"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{
"type": "rect",
"from": {"data": "source_0"},
"encode": {
"enter": {
"x": {"scale": "x", "field": "district"},
"width": {"scale": "x", "band": 1},
"y": {"scale": "y", "field": "y1"},
"y2": {"scale": "y", "field": "y0"},
"fill": {"scale": "color", "field": "name"}
}
}
}
]
}
This sample code from vega transformations is not working.
I am not getting the expected results.
Can you please help me run this example in the vega editor?
[
{"foo": {"a": 5, "b": "abc"}, "bar": 0},
{"foo": {"a": 6, "b": "def"}, "bar": 1},
{"foo": {"a": 7, "b": "ghi"}, "bar": 2}
]
To extract the "bar" field along with the "a" and "b" sub-fields into new objects, use the transform:
{
"type": "project",
"fields": ["bar", "foo.a", "foo.b"],
"as": ["bar", "a", "b"]
}
This produces the following output:
[
{"bar":0, "a":5, "b":"abc"},
{"bar":1, "a":6, "b":"def"},
{"bar":2, "a":7, "b":"ghi"}
]
Ok, I used the very first sample in the editor (the bar chart one) to demonstrate the transformation for you. Here is the modified code you can paste in the editor:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A basic bar chart example, with value labels shown upon mouse hover.",
"width": 400,
"height": 200,
"padding": 5,
"data": [
{
"name": "table",
"values": [
{"foo": {"a": 5, "b": "abc"}, "bar": 0},
{"foo": {"a": 6, "b": "def"}, "bar": 1},
{"foo": {"a": 7, "b": "ghi"}, "bar": 2}
],
"transform": [
{
"type": "project",
"fields": ["bar", "foo.a", "foo.b"],
"as": ["bar", "a", "b"]
}
]
}
],
"signals": [
{
"name": "tooltip",
"value": {},
"on": [
{"events": "rect:mouseover", "update": "datum"},
{"events": "rect:mouseout", "update": "{}"}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {"data": "table", "field": "bar"},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {"data": "table", "field": "a"},
"nice": true,
"range": "height"
}
],
"axes": [
{ "orient": "bottom", "scale": "xscale" },
{ "orient": "left", "scale": "yscale" }
],
"marks": [
{
"type": "rect",
"from": {"data":"table"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "bar"},
"width": {"scale": "xscale", "band": 1},
"y": {"scale": "yscale", "field": "a"},
"y2": {"scale": "yscale", "value": 0}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {
"fill": {"value": "red"}
}
}
},
{
"type": "text",
"encode": {
"enter": {
"align": {"value": "center"},
"baseline": {"value": "bottom"},
"fill": {"value": "#333"}
},
"update": {
"x": {"scale": "xscale", "signal": "tooltip.bar", "band": 0.5},
"y": {"scale": "yscale", "signal": "tooltip.a", "offset": -2},
"text": {"signal": "tooltip.b"},
"fillOpacity": [
{"test": "datum === tooltip", "value": 0},
{"value": 1}
]
}
}
}
]
}
And here would be the expected result:
As you can see in the data viewer of the editor, "bar" "a" and "b" have the correct values, and I have changed the bar chart so it uses those values to show the bars, the appropriate height, as well as the tooltip when you hover over a bar.
I have a question about facet visualizations in vega.
I have a pretty similar problem as the nested bar char example.
Here I changed the order of the tuple values. as intended, the order in the visualization is changing to.
But I want the 3 facets ordered ascending for value "a".
I don't really understand, if there is a "scale" for the facets, or where to order them.
Second part would be to have an axes for the value "a" shown below/above the bar chart.
Hope someone can help me.
Greetings
Christian
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A nested bar chart example, with bars grouped by category.",
"width": 300,
"padding": 5,
"autosize": "pad",
"signals": [
{
"name": "rangeStep", "value": 20,
"bind": {"input": "range", "min": 5, "max": 50, "step": 1}
},
{
"name": "innerPadding", "value": 0.1,
"bind": {"input": "range", "min": 0, "max": 0.7, "step": 0.01}
},
{
"name": "outerPadding", "value": 0.2,
"bind": {"input": "range", "min": 0, "max": 0.4, "step": 0.01}
},
{
"name": "height",
"update": "trellisExtent[1]"
}
],
"data": [
{
"name": "tuples",
"values": [
{"a": 1, "b": "b", "c": 4.4},
{"a": 0, "b": "c", "c": 5.1},
{"a": 0, "b": "a", "c": 6.3},
{"a": 0, "b": "a", "c": 4.2},
{"a": 0, "b": "b", "c": 6.8},
{"a": 2, "b": "b", "c": 3.5},
{"a": 2, "b": "c", "c": 6.2}
],
"transform": [
{
"type": "aggregate",
"groupby": ["a", "b"],
"fields": ["c"],
"ops": ["average"],
"as": ["c"]
}
]
},
{
"name": "trellis",
"source": "tuples",
"transform": [
{
"type": "aggregate",
"groupby": ["a"]
},
{
"type": "formula", "as": "span",
"expr": "rangeStep * bandspace(datum.count, innerPadding, outerPadding)"
},
{
"type": "stack",
"field": "span"
},
{
"type": "extent",
"field": "y1",
"signal": "trellisExtent"
}
]
}
],
"scales": [
{
"name": "xscale",
"domain": {"data": "tuples", "field": "c"},
"nice": true,
"zero": true,
"round": true,
"range": "width"
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "trellis", "field": "a"}
}
],
"axes": [
{ "orient": "bottom", "scale": "xscale", "domain": true }
],
"marks": [
{
"type": "group",
"from": {
"data": "trellis",
"facet": {
"name": "faceted_tuples",
"data": "tuples",
"groupby": "a"
}
},
"encode": {
"enter": {
"x": {"value": 0},
"width": {"signal": "width"}
},
"update": {
"y": {"field": "y0"},
"y2": {"field": "y1"}
}
},
"scales": [
{
"name": "yscale",
"type": "band",
"paddingInner": {"signal": "innerPadding"},
"paddingOuter": {"signal": "outerPadding"},
"round": true,
"domain": {"data": "faceted_tuples", "field": "b"},
"range": {"step": {"signal": "rangeStep"}}
}
],
"axes": [
{ "orient": "left", "scale": "yscale",
"ticks": false, "domain": false, "labelPadding": 4 }
],
"marks": [
{
"type": "rect",
"from": {"data": "faceted_tuples"},
"encode": {
"enter": {
"x": {"value": 0},
"x2": {"scale": "xscale", "field": "c"},
"fill": {"scale": "color", "field": "a"},
"strokeWidth": {"value": 2}
},
"update": {
"y": {"scale": "yscale", "field": "b"},
"height": {"scale": "yscale", "band": 1},
"stroke": {"value": null},
"zindex": {"value": 0}
},
"hover": {
"stroke": {"value": "firebrick"},
"zindex": {"value": 1}
}
}
}
]
}
]
}
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"}
}
}
]
}
I have a vega-lite chart that shows up as expected in Chrome (72.0.3626.96), but not in Firefox (70.0.1). I have checked the spec in the Vega Editor. Does anyone know why this might be?
Here are the rendered charts:
Firefox:
Chrome:
Here is the spec:
Any help you might be able to give would be much appreciated.
Apologies, but I do not know how to collapse this code.
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.2.1.json",
"background": "white",
"config": {"mark": {"tooltip": null}, "view": {"height": 300, "width": 400}},
"datasets": {
"data-511198e25d4dbee99248144390684caa": [
{
"counts": 338,
"filter_method": "greater than",
"grade": "9",
"index": 3,
"perc": 0.2669826224328594,
"school_code": "Board",
"threshold": "8",
"year": 20172018,
"year_lab": "2017/18",
"year_lab_q": "2017"
},
{
"counts": 414,
"filter_method": "greater than",
"grade": "9",
"index": 4,
"perc": 0.30689399555226093,
"school_code": "Board",
"threshold": "8",
"year": 20182019,
"year_lab": "2018/19",
"year_lab_q": "2018"
}
],
"data-72a083843a98847e44077116c495e448": [
{
"counts": 49,
"filter_method": "greater than",
"grade": "9",
"index": 0,
"perc": 0.3356164383561644,
"school_code": "KING",
"threshold": "8",
"year": 20142015,
"year_lab": "2014/15",
"year_lab_q": "2014"
},
{
"counts": 62,
"filter_method": "greater than",
"grade": "9",
"index": 5,
"perc": 0.3668639053254438,
"school_code": "MLTS",
"threshold": "8",
"year": 20162017,
"year_lab": "2016/17",
"year_lab_q": "2016"
},
{
"counts": 53,
"filter_method": "greater than",
"grade": "9",
"index": 6,
"perc": 0.29608938547486036,
"school_code": "KING",
"threshold": "8",
"year": 20172018,
"year_lab": "2017/18",
"year_lab_q": "2017"
},
{
"counts": 44,
"filter_method": "greater than",
"grade": "9",
"index": 7,
"perc": 0.25882352941176473,
"school_code": "MLTS",
"threshold": "8",
"year": 20172018,
"year_lab": "2017/18",
"year_lab_q": "2017"
},
{
"counts": 53,
"filter_method": "greater than",
"grade": "9",
"index": 8,
"perc": 0.3212121212121212,
"school_code": "KING",
"threshold": "8",
"year": 20182019,
"year_lab": "2018/19",
"year_lab_q": "2018"
},
{
"counts": 61,
"filter_method": "greater than",
"grade": "9",
"index": 9,
"perc": 0.25206611570247933,
"school_code": "MLTS",
"threshold": "8",
"year": 20182019,
"year_lab": "2018/19",
"year_lab_q": "2018"
}
]
},
"height": 400,
"layer": [
{
"data": {"name": "data-72a083843a98847e44077116c495e448"},
"encoding": {
"color": {
"field": "school_code",
"legend": {"labelFontSize": 15, "titleFontSize": 20},
"title": null,
"type": "nominal"
},
"tooltip": [
{
"field": "perc",
"format": ".2%",
"title": "percentage",
"type": "quantitative"
},
{
"field": "counts",
"title": "number",
"type": "quantitative"
},
{"field": "year_lab", "title": "school year", "type": "nominal"},
{"field": "school_code", "title": "level", "type": "nominal"},
{"field": "grade", "type": "nominal"},
{"field": "filter_method", "type": "nominal"},
{"field": "threshold", "type": "nominal"}
],
"x": {
"axis": {"format": "%Y", "tickCount": 5},
"field": "year_lab_q",
"scale": {"domain": ["2013.9", "2018.5"]},
"title": "School Year (beginning)",
"type": "temporal"
},
"y": {
"axis": {"format": ".0%"},
"field": "perc",
"title": "Percentage",
"type": "quantitative"
}
},
"mark": {"point": true, "type": "line"},
"selection": {
"selector001": {
"bind": "scales",
"encodings": ["x", "y"],
"type": "interval"
}
}
},
{
"data": {"name": "data-511198e25d4dbee99248144390684caa"},
"encoding": {
"color": {
"field": "school_code",
"legend": {"labelFontSize": 15, "titleFontSize": 20},
"scale": {"domain": ["Board"], "range": ["black"]},
"title": null,
"type": "nominal"
},
"tooltip": [
{
"field": "perc",
"format": ".2%",
"title": "percentage",
"type": "quantitative"
},
{
"field": "counts",
"title": "number",
"type": "quantitative"
},
{"field": "year_lab", "title": "school year", "type": "nominal"},
{"field": "school_code", "title": "level", "type": "nominal"},
{"field": "grade", "type": "nominal"},
{"field": "filter_method", "type": "nominal"},
{"field": "threshold", "type": "nominal"}
],
"x": {"field": "year_lab_q", "type": "temporal"},
"y": {"field": "perc", "type": "quantitative"}
},
"mark": {"point": true, "type": "line"}
}
],
"resolve": {"scale": {"color": "independent"}},
"title": "A title!",
"width": 700
}
It appears that your temporal values are not being parsed correctly in firefox (details of javascript date parsing behavior is often browser-dependent). You could try forcing the correct parsing by changing your data specification (in both places) to:
"data": {
"name": "data-72a083843a98847e44077116c495e448",
"format": {"parse": {"year_lab_q": "date:%Y"}}
}
This should ensure that the year string is parsed as a year, rather than e.g. a unix timestamp.
The other place date parsing is happening is in your domain specification. You might try changing those to a more standard time format, e.g.
"domain": ["2013-11-01", "2018-06-01"]