janpfeifer / gonb

GoNB, a Go Notebook Kernel for Jupyter
https://github.com/janpfeifer/gonb
MIT License
467 stars 32 forks source link

Support for animated Plotly charts #90

Closed evertoncolling closed 4 months ago

evertoncolling commented 4 months ago

I came across this gem very recently and I'm loving this kernel already! It's really a nice addition to the Go ecosystem.

I come from the Python world, where I'm used to work with timeseries data using interactive plots with Plotly. I found the go-plotly library (https://github.com/MetalBlueberry/go-plotly) that provides decent functionality to generate the plots I need, but as far as I could tell, I can only generate html files that are opened on a browser tab.

Is there any way I could generate a figure and render it directly in a gonb notebook? That would be a killer feature which would allow me to transition some of my data analysis to Go.

PS: I tried the other charting libraries, but static images are not good enough for my use cases.

janpfeifer commented 4 months ago

hey Everton, thanks for the nice words :)

Oh, yes, Plotly is awesome, let me see if I find a way to integrate it to GoNB and then allow for MetalBlueberry/go-plotly to work as well. Hopefully, I can pull this off today, I'll keep you posted.

janpfeifer commented 4 months ago

So, there is an initial version working already, see the tutorial (search for "Plotting with Plotly")

But ... it doesn't save the generate image -- so it needs to be re-run. Nor are the images exported to HTML (when one tries to export the notebook to html). This is complicated, because Jupyter Notebooks won't try to save the javascript generated by the notebook.

I haven't yet figured out an easy fix for those, but if that is not a impediment for your use case ... then I could cut a new version (v0.9.6) as is now.

Would you like to give it a try ? You'll need the version from the HEAD of github:

$ git clone git@github.com:janpfeifer/gonb
$ cd gonb
$ go run . --install 

It doesn't yet allow for Go animations of the plot (re-plotting every few milliseconds), but Plotly javascript based animations should work -- at least the buttons on the plots are responsive.

Pls, let me know how it goes. And if you have a cool plot example, and don't mind sharing, I could add it to the tutorial :)

evertoncolling commented 4 months ago

No worries for not saving the generated image to the notebook file itself, that's quite common for many kernels that render plotly HTML charts. As long as it's rendered properly when the user runs a cell, it's perfectly fine.

When it comes to testing, I didn't managed to get it to work. I've cloned the repo and ran go run . --install from the root folder, but the generated kernelspec points to an invalid path, which makes the kernel fail when I try to start it.

Screenshot 2024-02-18 at 12 54 19

This is the generated kernelspec:

{
    "argv": [
        "/var/folders/z6/jk9dh3xx6s76y96_c3cls3xc0000gn/T/go-build140733839/b001/exe/gonb",
        "--kernel",
        "{connection_file}",
        "--logtostderr"
    ],
    "display_name": "Go (gonb)",
    "language": "go",
    "env": {}
}

Maybe it's something on my system. I don't mind waiting for this to be available on the new version though 🙂

janpfeifer commented 4 months ago

I know what caused it: when you run GoNB with go run it compiles to a temporary directory. If GoNB notices that (by checking if its directory starts with /tmp) it will copy itself during intallation, as opposed to linking to the binary.

In your case since your temporary directory is under /var/folder it didn't catch up on that.

Can you install with go run . --install --force_copy instead ? That trick should do it!

It's good to hear that the save/export is not a requirement, since it greatly simplifies. I still think it would be cool if it did, because it's very useful to write blog posts or simply show the demo to people ... but alas, this probably requires fundamental changes in Jupyter.

evertoncolling commented 4 months ago

Using go run . --install --force_copy did it. The kernelspec was installed properly and I was able to start the kernel. That being said, if I try to run the Plotly example on the tutorial notebook (after installing the updated kernel directly from the repo), I get the following error

image
janpfeifer commented 4 months ago

Ugh, my bad, I should have seen that one coming, apologies.

It is trying to download the new github.com/janpfeifer/gonb/gonbui/plotly package from github, but I haven't created a release from it yet.

To test packages that are local, as when doing these things in Go normally, you need to tell the Go compiler to look for the local copy of package, That can be done in GoNB by adding a cell with the following line:

!*go mod edit -replace=github.com/janpfeifer/gonb=<path_to_gonb_you_cloned>

What this line does is (%help has an entry about it):

Let me know if that works. I just tried it again here, it all worked fine. My test notebook has two cells:

Cell 1:

!*go mod edit -replace=github.com/janpfeifer/gonb=/home/janpf/Projects/gonb

Cell 2:

import (
    "github.com/janpfeifer/gonb/gonbui/plotly"
    grob "github.com/MetalBlueberry/go-plotly/graph_objects"
)

%%
fig := &grob.Fig{
    Data: grob.Traces{
        &grob.Bar{
            Type: grob.TraceTypeBar,
            X:    []float64{1, 2, 3},
            Y:    []float64{1, 2, 3},
        },
    },
    Layout: &grob.Layout{
        Title: &grob.LayoutTitle{
            Text: "A Figure Specified By Go Struct",
        },
    },
}

plotly.DisplayFig(fig)
evertoncolling commented 4 months ago

Pointing to the local version of github.com/janpfeifer/gonb solved it. Interaction is working great, now I can work and inspect data entirely using go notebooks 😎.

Below is a quick test fetching some time series data and visualizing it on the notebook.

image

I also tried to plot the chart directly in VsCode, where I use the Polyglot Notebooks extension that enables me to run any Kernel directly on VsCode and unfortunately, the plot is not shown there. Not a big issue, but just wanted to share this limitation.

image

The advantage of using notebooks on VsCode is that I get code completion from the Go extensions, Copilot, etc. In any case, thanks for extending this already amazing kernel with this new feature 😃

janpfeifer commented 4 months ago

Oh, cool!!

I'm moving ahead and creating the 0.9.6 release then -- btw, it is now also recognizing /var/folders/... as a temporary directory, so next time go run --install will work from your environment.

And, next weekend I'll play with VSCode Polyglot Notebooks, and see if I can make it work. I'll create another issue for that, and mark this one as done.

cheers!

janpfeifer commented 3 months ago

Just an FYI: the HEAD version now allows Plotly plots to be correctly exported to HTML, and work interactively.

It still doesn't show up in notebook previews in Github (which would be cool), but I don't think that would work -- I'm assuming github won't want to execute arbitrary javascript in their site.

But now it's easy to export an HTML and show the notebook as a report for others, for instance.

PS.: There are a couple of more issues I want to handle before cutting the next release (probably during the weekend).

janpfeifer commented 3 months ago

Btw @evertoncolling , how do you get auto-complete in VSCode in GoNB notebooks ? I have been trying it but didn't manage.

In the mean time, I created a page with VSCode usage info. Pls, let me know if you have more tricks/info to share.

I just now managed to install VSCode and started playing with it and GoNB.

evertoncolling commented 2 months ago

I've been away for vacation, so haven't played with GoNB for a while. I just tried again a while ago and it seems I don't get auto-complete working with VSCode as well. The Plotly charts are now rendering as they should though 🙂

janpfeifer commented 2 months ago

Thanks Everton, it's great to hear that plotly is working.

About the auto-complete I don't think it can be solved in GoNB -- VSCode won't use GoNB's auto-complete. Hopefully, we can get it from Polyglot: https://github.com/dotnet/interactive/issues/3511