How do I add secondary Y axis in vega-lite with 2 series having the same scale? - vega-lite

I'm trying to build something like this:
example histogram with multiple independent series
I have 2 independent y-axis with orient left and right.
All series/layers using "orient":"right" should be sharing the same scale and all series/layers using "orient":"left" should be sharing the same scale.
I know of the "resolve" option as documented here but having read this How do I add a secondary Y axis to my vega-lite chart? and a bunch of other questions I couldn't find my particular use case.
My futile attempt so far looks like this:
example in online editor
example screenshot
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.json",
"data": {"url": "data/movies.json"},
"transform":[
{"calculate":"datum.Production_Budget * 0.5","as":"y2"}
],
"layer":[
{
"mark": "bar",
"encoding": {
"x": {
"bin": true,
"field": "IMDB_Rating",
"type": "quantitative"
},
"y": {
"axis":{"orient":"left","title":"# of movies","grid":false},
"aggregate": "count",
"type": "quantitative"
}
}},
{
"mark": "line",
"encoding": {
"x": {
"bin": true,
"field": "IMDB_Rating",
"type": "quantitative"
},
"y": {
"field":"Production_Budget",
"aggregate": "average",
"type": "quantitative",
"axis":{"orient":"right","format":"s","title":"avg production budget in $"}
}
}
},
{
"mark": "line",
"encoding": {
"x": {
"bin": true,
"field": "IMDB_Rating",
"type": "quantitative"
},
"y": {
"field":"y2",
"aggregate": "average",
"type": "quantitative",
"axis":{"orient":"right","format":"s","title":"avg production budget in $"}
}
}
}
]
,"resolve": {
"scale":{"y":"independent"}
}
}
I've tried playing with the resolve option:
"resolve": {
"scale":{"axisLeft":"independent"}
}
"resolve": {
"axisLeft":{"y":"independent"}
}
"resolve": {
"axis":{"left":"independent"}
}
but none of them work.

You can do this by creating a layer within a layer: the two orient: "right" charts in a single layer with a shared axis, and the orient: "left" chart with an independent scale:
vega editor link
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.json",
"data": {"url": "data/movies.json"},
"transform": [{"calculate": "datum.Production_Budget * 0.5", "as": "y2"}],
"layer": [
{
"mark": "bar",
"encoding": {
"x": {"bin": true, "field": "IMDB_Rating", "type": "quantitative"},
"y": {
"axis": {"orient": "left", "title": "# of movies", "grid": false},
"aggregate": "count",
"type": "quantitative"
}
}
},
{
"layer": [
{
"mark": "line",
"encoding": {
"x": {"bin": true, "field": "IMDB_Rating", "type": "quantitative"},
"y": {
"field": "Production_Budget",
"aggregate": "average",
"type": "quantitative",
"axis": {
"orient": "right",
"format": "s",
"title": "avg production budget in $"
}
}
}
},
{
"mark": "line",
"encoding": {
"x": {"bin": true, "field": "IMDB_Rating", "type": "quantitative"},
"y": {
"field": "y2",
"aggregate": "average",
"type": "quantitative",
"axis": {
"orient": "right",
"format": "s",
"title": "avg production budget in $"
}
}
}
}
]
}
],
"resolve": {"scale": {"y": "independent"}}
}

Related

Legend Series Doubled in Line Chart

I've been trying to edit my legend on a line chart to use different symbols for each field in the series. My output on the actual chart is showing correctly, where each series had a different symbol, but my legend duplicates the series, one showing the original shapes with the correct colors, the other showing the correct shapes with the wrong color (just black). Am I missing something about how these properties need to be combined so it's not duplicated? Thanks in advance for the help. Link to online editor
Doubled Legend Series Image
(also how do I get images to just show up in the post??)
Thanks,
Bryan
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "data/barley.json"},
"layer": [
{
"mark": {"type": "line", "tooltip": true, "interpolate": "linear"},
"encoding": {
"stroke": {"field": "site", "type": "nominal", "legend": null},
"opacity": {
"condition": {
"test": {"field": "__selected__", "equal": "false"},
"value": 0.3
},
"value": 1
}
}
},
{
"mark": {"type": "point"},
"encoding": {
"shape": {"field": "site", "type": "nominal"},
"color": {"field": "site", "type": "nominal"},
"opacity": {
"condition": {
"test": {"field": "__selected__", "equal": "false"},
"value": 0.3
},
"value": 1
}
}
}
],
"encoding": {
"y": {
"field": "variety",
"type": "nominal",
"axis": {"grid": true},
"sort": {
"op": "average",
"field": "All Except Difference",
"order": "descending"
}
},
"x": {
"field": "yield",
"type": "quantitative",
"sort": {
"op": "average",
"field": "All Except Difference",
"order": "descending"
},
"scale": {"zero": false}
}
}
}

