How to bottom middle align a legend in Vega Lite? - vega-lite

In Vega Lite, I am trying to align my legend to the middle of this chart. I need something like an anchor parameter for the legend, but I can only find titleAnchor.
Chart with Legend
"legend": {
"title": "Signed NDA",
"orient": "bottom",
"titleAnchor": "middle"
}
This is how my legend looks right now. Anyone know how to do this?

This is actually possible within Vega 5.0, legend layout property, by setting the anchor property to "middle", in the legend's layout config.
Providing layout doesn't seem to be directly supported by Vega-Lite yet, but it is possible to propagate a layout definition from Vega-Lite to Vega.
Following Jake's answer, in Vega-Lite editor:
{
"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"}
},
"height": 300,
"width": 400,
"config": {
"legend": {"orient": "bottom", "layout": {"bottom": {"anchor": "middle"}}}
}
}
Specifying the config at the end basically allows you to customize how the orient "bottom" should look.

There is no option to anchor the legend in the bottom center, but you can set orient: "none" and use the legendX and legendY properties to locate it exactly where you would like. For example (vega editor):
{
"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",
"legend": {
"orient": "none",
"direction": "horizontal",
"legendX": 120,
"legendY": 340,
"title": null
}
}
},
"height": 300,
"width": 400
}

Related

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

How to make ticks fill the band width in Vega-lite

I'm trying to use tick marks to separate a stacked bar but I can't figure out how to make the tick marks full width of the responsive bar mark (example).
The reason I am doing this is I want the ticks to look like separators between the stacked bars. Another approach I have tried is setting stroke (example) on the bar mark but this adds a border to the left and right of the bars which I don't want. I only want the separator to be between two bars vertically.
You can simply add the width config inside your mark objects.
Refer the below config or editor:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Shows the relationship between horsepower and the numbver of cylinders using tick marks.",
"width": "container",
"data": {"url": "data/cars.json"},
"layer": [
{
"mark": {"type": "bar", "width": 50},
"encoding": {
"y": {"field": "Horsepower", "type": "quantitative"},
"x": {"field": "Cylinders", "type": "ordinal"}
}
},
{
"mark": {"type": "tick", "color": "tomato", "width": 50},
"encoding": {
"y": {"field": "Horsepower", "type": "quantitative", "stack": true},
"x": {"field": "Cylinders", "type": "ordinal"}
}
}
]
}

How to position image on top left corner?

I am trying to position an overlayed image in the top left corner of my chart.
To that end, I am using the aggregate transform directly in the encoding of channels x, and y of the image, as it can be seen in this example.
Here is the specific code snippet of the image mark:
{
"mark": {"type":"image", "width":50, "align":"left"},
"encoding": {
"x": {"aggregate": "min", "field":"months", "type":"temporal"},
"y": {"aggregate": "max", "field":"price", "type":"quantitative"},
"url": {"value": "data/ffox.png"}
}
}
The image, is still appearing at around the middle of the y axis, and not at the top:
Image in the middle, not top
How can I place it at the top left corner?
The image is not getting displayed in top because height is not provided for that image mark. Because of that image is getting displayed in center, if you inspect your image you will see some default height. Image for default height
To bring your image on top left, just provide height as done below:
{
"mark": {"type": "image", "width": 50, "align": "left", "height": 40},
"encoding": {
"x": {"aggregate": "min", "field": "months", "type": "temporal"},
"y": {"aggregate": "max", "field": "price", "type": "quantitative"},
"url": {"value": "data/ffox.png"}
}
}
But with the aggregation specified, your image might slighly go outside the chart view, so you can provide the following way as well where you provide hardcoded x and y value for the image mark. Which will always show appropriate position for your image. Below is the code and editor url:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.1.0.json",
"width": "container",
"data": {"url": "data/sp500.csv"},
"transform": [{"timeUnit": "utcyearmonth", "field": "date", "as": "months"}],
"layer": [
{
"encoding": {
"x": {"field": "months", "type": "temporal", "title": null},
"y": {"field": "price", "type": "quantitative", "title": "Price"}
},
"layer": [
{
"mark": {
"type": "area",
"color": "#3873b9",
"fillOpacity": 0.7,
"tooltip": true
}
},
{"mark": {"type": "line", "color": "#4883c9"}}
]
},
{
"mark": {"type": "image", "width": 50, "height": 40, "align": "left"},
"encoding": {
"x": {
"datum": 0,
"type": "quantitative",
"scale": {"domain": [0, 1]},
"axis": null
},
"y": {
"datum": 0.8,
"type": "quantitative",
"scale": {"domain": [0, 1]},
"axis": null
},
"url": {"value": "data/ffox.png"}
}
}
],
"resolve": {
"axis": {"x": "independent", "y": "independent"},
"scale": {"x": "independent", "y": "independent"}
}
}
As wahab memon mentioned, the image went middle due to the missing of height property.
Simply adding back "height": 50, "baseline": "alphabetic" to mark can fix the position and the overshoot issue as well. (no need for hard coding)
Last but not least, the original code has redundant nested layers, please see the complete code below:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.1.0.json",
"width": "container",
"data": {"url": "data/sp500.csv"},
"transform": [{"timeUnit": "utcyearmonth", "field": "date", "as": "months"}],
"encoding": {
"x": {"field": "months", "type": "temporal", "title": null},
"y": {"field": "price", "type": "quantitative", "title": "Price"}
},
"layer": [
{
"mark": {
"type": "area",
"color": "#3873b9",
"fillOpacity": 0.7,
"tooltip": true
}
},
{"mark": {"type": "line", "color": "#4883c9"}},
{
"mark": {"type": "image", "width": 50, "align": "left", "height": 50, "baseline": "alphabetic"},
"encoding": {
"x": {"aggregate": "min", "field": "months", "type": "temporal"},
"y": {"aggregate": "max", "field": "price", "type": "quantitative"},
"url": {"value": "data/ffox.png"}
}
}
]
}
Vega Editor

