Filter by selection from referenced table - vega-lite

I have a single data source within datasets that I use in two concatenated charts. Now when I click on a bar in the left chart I would like to filter the right chart. See animated gif:
But is doesn't.
Click here to open in the vega-editor.
Or check the spec here::
{
"config": {"view": {"width": 400, "height": 300}},
"hconcat": [
{
"width": 100,
"selection": {"SELECT": {"type": "single", "resolve": "global"}},
"data": {"name": "table_data"},
"mark": "bar",
"encoding": {
"x": {"type": "nominal", "field": "Major_Genre"},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {"type": "nominal", "field": "Major_Genre"},
"fillOpacity": {
"condition": {"selection": "SELECT", "value": 1},
"value": 0.3
}
}
},
{
"width": 100,
"data": {"name": "table_data"},
"transform": [{"filter": {"selection": "SELECT"}}],
"mark": "bar",
"encoding": {
"x": {"type": "nominal", "field": "Major_Genre"},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {"type": "nominal", "field": "Major_Genre"}
}
}
],
"datasets": {
"table_data": [
{
"Title": "Cidade de Deus",
"Major_Genre": "Drama",
"Country_Origin": "Brazil"
},
{
"Title": "Chocolate: Deep Dark Secrets",
"Major_Genre": "Thriller/Suspense",
"Country_Origin": "India"
},
{"Title": "Fiza", "Major_Genre": "Drama", "Country_Origin": "India"},
{
"Title": "First Love, Last Rites",
"Major_Genre": "Drama",
"Country_Origin": "United States"
},
{
"Title": "Foolish",
"Major_Genre": "Comedy",
"Country_Origin": "United States"
},
{
"Title": "I Married a Strange Person",
"Major_Genre": "Comedy",
"Country_Origin": "United States"
}
]
}
}

When your selections refer to groups of points rather than single points, you need to provide an explicit fields or encodings argument to specify what points are included in the selection.
In this case, the chart will behave as expected if you specify your selection in one of the following ways:
"selection": {"SELECT": {"type": "single", "fields": ["Major_Genre"], "resolve": "global"}}
"selection": {"SELECT": {"type": "single", "encodings": ["color"], "resolve": "global"}}
"selection": {"SELECT": {"type": "single", "encodings": ["x"], "resolve": "global"}}
Here's the working chart in action: (vega editor link).

Related

How can I add a year slider to this Ranged Dot Plot in Vega Lite?

I have a dataset with relevant values from 2000-2019, and when I load up the graph with this specification:
"data": {
"name": "chart6",
"url": "https://raw.githubusercontent.com/sebaconstable/sebaconstable.github.io/main/chart6data.csv"
},
"height": 300,
"width": 450,
"encoding": {
"x": {
"field": "average years in school",
"type": "quantitative",
"scale": {"domain": [0, 20]},
"title": "Average Years in School"
},
"y": {
"field": "Country",
"type": "nominal",
"axis": {"offset": 5, "ticks": false, "minExtent": 70, "domain": false}
}
},
"layer": [
{
"mark": "line",
"encoding": {
"detail": {"field": "Country", "type": "nominal"},
"color": {"value": "#BBBBBB"}
}
},
{
"mark": {"type": "point", "filled": true},
"encoding": {
"tooltip": [
{"field": "Country", "type": "nominal", "title": "Country"},
{"field": "QuintGap", "type": "quantitative", "title": "Difference between richest and poorest quintile"},
{"field": "Median % Pop", "type": "nominal", "title": "Median % of population in CCT programmes (2000-2019)"}
],
"color": {
"field": "Quintile",
"type": "nominal",
"title": null,
"scale": {"scheme": "inferno"}
},
"size": {
"field": "Median % Pop",
"type": "quantitative",
"legend":null,
"scale": {"range": [10, 100]}
},
"opacity": {"value": 1}
}
}
]
}
The points for every year appear on each country. I want to make it so it has a year slider and then only the two points for the selected year show.
I have tried many things. I added:
"transform": [
{"filter": {"field": "Quintile", "oneOf": ["Poorest Quintile", "Richest Quintile"]}},
{"filter": "datum.Year==selecta"}
],
"params": [
{
"name": "selecta",
"value": [{"year":2019}],
"bind": {
"input": "range",
"min": 2000,
"max": 2019,
"step": 1,
"name": "Select year:"
}
}
],
this code above the first encoding, and that successfully creates a slider (which filters to the relevant data correctly) however the rest of the chart disappears. I also tried adding a filter to "oneOf" the 20 years, however this made the visualisation dissapear.
I feel that I'm quite close to the solution but after several hours can't quite figure it out. Any help is much appreciated!
Here you go.
{
"data": {
"name": "chart6",
"url": "https://raw.githubusercontent.com/sebaconstable/sebaconstable.github.io/main/chart6data.csv"
},
"transform": [{"filter": "datum.Year==selecta"}],
"params": [
{
"name": "selecta",
"value": [2019],
"bind": {
"input": "range",
"min": 2000,
"max": 2019,
"step": 1,
"name": "Select year:"
}
}
],
"height": 300,
"width": 450,
"encoding": {
"x": {
"field": "average years in school",
"type": "quantitative",
"scale": {"domain": [0, 20]},
"title": "Average Years in School"
},
"y": {
"field": "Country",
"type": "nominal",
"axis": {"offset": 5, "ticks": false, "minExtent": 70, "domain": false}
}
},
"layer": [
{
"mark": "line",
"encoding": {
"detail": {"field": "Country", "type": "nominal"},
"color": {"value": "#BBBBBB"}
}
},
{
"mark": {"type": "point", "filled": true},
"encoding": {
"tooltip": [
{"field": "Country", "type": "nominal", "title": "Country"},
{
"field": "QuintGap",
"type": "quantitative",
"title": "Difference between richest and poorest quintile"
},
{
"field": "Median % Pop",
"type": "nominal",
"title": "Median % of population in CCT programmes (2000-2019)"
}
],
"color": {
"field": "Quintile",
"type": "nominal",
"title": null,
"scale": {"scheme": "inferno"}
},
"size": {
"field": "Median % Pop",
"type": "quantitative",
"legend": null,
"scale": {"range": [10, 100]}
},
"opacity": {"value": 1}
}
}
]
}

