theta and theta2 chanel encoding by field - vega-lite

I want to create arcs using vega-lite, here you will find a working example: enter link description here
but this does not work: enter link description here
The difference is only that I use this in the working example
"encoding": {
"theta": {"value": {"expr": "datum.thta"}},
"theta2": {"value": {"expr": "datum.thta2"}} }
And this is the code that does not work:
"encoding": {
"theta": {"field": "thta"},
"theta2": {"field": "thta2"}} }
Can someone explain why using the "fields" creates a half circle (not wanted) and "value" creates the quarter circle (wanted)?
Many thanks in advance

When you specify values via encodings, the scale is automatically adjusted based on the content of the data. You can fix this by specifying that the scale should be from 0 to 2pi (open in editor):
{
"width": 80,
"height": 80,
"params": [{"name": "radius", "value": 0}, {"name": "radius2", "value": 50}],
"data": {
"values": [{"name": "arc1", "quadrant": "TopRight", "ring": "Hold"}]
},
"transform": [
{
"calculate": "if(datum.quadrant === 'TopRight' , PI*0.5 , null)",
"as": "thta2"
},
{"calculate": "if(datum.quadrant === 'TopRight' , 0 , null)", "as": "thta"}
],
"mark": {
"type": "arc",
"radius": {"expr": "radius"},
"radius2": {"expr": "radius2"}
},
"encoding": {
"theta": {"field": "thta", "scale": {"domain": [0, "2*PI"]}},
"theta2": {"field": "thta2"}
}
}

Related

Align area and line marks to same domain in Vega-Lite

I'm trying to build a line chart with error area in vega lite.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_IC.csv"},
"transform": [
{"calculate": "toNumber(datum.x)", "as": "x2"},
{"calculate": "toNumber(datum.y)", "as": "y2"},
{"calculate": "toNumber(datum.CI_left)", "as": "l"},
{"calculate": "toNumber(datum.CI_right)", "as": "r"}
],
"params": [
{ "name": "scaleDomain", "expr": "[0, 10]"}
],
"encoding": {
"y": {
"field": "x2",
"type": "ordinal",
"sort": "descending"
}
},
"layer": [
{
"mark": {"type": "line", "interpolate": "cardinal"},
"encoding": {
"x": {
"field": "y",
"type": "quantitative",
"title": "Mean of Miles per Gallon (95% CIs)",
"scale": {"type": "linear", "domain": {"expr": "scaleDomain"}},
"axis": {
"orient": "top"
}
}
}
},
{
"mark": {"type": "area", "interpolate": "cardinal"},
"encoding": {
"x": {
"field": "l",
"scale": {"type": "linear", "domain": {"expr": "scaleDomain"}},
"axis": {
"orient": "top"
}
},
"x2": {
"field": "r"
},
"opacity": { "value": 0.3 }
}
}
]
}
So far, it's nice looking. But there's a problem: to get this to work I have had to manually constrain the scale domain for the two marks by setting a param called scaleDomain. This is a problem, because if ever the data changes I need to manually update the domain :/
However, look what would happen if I didn't manually set the scale to the same domain for the area plot and a line plot:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_IC.csv"},
"transform": [
{"calculate": "toNumber(datum.x)", "as": "x2"},
{"calculate": "toNumber(datum.y)", "as": "y2"},
{"calculate": "toNumber(datum.CI_left)", "as": "l"},
{"calculate": "toNumber(datum.CI_right)", "as": "r"}
],
"params": [
{ "name": "scaleDomain", "expr": "[0, 10]"}
],
"encoding": {
"y": {
"field": "x2",
"type": "ordinal",
"sort": "descending"
}
},
"layer": [
{
"mark": {"type": "line", "interpolate": "cardinal"},
"encoding": {
"x": {
"field": "y",
"type": "quantitative",
"title": "Mean of Miles per Gallon (95% CIs)",
// "scale": {"type": "linear", "domain": {"expr": "scaleDomain"}},
"axis": {
"orient": "top"
}
}
}
},
{
"mark": {"type": "area", "interpolate": "cardinal"},
"encoding": {
"x": {
"field": "l",
// "scale": {"type": "linear", "domain": {"expr": "scaleDomain"}},
"axis": {
"orient": "top"
}
},
"x2": {
"field": "r"
},
"opacity": { "value": 0.3 }
}
}
]
}
Yikes! The area plot gets a bit lost and doesn't track the line.
I can see one of two solutions to this problem:
Shared Scale: Coax the two mark layers to share the same scale
Manually Calculate Scale Domain: Use a parameter or a signal to store the desired domain.
I don't know how to do #1, but it seems like the correct approach. One imagined solution is something like:
"scale": {"align": "shared"},
I tried adding an aggregation to transform, but that of course results in summarizing the whole data set.
"transform": [
{"calculate": "toNumber(datum.x)", "as": "x2"},
{"calculate": "toNumber(datum.y)", "as": "y2"},
{"calculate": "toNumber(datum.CI_left)", "as": "l"},
{"calculate": "toNumber(datum.CI_right)", "as": "r"},
{ "aggregate": [
{
"field": "l",
"op": "min",
"as": "min"
},
{
"field": "r",
"op": "max",
"as": "max"
}
]}
],
It seems like I'd want to somehow put the transform directly into the layer or the params, but it's not clear how to do that.
I have seen these answers (finding max and min from dataset in vega and Post aggregation calculation & filter ##) but I don't know how to use them to achieve this.
You don't need any transforms and scales are automatically shared. Try this:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width":500,
"height":500,
"data": {
"url": "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_IC.csv"
},
"encoding": {"y": {"field": "x", "type": "quantitative", "sort": "ascending"}},
"layer": [
{
"mark": {"type": "line", "interpolate": "cardinal"},
"encoding": {
"x": {
"field": "y",
"sort": null,
"type": "quantitative",
"title": "Mean of Miles per Gallon (95% CIs)",
"axis": {"orient": "top"}
}
}
},
{
"mark": {"type": "area", "interpolate": "cardinal"},
"encoding": {
"x": {"field": "CI_left", "type": "quantitative"},
"x2": {"field": "CI_right"},
"opacity": {"value": 0.3}
}
}
]
}