Vega-lite: How to show multiple "color" legends for multi-layer scatter plot?

My vega lite json: Open the Chart in the Vega Editor
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"layer": [
{
"data": {"url": "data/cars.json"},
"params": [
{
"name": "grid",
"select": "interval",
"bind": "scales"
}
],
"mark": "circle",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {
"field": "Horsepower",
"type": "quantitative",
"scale": {
"range": ["blue", "blue"]
}
}
}
},
{
"data": {"url": "data/cars.json"},
"mark": "circle",
"encoding": {
"x": {"field": "Miles_per_Gallon", "type": "quantitative"},
"y": {"field": "Acceleration", "type": "quantitative"},
"color": {
"field": "Displacement",
"type": "quantitative",
"scale": {
"range": ["black", "black"]
}
}
}
}
]
}
I'm displaying 2 layers of scratter plot, so I want it to have 2 legend color bars.
When I use "color", the second legend is merged, and overriden by the first one.
When I change to use "fill", I manage to have 2 different color bars. But what if I have 4 layers, how to do it?
You need to add the resolve property.
"resolve": {"legend":{"color": "independent"}, "scale": {"color": "independent"} }
Sample on vega editor:
Open the Chart in the Vega Editor

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).

Is it possible to apply the same condition as color encoding for legend

My source code is following
"transform": [
{
"window": [
{
"op": "rank", "field": "Value", "as": "_rank"
}
],
"sort": [
{
"field": "Value",
"order": "descending"
}
]
}
],
"encoding": {
"color": {
"field": "_rank",
"condition": {
"test": "datum._rank>5",
"value": "grey"
}
},
"x": {
"field": "Week",
"type": "nominal",
"axis": {
"labelAngle": 0
}
},
"y": {
"field": "Value",
"type": "quantitative",
"axis": {
"grid": false
}
}
},
"layer": [
{
"mark": {
"type": "bar",
"tooltip": true
}
},
{
"mark": {
"type": "text",
"align": "center",
"baseline": "middle",
"dx": 0,
"dy": -5,
"tooltip": true
},
"encoding": {
"text": {
"field": "Value"
}
}
}
]
I put a condition for the color encoding to show anything but top5 to show in different colors and any values that are not top5 should be grey.
"color": {
"field": "_rank",
"condition": {
"test": "datum._rank>5",
"value": "grey"
}
}
It is all good for the bars but the legends don't generate with the same conditions.
Is it possible to extend the same top5 logics for the legend's color as well? i.e. anything <5 are grey in color (each) in legend and everything else is the same color as the condition (currently this part is getting generated)
Editor
The legend colors will reflect the color scale that you specify, and not reflect conditions.
The easiest way to do what you want is likely by setting the range for your color scheme; for example:
{
"data": {"url": "data/cars.json"},
"mark": "point",
"encoding": {
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"},
"color": {
"field": "Origin", "type": "nominal",
"scale": {"range": ["purple", "#ff0000", "teal"]}
}
}
}
You'll have to modify the specified colors based on how many color categories you have in your data.

Minimum value for y-axis in Vega lite

I have a line chart with stock ticks based on this examples: https://vega.github.io/vega-lite/examples/interactive_multi_line_pivot_tooltip.html
I'm trying to set a min. val. for the y-axis and have tried the below:
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {
"field": "price",
"type": "quantitative",
"scale": {"domain": [150,350]},
},
},
This works with negative values like -150 but not positive. Also my tooltip disappears when setting the y variables..
Setting the scale domain appears to work with the example you linked to (editor):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/stocks.csv"},
"width": 400,
"height": 300,
"encoding": {"x": {"field": "date", "type": "temporal"}},
"layer": [
{
"encoding": {
"color": {"field": "symbol", "type": "nominal"},
"y": {
"field": "price",
"type": "quantitative",
"scale": {"domain": [100, 500]}
}
},
"layer": [
{"mark": {"type": "line", "clip": true}},
{
"transform": [{"filter": {"selection": "hover"}}],
"mark": {"type": "point", "clip": true}
}
]
},
{
"transform": [{"pivot": "symbol", "value": "price", "groupby": ["date"]}],
"mark": "rule",
"encoding": {
"opacity": {
"condition": {"value": 0.3, "selection": "hover"},
"value": 0
},
"tooltip": [
{"field": "AAPL", "type": "quantitative"},
{"field": "AMZN", "type": "quantitative"},
{"field": "GOOG", "type": "quantitative"},
{"field": "IBM", "type": "quantitative"},
{"field": "MSFT", "type": "quantitative"}
]
},
"selection": {
"hover": {
"type": "single",
"fields": ["date"],
"nearest": true,
"on": "mouseover",
"empty": "none",
"clear": "mouseout"
}
}
}
]
}
Note that I also set the clip mark property to hide marks outside the axis boundaries.