Does anyone have an explanation as to why this graph is being made on vega?

Am trying to make a graph in vegalite whereby i show the evolution of stock prices overtime. Intuitively this should be very easy however for some reason only two lines seem to get output and they aren't reflective of the stock prices at all. Is there something wrong with my data or am i missing something quite basic?
{"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"title": {
"text": "Cases: UK nations",
"subtitle": [
"New cases by publish date, rolling rate"
],
"subtitleFontStyle": "italic",
"subtitleFontSize": 10,
"anchor": "start",
"color": "black"
},
"background": "whitesmoke",
"width": 800,
"height": 600,
"data": {
"url": "https://raw.githubusercontent.com/andrewsnowdon/andrewsnowdon.github.io/main/graph1megasheet.csv",
"format": {"type": "csv"}},
"layer": [
{
"encoding": {
"x": {"field": "Date", "type": "temporal"},
"y": {"field": "Open", "type": "quantitative"},
"color": {
"field":"Stockname",
"type": "nominal"
}
},
"layer": [
{"mark": "line"},
{
"params": [
{
"name": "label",
"select": {
"type": "point",
"encodings": ["x"],
"nearest": true,
"on": "mouseover"
}
}
],
"mark": "point",
"encoding": {
"opacity": {
"condition": {"param": "label", "empty": false, "value": 1},
"value": 0
}
}
}
]
},
{
"transform": [{"filter": {"param": "label", "empty": true}}],
"layer": [
{
"mark": {"type": "rule", "color": "grey"},
"encoding": {
"x": {"type": "temporal", "field": "Date", "aggregate": "min"}
}
},
{
"encoding": {
"text": {"type": "quantitative", "field": "Open"},
"x": {"type": "temporal", "field": "Date", "title": "Month"},
"y": {
"type": "quantitative",
"field": "Open",
"title": "Price"
}
},
"layer": [
{
"mark": {
"type": "text",
"stroke": "white",
"strokeWidth": 0.5,
"align": "left",
"dx": 5,
"dy": -5
}
},
{
"mark": {"type": "text", "align": "left", "dx": 5, "dy": -5},
"encoding": {"color": {"type": "quantitative"}}
}
]
}
]
}
],
"config": {}
}
Four of your stocks have identical data, so the lines are hidden below the last one drawn. You can see this by faceting your dataset:
{
"data": {
"url": "https://raw.githubusercontent.com/andrewsnowdon/andrewsnowdon.github.io/main/graph1megasheet.csv",
"format": {"type": "csv", "parse": {"Date": "date:'%d/%m/%Y'"}}
},
"mark": "line",
"encoding": {
"x": {"field": "Date", "type": "temporal"},
"y": {"field": "Open", "type": "quantitative"},
"facet": {"field": "Stockname", "type": "nominal", "columns": 3}
}
}
Notice the parse argument to the data format; this is required for correct parsing of your date entries (as mentioned in https://stackoverflow.com/a/70658380/2937831).

Slider for chloropeth map Vega-lite

I am trying to add a slider for my chloropeth map of Europe in vega-lite, to filter the data by year. I currently have a map which just shows data from 2019 (colour coded), and I am trying to make a slider so I can change years and see how the colours have changed over time.
Here is my code so far:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 300,
"height": 300,
"data": {
"url": "https://raw.githubusercontent.com/leakyMirror/map-of-europe/master/TopoJSON/europe.topojson",
"format": {"type": "topojson", "feature": "europe"}
},
"transform": [
{
"lookup": "properties.NAME",
"from": {
"data": {
"url": "https://raw.githubusercontent.com//jamesjeffery77/jamesjeffery77.github.io/main/share-electricity-low-carbon_fullDataset.csv"
},
"key": "country",
"fields": ["percentage"]
}
}
],
"params": [
{
"name": "year",
"value": 2019,
"bind": {
"input": "range",
"min": 1985,
"max": 2019,
"step": 1,
"name": "Select the year:"
}
}
],
"projection": {"type": "naturalEarth1"},
"mark": "geoshape",
"encoding": {
"color": {
"field": "percentage",
"type": "quantitative"},
"tooltip": [
{"field": "properties.NAME", "type": "nominal", "title": "country"},
{"field": "percentage", "type": "quantitative"}
]
}
}
I have been able to do make a bar chart using the same data which updates as I move the slider.The {"filter": "datum.year==year"} is what makes my bar chart able to do this, however it does not work on my chloropeth map (I have tried to add this within the "transform" array in both, with success for my bar chart). Here is the code for my bar chart in case that helps.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "",
"title": {
"text": "Thisisatest",
"subtitle":
"hellohello Source: OurWorldInData",
"subtitleFontStyle": "italic",
"subtitleFontSize": 10,
"anchor": "start",
"color": "black"
},
"data": {
"url": "https://raw.githubusercontent.com//jamesjeffery77/jamesjeffery77.github.io/main/share-electricity-low-carbon_fullDataset.csv"
},
"height": 300,
"width": 350,
"mark": {"type": "bar", "color": "skyblue"},
"transform": [
{"filter": "datum.year==year"},
{"filter": {
"field": "country",
"oneOf": [
"United Kingdom", "Spain", "France", "Netherlands", "Portugal", "Italy", "Poland", "Albania", "Germany", "Belgium", "Austria", "Denmark"]}
}
],
"params": [
{
"name": "year",
"value": 2019,
"bind": {
"input": "range",
"min": 1985,
"max": 2019,
"step": 1,
"name": "Select the year:"
}
}
],
"encoding": {
"y": {
"field": "percentage",
"type": "quantitative",
"title": "Percentage of low carbon energy",
"axis": {"grid": false}
},
"x": {
"field": "country",
"type": "nominal",
"title": "",
"axis": {"grid": false, "labelAngle": 20},
"sort": "-y"
},
"tooltip": [
{"field": "country", "title": "Country"},
{"field": "percentage", "title": "percentage of low carbon energy"}
]
}
}
What am I am doing wrong? Would appreciate any help! :)
Thanks
It was almost correct but in your lookup transform you need to provide the fields which you are going to be required in your final data like year field. Since there was no year field the filter transform was not working.
Below is the modified config or refer editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 300,
"height": 300,
"data": {
"url": "https://raw.githubusercontent.com//jamesjeffery77/jamesjeffery77.github.io/main/share-electricity-low-carbon_fullDataset.csv"
},
"transform": [
{
"lookup": "country",
"from": {
"data": {
"url": "https://raw.githubusercontent.com/leakyMirror/map-of-europe/master/TopoJSON/europe.topojson",
"format": {"type": "topojson", "feature": "europe"}
},
"key": "properties.NAME",
"fields": ["properties", "type", "geometry"]
}
},
{"filter": "datum.year==year"}
],
"params": [
{
"name": "year",
"value": 2019,
"bind": {
"input": "range",
"min": 1985,
"max": 2030,
"step": 1,
"name": "Select the year:"
}
}
],
"projection": {"type": "naturalEarth1"},
"mark": "geoshape",
"encoding": {
"color": {"field": "percentage", "type": "quantitative"},
"tooltip": [
{"field": "properties.NAME", "type": "nominal", "title": "country"},
{"field": "percentage", "type": "quantitative"}
]
}
}
Edit
I have inverted the main data and lookup data, which seems to bring all the years for your countries. Let me know if this works.