Highest Value Wrong Colour

Just made a simple bar chart, but for some reason, the final value is the wrong colour?
Code:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 800,
"height": 600,
"title": "Death Rates Amongst Ages",
"data": {"url": "https://raw.githubusercontent.com/githubuser0099/Repo55/main/AgeBracket_DeathRate.csv"},
"transform": [
{"calculate":"parseInt(datum.Death_Rate)", "as": "Death_Rate"}
],
"mark": "bar",
"encoding": {
"x": {"field": "Death_Rate", "type": "quantitative", "title": ""},
"y": {"field": "Age", "type": "nominal", "title": "", "sort": "-x"},
"color": {
"field": "Age",
"type": "nominal",
"scale": {"scheme": "reds"}
}
}
}
The problem with your colour scale is: "Age" is currently encoded as a string (nominal variable). You define the type of "Age" as "nominal", but use a sequential colour scale ("reds"). Your data also has some issues - there are some empty spaces before 5-9, and 10-14.
In string comparison, white space < "0" < "100" < "15".
To solve the issue, we can get the first number from the range, and then define another channel to encode this first number (but hide the legend), then in the colour channel, you can define the colour order based on this additional channel.
Check the result and the codes below.
I have printed out the data and let you know how the calculation works.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 800,
"height": 600,
"title": "Death Rates Amongst Ages",
"data": {"url": "https://raw.githubusercontent.com/githubuser0099/Repo55/main/AgeBracket_DeathRate.csv"},
"transform": [
{"calculate":"parseInt(datum.Death_Rate)", "as": "Death_Rate"},
{"calculate": "split(datum['Age'], '-')[0]", "as": "Age_new"},
{"calculate": "replace(datum['Age_new'], ' ', '')", "as": "Age_new_2"},
{"calculate": "replace(datum['Age_new_2'], ' ', '')", "as": "Age_new_3"},
{"calculate": "parseInt(datum['Age_new_3'])", "as": "Age_new_4"}
],
"mark": "bar",
"encoding": {
"x": {"field": "Death_Rate", "type": "quantitative", "title": ""},
"y": {"field": "Age", "type": "nominal", "title": "", "sort": "-x"},
"opacity":{"field": "Age_new_4", "legend": null},
"color": {
"field": "Age",
"type": "ordinal",
"sort": "opacity",
"scale": {"scheme": "reds"}
}
}
}
Cheers,
KL

Creating custom bar chart in Vega-Lite

