概要
Vegaの記法でKibanaのVisualizationをやりくりするのって、まだ慣れませんね。
6.2.0では、Vegaが使えるようになったということで、ぐっと可視化力があがったと思います。
以前は、こんな質問がElasticのフォーラムに上がっていました。
当時はうまい解決策が見つからなかったようですが、今ならVegaでやれそうだ、ということでやってみた。
先に結論
データの準備
データについては、気象庁の「過去の気象データ・ダウンロード」からCSVを頂戴します。
1年分の東京の平均気温のCSVをダウンロードしました。
これをElasticsearchに入れて、検索するとこう見えます。
field | 説明 |
---|---|
temp_value | 平均気温 |
timestamp | 時系列の元となるDate値 |
{
"_index": "doc",
"_type": "weather",
"_id": "0",
"_score": 1,
"_source": {
"temp_value": 5.6,
"timestamp": "2017-02-07T00:00:00"
}
},
{
"_index": "doc",
"_type": "weather",
"_id": "14",
"_score": 1,
"_source": {
"temp_value": 6.1,
"timestamp": "2017-02-21T00:00:00"
}
},
{
"_index": "doc",
"_type": "weather",
"_id": "19",
"_score": 1,
"_source": {
"temp_value": 8.6,
"timestamp": "2017-02-26T00:00:00"
}
}
Vegaの記述
今回は、3つのグラフを重ね合わせます。
No | グラフ | 用途 |
---|---|---|
1 | point | 平均気温を丸でプロットする |
2 | line | 各月の平均気温を線で結ぶ |
3 | rule | 誤差棒相当の縦線を描画する |
データ取得部分
"data": {
"url": {
"%context%": true,
"%timefield%": "timestamp",
"index": "doc",
"body": {
"aggs": {
"time_buckets": {
"date_histogram": {
"field": "timestamp",
"interval": "1M",
"extended_bounds": {
"min": {"%timefilter%": "min"},
"max": {"%timefilter%": "max"}
},
"min_doc_count": 0
},
"aggs": {"avg_temp": {"avg": {"field": "temp_value"}}}
}
},
"size": 0
}
},
"format": {"property": "aggregations.time_buckets.buckets"}
}
各月の平均気温を求めるので、月単位のAggregationの下にAverageのAggregationを追加する形となります。
"aggs" : { "avg_temp": ... }
とした、avg_tempは後で使うので、しっかり覚えておきます。
誤差棒部分のデータを作る
今回は平均気温しかIndexしていないので、上下の誤差の値がありません。
適当に下に-1、上に+2とする例を示します。transformの部分に注目してください。
"transform": [
{"calculate": "datum.avg_temp.value-1", "as": "lower"},
{"calculate": "datum.avg_temp.value+2", "as": "upper"}
],
datum.avg_temp.valueとすることで、上のdataで取得したavg_tempのAggregation結果にアクセスできます。
asで、名前を付けて保存します。lowerとupperとしていますが、これも後で使います。
Layer
上で取得したdata、加工したデータをもとに、いよいよグラフを書いていくところです。
Layerで複数のグラフを重ねていくわけですが、順に見ていきます。
point
項目 | 値 | 説明 |
---|---|---|
type | point | ポイントをプロットするタイプを宣言する |
filled | true or false | trueにしておくと●、falseにしておくと○ |
size | 100 | 円の大きさを指定する |
date_histogramで取得した時系列の値はkey, "timeUnit": "yearmonthdate"でx軸に描画できます。
y軸の値は、先に宣言していたavg_temp.valueを使用します。
{
"mark": {"type": "point", "filled": false, "size": 100},
"encoding": {
"x": {
"field": "key",
"timeUnit": "yearmonthdate",
"scale": {"zero": false},
"axis": {"title": "年月"}
},
"y": {"field": "avg_temp.value"},
"color": {"value": "black"}
}
},
line
先のpointと違うのは、typeがlineになったこと、colorがredになったぐらいで特に変わりはありません。
{
"mark": {"type": "line"},
"encoding": {
"x": {
"field": "key",
"timeUnit": "yearmonthdate",
"scale": {"zero": false},
"axis": {"title": "年月"}
},
"y": {"field": "avg_temp.value"},
"color": {"value": "red"}
}
}
rule
いよいよ誤差棒的なグラフを書きます。
pointやlineとx軸の設定部分については同じですが、yのところが違います。
これまで、yは1つの指定でしたが、y2の指定もすることになります。これで縦線が引けるということですね。
項目 | 値 | 説明 |
---|---|---|
y.field | upper | trasformで計算して取得した avg_tempの値に+2した数値 |
y2.field | lower | trasformで計算して取得した avg_tempの値に-1した数値 |
{
"mark": "rule",
"encoding": {
"x": {
"field": "key",
"timeUnit": "yearmonthdate",
"axis": {"title": "年月"}
},
"y": {"field": "upper", "type": "quantitative"},
"y2": {"field": "lower", "type": "quantitative"}
}
}
最後に
今回は固定値でプラスマイナスしていますが、標準偏差から求めるなり、適当に値をセットしてやれば誤差棒は描けると思います。
なお、使用したものは、こちらにあげておきます。
Vegaにはほかにもいろいろな見せ方があるので、おいおい試していきたいですね!