Vega Lite: Normalized Stacked Bar Chart + Overlay percentages as text

I have a stacked normalized bar chart similar to this:
https://vega.github.io/editor/#/examples/vega-lite/stacked_bar_normalize
I'm trying to show the related percentages (per bar segment) as text on the bars similar to: https://gist.github.com/pratapvardhan/00800a4981d43a84efdba0c4cf8ee2e1
I tried adding a transform field to calculate the percentages, but still couldn't get it to work after hours of trying.
I'm lost help 🥺
My best try:
{
"description":
"A bar chart showing the US population distribution of age groups and gender in 2000.",
"data": {
"url": "data/population.json"
},
"transform": [
{"filter": "datum.year == 2000"},
{"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"},
{
"stack": "people",
"offset": "normalize",
"as": ["v1", "v2"],
"groupby": ["age"],
"sort": [{"field": "gender", "order": "descending"}]
}
],
"encoding": {
"y": {
"field": "v1",
"type": "quantitative",
"title": "population"
},
"y2": {"field": "v2"},
"x": {
"field": "age",
"type": "ordinal"
},
"color": {
"field": "gender",
"type": "nominal",
"scale": {
"range": ["#675193", "#ca8861"]
}
}
},
"layer":[
{ "mark": "bar"},
{"mark": {"type": "text", "dx": 0, "dy": 0},
"encoding": {
"color":{"value":"black"},
"text": { "field": "v1", "type": "quantitative", "format": ".1f"}}
}
]
}
You can use a joinaggregate transform to normalize each group, and then use "format": ".1%" to display fractions as percents. Using this, there is no need to manually compute the stack transform; it is simpler to specify the stack via the encoding, as in the example you linked to.
Here is the result (open in editor):
{
"description": "A bar chart showing the US population distribution of age groups and gender in 2000.",
"data": {"url": "data/population.json"},
"transform": [
{"filter": "datum.year == 2000"},
{"calculate": "datum.sex == 2 ? 'Female' : 'Male'", "as": "gender"},
{
"joinaggregate": [{"op": "sum", "field": "people", "as": "total"}],
"groupby": ["age"]
},
{"calculate": "datum.people / datum.total", "as": "fraction"}
],
"encoding": {
"y": {
"aggregate": "sum",
"field": "people",
"title": "population",
"stack": "normalize"
},
"order": {"field": "gender", "sort": "descending"},
"x": {"field": "age", "type": "ordinal"},
"color": {
"field": "gender",
"type": "nominal",
"scale": {"range": ["#675193", "#ca8861"]}
}
},
"layer": [
{"mark": "bar"},
{
"mark": {"type": "text", "dx": 20, "dy": 0, "angle": 90},
"encoding": {
"color": {"value": "white"},
"text": {"field": "fraction", "type": "quantitative", "format": ".1%"}
}
}
]
}

