The "line chart" demo works fine, and is expressed in javascript, as in getting_started.html.
... but when I replace "data" field from URL to inline values, it shows only the axys, no chart into.
It works: "data":{"url":"https://vega.github.io/vega-lite/examples/data/stocks.csv"},
It not works:
var vlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Google's stock price over time.",
"data": {"values": [
{"symbol":"MSFT","date":"Jan 1 2000","price":39.81},
{"symbol":"MSFT","date":"Feb 1 2000","price":36.35},
{"symbol":"MSFT","date":"Mar 1 2000","price":43.22},
{"symbol":"MSFT","date":"Apr 1 2000","price":28.37},
{"symbol":"MSFT","date":"May 1 2000","price":25.45}
]},
"transform": [{"filter": "datum.symbol==='GOOG'"}],
"mark": "line",
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "price", "type": "quantitative"}
}
};
There are an error at console, that not make sense:
WARN Infinite extent for field "date": [Infinity, -Infinity]
Your specification only contains rows with symbol="MSFT". It also contains a filter transform, {"filter": "datum.symbol==='GOOG'"}, which removes all rows except those with symbol="GOOG". The result is there is no data left to plot.
The warning you see comes from the fact that axis extent is determined from the data, and when there is no data, the extent is left at [-Infinity, Infinity].
If you remove or modify this filter statement, the chart will work. For example:
vlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Google's stock price over time.",
"data": {"values": [
{"symbol":"MSFT","date":"Jan 1 2000","price":39.81},
{"symbol":"MSFT","date":"Feb 1 2000","price":36.35},
{"symbol":"MSFT","date":"Mar 1 2000","price":43.22},
{"symbol":"MSFT","date":"Apr 1 2000","price":28.37},
{"symbol":"MSFT","date":"May 1 2000","price":25.45}
]},
"transform": [{"filter": "datum.symbol==='MSFT'"}],
"mark": "line",
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {"field": "price", "type": "quantitative"}
}
};
The result looks like this (Open the Chart in the Vega Editor):
Need only to comment the "magic line"
// "transform": [{"filter": "datum.symbol==='GOOG'"}],
Please explain! This is a Wiki answer
According to the Vega docs for the Date type, the date needs to be a valid Javascript Date object or timestamp.
A valid JavaScript Date object or timestamp. As JSON does not support date values natively, within a Vega specification a date-time value can be expressed either as a numeric timestamp (the number of milliseconds since the UNIX epoch, as produced by the Date.getTime() method) or using a signal expression (such as {"signal": "datetime(2001, 2, 3)"})
Related
I'm trying to build a chart from live json data but the format has the date data as the key for other nested data, the essential structure is:
{
"Meta": {
"Frequency": "Monthly",
"Time zone": "EST"
},
"Monthly data": {
"2022-01-01": {
"valueA": "13.44",
"valueB": "97.68"
},
"2021-12-01": {
"valueA": "11.39",
"valueB": "99.81"
},
"2021-11-01": {
"valueA": "12.31",
"valueB: "93.56"
},
"2022-10-01": {
"valueA": "15.42",
"valueB": "98.54"
}
}}
I'm trying to get into a format where i can encode the date on the x-axis, but can't as there is no column name/key and it isn't an array so cannot flatten. Then would be looking to encode any normal nested field (eg valueA) on the y-axis, but can't find any documentation or examples on this specific case. I don't need any information in the metadata part so can be ignored.
The only similar comment on this I've found is https://github.com/vega/vega/issues/1360, I can get this to work as a test but typing out each monthly date to map of course removes the benefit of live data and wouldn't allow high-frequency data.
Is there a way for this to be mapped automatically?
No, I don't believe this is currently possible. You could potentially do it with the flatten transform if there were a vega expression for extracting keys from an object, but support for this has not yet been added to vega expressions (see https://github.com/vega/vega/issues/3207 for a similar request).
Unfortunately, I believe the best you can do currently is use the fold transform while specifying the keys explicitly. For example:
{
"data": {
"values": {
"2022-01-01": {"valueA": "13.44", "valueB": "97.68"},
"2021-12-01": {"valueA": "11.39", "valueB": "99.81"},
"2021-11-01": {"valueA": "12.31", "valueB": "93.56"},
"2022-10-01": {"valueA": "15.42", "valueB": "98.54"}
}
},
"transform": [
{
"fold": ["2021-11-01", "2021-12-01", "2022-01-01", "2022-10-01"],
"as": ["date", "value"]
},
{"calculate": "datum.value.valueA", "as": "valueA"},
{"calculate": "datum.value.valueB", "as": "valueB"}
],
"mark": "bar",
"encoding": {
"y": {"field": "date"},
"x": {"field": "valueA"},
"x2": {"field": "valueB"}
}
}
I'm trying to calculate a value for domainMax on the Y-axis scale. I tried the following example where I want the Y-axis domainMax to be one greater than the maximum value in the dataset field named "value". The example produces the error 'Unrecognized signal name: "domMax"'. How can I get it to work?
{
"data": {
"values": [
{"date": "2021-03-01T00:00:00", "value": 1},
{"date": "2021-04-01T00:00:00", "value": 3},
{"date": "2021-05-01T00:00:00", "value": 2}
]
},
"transform": [
{ "calculate": "max(datum.value)+1","as": "domMax"}
],
"mark": "line",
"encoding": {
"x": {
"field": "date",
"type": "temporal"
},
"y": {"field": "value", "type": "quantitative",
"scale": {"domainMax": {"expr": "domMax"}}
}
}
}
This transform
"transform": [
{ "calculate": "max(datum.value)+1","as": "domMax"}
]
adds a new column to your data set - it does not create a new signal. You can check that in the editor. Go to the DataViewer tab and select data_0 from the drop down. Can you see the new domMax column?
Signals are a different thing entirely - have a look here in the documentation. Note that the link points to Vega, not Vega-Lite. (Vega-Lite specifications are compiled to Vega.)
Vega-Lite does not let you declare signals; you declare parameters instead. Here is another example using the domMax parameter. Vega-Lite parameters are translated to Vega signals.
It looks like you are trying to derive the value of your parameter/signal from the data. I am not sure you can do that in Vega-Lite.
On the other hand it's very easy in Vega. For example you could use the extent transform:
https://vega.github.io/vega/docs/transforms/extent/
Side comment - while Vega specifications are more verbose you can sometimes find their primitives simpler and a good way to understand how the visualisation works. (You can see compiled Vega in the editor.)
I tried to get a custom domain based on the data but hit the same limitations as you did.
In my case, I update the data from the outside a bit like the streaming example. I compute the domain from the outside and modify them in the visualization with params. This is quite easy as vega-lite params are exposed as vega signals.
This is the gist of the layout:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"params": [
{
"name": "lowBound",
"value": -10
},
{
"name": "highBound",
"value": 100
}
],
../..
"vconcat": [
{
"name": "detailed",
../..
"layer": [
{
../..
"mark": "line",
"encoding": {
"y": {
"field": "value",
"title": "Temperature",
"type": "quantitative",
"scale": {
"domainMin": {
"expr": "lowBound"
},
"domainMax": {
"expr": "highBound"
}
}
},
...
The lowBound and highBound are dynamically changed through vega signals. I change them with the regular JS API.
You can add a param to pan and zoom in case your hard coded values are less than ideal.
"params": [{"name": "grid", "select": "interval", "bind": "scales"}],
Open the Chart in the Vega Editor
I'd like to have multiple time series drawn by row channel ("field": "PLATFORM"), x channel: ("field": "estimating-date-time"), and y channel ("field": "eta-variance").
Besides the lines of time series, I'd like to draw a vertical line at x = arrvial-time which is another field, conditioned by the value of "PLATFORM".
The following is a working example of the charts except the desirable vertical line in each chart:
vega-lite for multiple time series
Below is the desired effect with manual illustration:
My question is how to add the vertical line for each chart to the specifications?
The challenge to me is that the field "arrival-time" from which the value used to draw the vertical line is not the same as the chart's x channel "estimating-data-time". I've found examples of drawing such a line using a value related to the same x channel.
You can do this by nesting a layer specification within a facet operator; something like this (open in editor):
{
"facet": {"row": {"field": "PLATFORM"}},
"spec": {
"height": 80,
"width": 300,
"layer": [
{
"mark": "line",
"encoding": {
"x": {"field": "estimating-date-time", "type": "temporal"},
"y": {"field": "ETA-variance", "type": "quantitative"}
}
},
{
"mark": "rule",
"encoding": {"x": {"field": "arrival-time", "type": "temporal"}}
}
]
},
"data": {...}
}
I am asking this question as a follow-up to :
Original Question
The basic requirement is very simple:
To display sport competition results on a graph, based on human readable time period.
For example top 8 Men's 800m , from Rio 2016.
Rank Name Time
1 David Lekuta Rudisha 1:42.15
2 Taoufik Makhloufi 1:42.61
3 Clayton Murphy 1:42.93
4 Pierre-Ambroise Bosse 1:43.41
5 Ferguson Cheruiyot Rotich 1:43.55
6 Marcin Lewandowski 1:44.20
7 Alfred Kipketer 1:46.02
8 Boris Berian 1:46.15
There were some issues such as :
The zero-point for a timestamp is not well defined, so a bar mark is not a good fit
for temporal data.
I will appreciate any workaround to display to display time-period results to solve such a problem.
Thanks
Yoav
Vega-lite does not have any native data type to represent time periods, it only has a data type representing timestamps. When using bar marks for timestamps, the zero-point is context-dependent, and so Vega-Lite will not try to infer it for you.
For your data, I would probably approach it as follows:
Use a parse argument in your data to specify the expected format of your timestamps, as in the original question
Use a timeUnit transform to manually compute a relevant zero-point for your data: here a yearmonthdate timeUnit works well because it strips away hours, minutes, and seconds.
Use a y2 encoding in your bar to specify this zero-point for your bar mark.
Put together, the result might look something like this (Vega Editor):
{
"data": {
"values": [
{"Rank": 1, "Name": "David Lekuta Rudisha", "Time": "1:42.15"},
{"Rank": 2, "Name": "Taoufik Makhloufi", "Time": "1:42.61"},
{"Rank": 3, "Name": "Clayton Murphy", "Time": "1:42.93"},
{"Rank": 4, "Name": "Pierre-Ambroise Bosse", "Time": "1:43.41"},
{"Rank": 5, "Name": "Ferguson Cheruiyot Rotich", "Time": "1:43.55"},
{"Rank": 6, "Name": "Marcin Lewandowski", "Time": "1:44.20"},
{"Rank": 7, "Name": "Alfred Kipketer", "Time": "1:46.02"},
{"Rank": 8, "Name": "Boris Berian", "Time": "1:46.15"}
],
"format": {"parse": {"Time": "date:'%M:%S.%L'"}}
},
"transform": [
{"timeUnit": "yearmonthdate", "field": "Time", "as": "zeropoint"}
],
"mark": "bar",
"encoding": {
"x": {"field": "Name", "type": "nominal"},
"y": {
"field": "Time",
"timeUnit": "minutessecondsmilliseconds",
"type": "temporal",
"title": "Time"
},
"y2": {"field": "zeropoint", "timeUnit": "minutessecondsmilliseconds"}
},
"$schema": "https://vega.github.io/schema/vega-lite/v4.0.0.json"
}
I want to combine facet operators (row, column) along with the repeat operator to create 'small multiple' charts that display different data variables. This works for some types of charts (e.g. simple bar charts) but not others (i.e. histograms). For example, below I have modified the 'Horizontally repeated charts' example (https://vega.github.io/vega-lite/examples/repeat_histogram.html).
{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"repeat": {"column": ["Horsepower","Miles_per_Gallon", "Acceleration"]},
"spec": {
"data": {"url": "data/cars.json"},
"mark": "bar",
"encoding": {
"row":{"field":"Origin", "type":"nominal"},
"x": {
"field": {"repeat": "column"},
"bin": true,
"type": "quantitative"
},
"y": {"aggregate": "count","type": "quantitative"}
}
}
}
I expect three rows, with each row showing histograms of cars from different countries. However, this code results in the error :
'Error: Undefined data set name: "scale_child_Miles_per_Gallon_child_main"'
I'm reasonably sure that this worked with Vega-Lite v2. Is there some reason that the aggregate / bin operator can't work with a combination of facets and repeats?