Directly support display MIME types for Vega and Vega-lite JSON rendering?
vsivsi opened this issue · 4 comments
Hi, I've finally worked out how to use gophernotes to display Vega / VegaLite SVG graphics, (crudely) similar to what the Altair Python package can do. This works "out of the box" in Nteract and JupyterLab. In classic Jupyter notebooks I believe it requires installing a Jupyter extension to support Vega(lite).
Anyway, thanks to the excellent example documentation for the Gophernotes display
support package, I was able to figure out how to make this work:
// Support for Vega...
type Vega struct {
Json map[string]interface{}
}
func (v Vega) SimpleRender() display.MIMEMap {
return display.MIMEMap{
`application/vnd.vega.v5+json`: v.Json,
`text/plain`: "<Vega 5 object>",
}
}
// ...and VegaLite
type VegaLite struct {
Json map[string]interface{}
}
func (vl VegaLite) SimpleRender() display.MIMEMap {
return display.MIMEMap{
`application/vnd.vegalite.v4+json`: vl.Json,
`text/plain`: "<VegaLite 4 object>",
}
}
To use, simply create and populate one of the above types:
import "encoding/json"
g := []byte(`
{
"$schema": "https://vega.github.io/schema/vega-lite/v2.0.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": 19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"}
}
}`)
vl := VegaLite{}
err := json.Unmarshal(g, &vl.Json)
vl
It would be cool if this was actually built into Gophernotes, or at least documented, since Vega(Lite) are pretty world class declarative plotting libraries and this opens them up for use with gophernotes!
Heres what it looks like in an actual notebook:
https://gist.github.com/vsivsi/f63be32d037e3effcd7c0e04aacda2cf
Definitely very useful!
Also, the structs Vega
and VegaLite
you wrote above are perfect for inclusion in Gophernotes, and they do not even depend on some Vega library.
The only part I did not understand is: how do you configure jupyter to make it recognize MIME types application/vnd.vega.v5+json
and application/vnd.vegalite.v4+json
?
I.e. does jupyter know about them "out of the box", or you need to execute some procedure?
Jupyterlab and Nteract both support it out-of-the-box. Apparently their front-end JS bundles already include recent versions of Vega and VegaLite. To make it work with classic Jupyter notebooks you need to install a Jupyter extension. I think this is the one, but I haven't tried it.
After posting I realized that the wrapping struct in my code is redundant. This works just as well:
import "encoding/json"
type VegaLite map[string]interface{}
func (v VegaLite) SimpleRender() display.MIMEMap {
return display.MIMEMap{
"application/vnd.vegalite.v4+json": v,
"text/plain": "<VegaLite 4 object>",
}
}
graph := []byte(`
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.0.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"a": "A", "b": 28},
{"a": "B", "b": 55},
{"a": "C", "b": 43},
{"a": "D", "b": 91},
{"a": "E", "b": 81},
{"a": "F", "b": 53},
{"a": "G", "b": 19},
{"a": "H", "b": 87},
{"a": "I", "b": 52}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "a", "type": "ordinal"},
"y": {"field": "b", "type": "quantitative"}
}
}`)
v := VegaLite{}
json.Unmarshal(graph, &v)
v