Is it possible to have columns of donut chart with gray arc indicating the missing part?

Currently, the donut chart assumed that the max value is 100%. What I would like is for the category Chinese to have a percentage of 50% with gray arc indicating the missing 50%. The two other donut charts will behave similarly in their respective column.
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple donut chart with embedded data.",
"data": {
"values": [
{"category": "English", "value": 4},
{"category": "Malay", "value": 6},
{"category": "Chinese", "value": 10}
]
},
"mark": {"type": "arc", "innerRadius": 80},
"encoding": {
"column": {"field": "category"},
"theta": {"field": "value", "type": "quantitative"},
"color": {"field": "category", "type": "nominal"}
},
"view": {"stroke": null}
}
It's a bit more complex, but one way to do this is to use a transform to calculate the total, and then a layer chart to plot that total in the background.
Here is an example (open in editor):
{
"data": {
"values": [
{"category": "English", "value": 4},
{"category": "Malay", "value": 6},
{"category": "Chinese", "value": 10}
]
},
"transform": [
{"joinaggregate": [{"op": "sum", "field": "value", "as": "total"}]}
],
"facet": {"column": {"field": "category"}},
"spec": {
"layer": [
{
"mark": {"type": "arc", "innerRadius": 80, "color": "lightgray"},
"encoding": {"theta": {"field": "total", "type": "quantitative"}}
},
{
"mark": {"type": "arc", "innerRadius": 80},
"encoding": {
"theta": {"field": "value", "type": "quantitative"},
"color": {"field": "category"}
}
}
],
"view": {"stroke": null}
}
}