I am a newbie to Vega-Lite and I am trying to replicate a chart similar to this
Following is my code and it does not generate what I need.
{
"$schema":"https://vega.github.io/schema/vega-lite/v5.json",
"width":800,
"height":600,
"autosize":{
"type":"fit",
"contains":"padding"
},
"data":{
"url":"data/cars.json"
},
"mark":{
"type":"rect",
"tooltip":true,
"strokeWidth":0.1,
"stroke":"white"
},
"encoding":{
"x":{
"field":"Horsepower",
"type":"quantitative",
"bin":{
"maxbins":100
},
"axis":{
"labelAngle":0
}
},
"y":{
"aggregate":"count",
"field":"Horsepower",
"type":"quantitative"
}
}
}
Here is what it does
What do I need to do to be able to get my desired output? There is a question here already asked on the topic How to reproduce the Unsub histogram in Altair? but it was done in python altair, which I am not trying to do. I want to generate that using solely Vega-Lite.
Thank you in advance.
You can use a bin transform followed by a window transform to generate the fields required to create this kind of chart. For example (open in editor):
{
"data": {"url": "data/cars.json"},
"transform": [
{"bin": {"maxbins": 50}, "field": "Horsepower", "as": "Horsepower"},
{"window": [{"op": "count", "as": "index"}], "groupby": ["Horsepower"]}
],
"mark": {
"type": "rect",
"tooltip": true,
"strokeWidth": 0.3,
"stroke": "white"
},
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative", "bin": "binned"},
"x2": {"field": "Horsepower_end"},
"y": {
"field": "index",
"type": "ordinal",
"scale": {"reverse": true},
"title": "count"
}
},
"width": 400,
"height": 300
}

Vega-Lite layered chart: how to get tick marks and tick labels to span the entire axis?

I am working on a layered chart where I have both bars and rule lines. The issue I'm having is that on the x-axis, the tick marks and tick labels only appear under the bars and do not span the entire axis, making it so that there are no tick marks and labels underneath where the rule lines are located. Here is an example of what I'm seeing (link to Vega editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/movies.json"},
"transform": [
{"calculate": "2*datum.IMDB_Rating", "as": "UpperLimit"}
],
"layer": [
{
"mark": "bar",
"encoding": {
"x": {"bin": true, "field": "IMDB_Rating", "type": "quantitative"},
"y": {"aggregate": "count", "type": "quantitative"}
}
},
{
"mark": "rule",
"encoding": {
"x": {
"aggregate": "max",
"field": "UpperLimit",
"type": "quantitative"
},
"color": {"value": "red"},
"size": {"value": 5}
}
}
]
}
Image of issue
How do I get the tick marks and labels to span the entire axis? Thanks in advance for the help!
When you use a bin transform within an encoding, Vega-Lite adjusts the default axis properties to match the binning. You can re-adjust these manually via the encoding's scale and axis properties, but I think a simpler way is to move the bin transform to the chart's transform specification. Here is an example (Vega Editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/movies.json"},
"transform": [
{"calculate": "2*datum.IMDB_Rating", "as": "UpperLimit"},
{
"bin": true,
"field": "IMDB_Rating",
"as": ["IMDB_Rating_0", "IMDB_Rating_1"]
}
],
"layer": [
{
"mark": "bar",
"encoding": {
"x": {
"field": "IMDB_Rating_0",
"type": "quantitative",
"bin": "binned"
},
"x2": {"field": "IMDB_Rating_1"},
"y": {"aggregate": "count", "type": "quantitative"}
}
},
{
"mark": "rule",
"encoding": {
"x": {
"aggregate": "max",
"field": "UpperLimit",
"type": "quantitative"
},
"color": {"value": "red"},
"size": {"value": 5}
}
}
]
}

How to color lines with specific colors in Vega-Lite?

VegaLite assigns colors automatically. The Gold prices are Blue, and Silver prices are Orange, which feels wrong.
How can I assign explicit colours - #F1C40F for Gold and #95A5A6 for Silver?
I also would like to keep the data.values as in the example code below - as a set of separate arrays.
Code and Playground
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Stock prices of 5 Tech Companies over Time.",
"data": {
"values": [
{
"dates": ["2000-01", "2000-02", "2000-03"],
"gold": [1, 2, 1],
"silver": [1.5, 1, 2]
}
]
},
"transform": [
{"flatten": ["dates", "gold", "silver"]},
{"fold": ["gold", "silver"], "as": ["symbol", "price"]},
{"calculate": "datetime(datum.dates)", "as": "dates"}
],
"mark": {"type": "line", "point": {"filled": false, "fill": "white"}},
"encoding": {
"x": {"field": "dates", "type": "temporal", "timeUnit": "yearmonth"},
"y": {"field": "price", "type": "quantitative"},
"color": {"field": "symbol", "type": "nominal"}
}
}
You can set a custom Color Scheme using the scale.domain and scale.range arguments:
"color": {
"field": "symbol",
"type": "nominal",
"scale": {"domain": ["gold", "silver"], "range": ["#F1C40F", "#95A5A6"]}
}
This works regardless of how the data source is specified.
Here is the result when applied to your chart (Vega Editor):