Vega-Lite: Is it possible to have images as labels in a line chart?

I want to have images as my axis labels. I tried to use the image mark, but that did not work and that is kind of expected. Label expression is also something I tried, but that did not work if I want it to be an image. What else could I tried or is it possible at all?
Line chart example
Using the same technique in another answer, an image axis can be added via an extra layer:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"x": 0.5, "y": 0.5, "img": "data/ffox.png"},
{"x": 1.5, "y": 1.5, "img": "data/gimp.png"},
{"x": 2.5, "y": 2.5, "img": "data/7zip.png"}
]
},
"layer": [{
"mark": {"type": "image", "width": 50, "height": 50},
"encoding": {
"x": {"field": "x", "type": "quantitative"},
"y": {"field": "y", "type": "quantitative"},
"url": {"field": "img", "type": "nominal"}
}
}, {
"transform": [{"calculate": "-.2", "as": "axis"}],
"mark": {"type": "image", "width": 25, "height": 25},
"encoding": {
"x": {"field": "x", "type": "quantitative", "axis":{"labelExpr": "", "title": null}},
"y": {"field": "axis", "type": "quantitative", "scale": {"domain": [0, 2.5]}},
"url": {"field": "img", "type": "nominal"}
}
}],
"resolve": {"scale": {"y": "shared"}}
}
Vega Editor
===== 2021-07-20 =====
Your BarChart's x encoding uses the x field which is not evenly distributed, so it is misaligned.
If you do have the a field shown in your editor, simplest way is to replace the encoding as "x": {"field": "a", "type": "ordinal", "axis": null}
Vega Editor
Even the a field was not there, you may wanna add such a field for aligning, or even ordering, the image axis.
The last resort I can think of is window transform which is an overkill, but adds no extra value as well:
Vega Editor

vega-lite: is it possible to render only the legend without the reference chart?

I'm building a wireframe of an HTML page in which I have some vega-lite charts.
Is there a way to render only the legend of a chart? If yes, how to?
I don't know of a built-in way to display only the legend, but you can hack it by removing all positional encodings, setting the mark opacity to zero, and setting the view width/height to 0. For example, here is a way to generate just the legend from this Vega-Lite example:
{
"data": {
"url": "data/penguins.json"
},
"mark": {"type": "point", "opacity": 0},
"encoding": {
"color": {"field": "Species", "type": "nominal"},
"shape": {"field": "Species", "type": "nominal"}
},
"config": {"view": {"width": 0, "height": 0}}
}