Related
I'm fairly new to vega-lite. I'd really like to get the following nested bar chart working.
This nested bar chart depicts aggregated values across multiple categories. The input data is subdivided according to two fields (with uneven category membership). Each sub-group is then aggregated to show the average value of a third, quantitative field.
Example on vega:Nested Bar Chart Example
How not to use the row function?
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {
"values": [
{"a0": 0,"a": 0, "b": "a", "c": 6.3},
{"a0": 0,"a": 0, "b": "a", "c": 4.2},
{"a0": 0,"a": 0, "b": "b", "c": 6.8},
{"a0": 0,"a": 0, "b": "c", "c": 5.1},
{"a0": 0,"a": 1, "b": "b", "c": 4.4},
{"a0": 0,"a": 2, "b": "b", "c": 3.5},
{"a0": 0,"a": 2, "b": "c", "c": 6.2}
]
},
"transform": [
{"window": [{"op": "count", "as": "room2"}]}
],
"vconcat": [
{
"facet": {"column": {"field": "a0"},"row": {"field": "a"}},
"spec": {
"width": 100,
"encoding": {
"y": {"field": "room2", "type": "nominal","axis": null},
"x": {"value": 100, "type": "quantitative"}
},
"layer": [
{
"mark": {"type": "bar", "cornerRadius": 10},
"encoding": {
"color": {
"field": "room2"
}
}
}
]
}
}
]
}
I have converted the Example on vega: Nested Bar Chart Example to vega-lite. So I hope it helps you understand or resolve your case. If you need help with your chart then I would need some proper inputs from your end. Refer the code below or in Editor
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"a": 0, "b": "a", "c": 6.3},
{"a": 0, "b": "a", "c": 4.2},
{"a": 0, "b": "b", "c": 6.8},
{"a": 0, "b": "c", "c": 5.1},
{"a": 1, "b": "b", "c": 4.4},
{"a": 2, "b": "b", "c": 3.5},
{"a": 2, "b": "c", "c": 6.2}
]
},
"transform": [
{
"aggregate": [{"field": "c", "as": "avg_c", "op": "average"}],
"groupby": ["a", "b"]
}
],
"vconcat": [
{
"facet": {"row": {"field": "a", "title": null, "header": null}},
"spec": {
"width": 300,
"encoding": {
"y": {"field": "b", "type": "nominal", "axis": null},
"x": {"field": "avg_c", "type": "quantitative"}
},
"layer": [
{
"mark": {"type": "bar", "cornerRadius": 10},
"encoding": {"color": {"field": "a"}}
},
{
"mark": {"type": "text", "align": "right", "dx": -5},
"encoding": {
"text": {"field": "b"},
"x": {"datum": "0", "type": "quantitative"}
}
}
]
}
}
]
}
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.
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}
]
}
}
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
}
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 :).