How to position image on top left corner? - vega-lite

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

Related

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

How to center the horizontal axis

Is it possible to vertically centered the horizontal axis ? positive values stay on the top of axis, negative the bottom.
I don't find any example like this.
You can accomplish this using the axis.offset property. For example (open in editor):
{
"width": 300,
"height": 150,
"data": {"sequence": {"start": 0, "stop": 12.7, "step": 0.1, "as": "x"}},
"transform": [{"calculate": "sin(datum.x)", "as": "sin(x)"}],
"mark": "line",
"encoding": {
"x": {
"field": "x",
"type": "quantitative",
"axis": {"offset": -75, "grid": false}
},
"y": {"field": "sin(x)", "type": "quantitative", "axis": {"grid": false}}
},
"view": {"stroke": 0}
}

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.

Brush zooming in X and Y in Vega-lite

In Vega-lite, is it possible to zoom in to a plot with a brush in the X and Y direction at the same time?
Using this example as a base:
https://vega.github.io/vega-lite/examples/interactive_overview_detail.html
I tried encoding the Y, but I'm not sure how to point "scale": {"domain": {"selection": "brush"}} in the Y axis direction.
unexpected result
If not, is it possible to achieve similar results with the "bind": "scales"? The goal is to have a "key-map" of the chart with a zoom-in, and a small box showing where the zoom is on the broader time-series.
Code I've been trying with that example:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/sp500.csv"},
"vconcat": [{
"width": 480,
"mark": "area",
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"scale": {"domain": {"selection": "brush"}},
"axis": {"title": ""}
},
"y": {"field": "price",
"type": "quantitative",
"scale": {"domain": {"selection": "brush"}}
}
}
}, {
"width": 480,
"height": 60,
"mark": "area",
"selection": {
"brush": {"type": "interval", "encodings": ["x","y"]}
},
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {
"field": "price",
"type": "quantitative",
"axis": {"tickCount": 3, "grid": false}
}
}
}]
}`
You can do this by specifying the field or the encoding within the domain; for example:
"domain": {"selection": "brush", "encoding": "y"}
Putting this into your example looks like this (view live):
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"data": {"url": "data/sp500.csv"},
"vconcat": [
{
"width": 480,
"mark": "area",
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"scale": {"domain": {"selection": "brush", "encoding": "x"}},
"axis": {"title": ""}
},
"y": {
"field": "price",
"type": "quantitative",
"scale": {"domain": {"selection": "brush", "encoding": "y"}}
}
}
},
{
"width": 480,
"height": 60,
"mark": "area",
"selection": {"brush": {"type": "interval", "encodings": ["x", "y"]}},
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {
"field": "price",
"type": "quantitative",
"axis": {"tickCount": 3, "grid": false}
}
}
}
]
}

Is there a way to add a line break between the plot and X axis (vega-lite)

I am not sure if it makes sense but will it be possible to add a line break between the start of the plot and the X-axis.
For e.g.
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": {"step": 10},
"height": 120,
"data": {"url": "data/cars.json"},
"mark": "area",
"encoding": {
"x": {"field": "Name", "type": "nominal", "scale": {"round": false}},
"y": {"aggregate": "count", "type": "quantitative"}
}
}
Hopeful output:
One way to do this is by adding a scale.domain argument:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": {"step": 10},
"height": 120,
"data": {"url": "data/cars.json"},
"mark": "area",
"encoding": {
"x": {"field": "Name", "type": "nominal", "scale": {"round": false}},
"y": {"aggregate": "count", "type": "quantitative", "scale": {"domain": [-0.5, 6]}}
}
}
Another way to do this is to use the y and y2 encodings to set a bottom value for the area chart:
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": {"step": 10},
"height": 120,
"data": {"url": "data/cars.json"},
"mark": "area",
"transform": [{"calculate": "0.1", "as": "bottom"}],
"encoding": {
"x": {"field": "Name", "type": "nominal", "scale": {"round": false}},
"y": {"aggregate": "count", "type": "quantitative"},
"y2": {"field": "bottom"}
}
}
Another way to do something similar, adding it as another answer to make it convenient for others.
offset property of axis shifts the axis line by fixed pixels, independent of the data. Using offset adds a gap between the x and y axis lines though.
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"width": {"step": 10},
"height": 120,
"data": {"url": "data/cars.json"},
"mark": "area",
"encoding": {
"x": {"field": "Name", "type": "nominal", "scale": {"round": false}, "axis": {"offset": 5}},
"y": {"aggregate": "count", "type": "quantitative"}
}
}