Kotlin / kotlin-jupyter

Kotlin kernel for Jupyter/IPython
Apache License 2.0
1.09k stars 106 forks source link

question: how to render vega-lite (HTML or w MimeType) #396

Open restlessronin opened 1 year ago

restlessronin commented 1 year ago

I'd like to output vega lite graphics ideally for Jupyter (as HTML) but am OK with doing it for JupyterLab (as a Mime type). Is there an example for how to do this somewhere?

ileasile commented 1 year ago

Judging by this example notebook, vega graphics in python is simply rendered to HTML/JS/Images, so it's just a matter of library to support it. As I understand from this page, neither Java nor Kotlin library does exist... So it seems that currently, it's not possible to use it in JVM ecosystem. But we have experimental library which is currently called ggdsl(https://github.com/Kotlin/ggdsl) and supports lets-plot and echarts backends. Maybe it'll be interesting for you

restlessronin commented 1 year ago

Thanks for your response @ileasile

I looked at the page you referenced, and there do seem to be a few JVM options (Vegas, Smile, Hanami, Vizard, Oz), including Java, Scala and several in Clojure, but my base library is in java, and I'd rather not add too much polyglot flavor :-). Plus many of these libraries are no longer actively maintained.

Also, my primary use-case is accessing my base java library from a notebook front end, and kotlin-jupyter is quite handy :-).

I took a look at ggdsl. It looks nice, but I think I'd prefer a vega-lite backend. I'm doing a few non-standard things, and I found it easier to find helpful vega-lite documentation to get started. The lets-plot documentation is great for standard stuff, but I'm not confident that my edge-cases will be easy to specify.

It seems like if I output the right HTML/JS/Images (with supporting mime types for JupyterLab), I should be able to have it rendered as a plot by the jupyter server. Initially, I plan on creating the output HTML/JS etc. by hand and once the usage structure is better understood, I can wrap it in a kotlin DSL.

But I think I need some kind of specialized renderer which is registered in jupyter-kotlin. I was wondering if there were any pointers or samples I could use to get started. I'm guessing that the lets-plot renderer does something similar, but I'm not familiar enough with mutliplatform builds to figure out where in the code I should start looking. I'd be happy to contribute it back to the jupyter-kotlin repo along with usage documentation, once it's done.

ileasile commented 1 year ago

@restlessronin sorry, it seems that I indeed looked through the page unattentively. That's great then. Actually, if you have a JsonObject that contains output with MIME types, i.e.

{
    "text/html": "<p>some html</p>",
    "application/json": { "key": 42 }
}

you can pass it to MimeTypedResultEx, and just place it in the last line of the cell. Jupyter infrastructure will then render it correctly. You can also use other convenience functions and methods from this file such as HTML(...)

But of course, you're not obliged to wrap it manually every time. Say you have some class VegaPlot that has a method toMimeJson(): JsonObject in your library. Then you have two options.

First one: you create a json descriptor of your library and define a renderer in it (see example). Later you can contribute this descriptor to https://github.com/Kotlin/kotlin-jupyter-libraries and it will appear in this repository README.

Another option: you add a dependency on kotlin-jupyter-api to your library and add a class that we call Integration. And describe all the renderers there. We encourage this method, because it is easier to keep everything up-to-date with it. That's the example how renderers in this kind of integration look like.

There is a documentation on both types of integrations here: https://github.com/Kotlin/kotlin-jupyter/blob/master/docs/libraries.md. Sorry that we failed to make it more visible

restlessronin commented 1 year ago

@ileasile thank you! this is what i needed. I had actually found the document on integrations, so it was adequately visible. Somehow i failed to make the connection with what i am trying to do, which is to do a quick prototype visualization where i am constructing a vega-lite spec in the kotlin jupyter notebook itself. My bad.

🙏🏽🙏🏽🙏🏽

restlessronin commented 1 year ago

With a little trial and error, I got vega-lite (via vega-embed) to work in a kotlin jupyter kernel. For other users that might be interested, here is a notebook link showing a simple example.

https://github.com/restlessronin/nb-pub/blob/main/kt-vega.ipynb

Github is not rendering the final vega chart in the notebook display (which I thought it would), but it renders fine on my local jupyter.