Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrating Makie's new SpecApi #2706

Open
SimonDanisch opened this issue Nov 9, 2023 · 8 comments
Open

Integrating Makie's new SpecApi #2706

SimonDanisch opened this issue Nov 9, 2023 · 8 comments

Comments

@SimonDanisch
Copy link

SimonDanisch commented Nov 9, 2023

Makie is getting a declarative API in MakieOrg/Makie.jl#3113, which should work much better with the way Pluto creates animations.
From Makie's side everything is there to make for a nice integration, but it's still an open question how to hook it up with Pluto.
To render the following efficiently:

begin 
    @bind markersize PlutoUI.Slider(5:15)
end
begin
   S.Figure([ S.Axis(plots = [S.scatter(1:4; markersize=markersize)] )])
end

I need something like this in pseydo code:

obs = Observable(S.Figure([ S.Axis(plots = [S.scatter(1:4; markersize=markersize)] )]))
display(plot(obs)) # display on first cell invokation

on(cell_update) do cell_content
     obs[] = cell_content
end
# dont display anything again, just update the internal object

In other words, I need to be able to display my plot only one time, and after that only update an Makie "internal" object with the new values of that cell.

Is this possible in any way?

@fonsp
Copy link
Owner

fonsp commented Nov 13, 2023

That's awesome! A declarative API is really helpful, I'm sure we can make something work.

What happens when you set obs[] = ..., is that update sent with a separate JSServe connection to the frontend? It is important that the cell does not re-render the HTML and <script> when it runs reactively (i.e. when you move the slider)? Can you set an observable value from javascript instead of Julia?

Pluto's core API for persistent plots is based on JavaScript (see "Stateful output with this" and "Embedding Julia data directly into JavaScript" in https://featured.plutojl.org/web/javascript), where all the statefulness happens on the JavaScript side, so it's not directly obvious how to integrate it. A solution that uses this API will also work with https://github.com/JuliaPluto/PlutoSliderServer.jl .

@Pangoraw what do you think? This is easy with PlutoHooks.jl but then S.Figure needs to be a macro or you need to prepend a macro.

@fonsp
Copy link
Owner

fonsp commented Nov 13, 2023

@SimonDanisch Where can we read more about SpecApi ?

@SimonDanisch
Copy link
Author

What happens when you set obs[] = ..., is that update sent with a separate JSServe connection to the frontend

Yeah so all the diffing and updating happens in julia and is then send via JSServe to the WGLMakie plot directly...
So it would be really easy to implement if we just don't display anything new...
If this is absolutely not possible, I'd need to think hard about a solution :D
I guess it should still be possible somehow, just quite a bit harder on my side.

@SimonDanisch Where can we read more about SpecApi ?

There are some docs in the docs preview of the PR:
https://docs.makie.org/previews/PR3113/reference/specapi/

@fonsp
Copy link
Owner

fonsp commented May 7, 2024

I talked with Simon today, it looks more promising again! Useful API from Pluto:

SpecApi has a declarative user-facing API , and the implementation handles state and diffing on the Julia side. This is tricky beacuse our API listed above was designed for state and diffing on the JS side with stateless Julia (to support multiple people viewing the same notebook simultaneously and PlutoSliderServer.jl).

For Julia-based state, @use_ref from PlutoHooks.jl is useful, and JuliaPluto/PlutoHooks.jl#8 would make it possible to hide this functionality inside Makie, so that users don't have to write macrocalls.

@behinger
Copy link

behinger commented May 7, 2024

Great that this is moving along!! Would be amazing to have both, without needing to redo the Page if the website is closed / reopened.

One question (maybe only for my understanding and your plan is already a completly otherone): is the script_id a UUID? My understanding at some point was that WGLMakie could open one websocket connection per UUID, as long as the UUID is available in the show() function. Which would mean pluto can stay "stateless" as Bonito/WGLMakie handles all the plotting-interaction (o.c. this changes with Observables, similar to inplace operations in Pluto already are "invisible" as far as I understand)

@fonsp
Copy link
Owner

fonsp commented May 7, 2024

Hi Bene! The script id is not useful for that, it's used to distinguish between multiple <script>s in the same cell, but the value is the same for all visitors.

You could use let my_name = window.my_bonito_id = window?.my_bonito_id ?? Math.random() to get a unique ID for a tab session that is shared among all cells, but different for parallel visitors.

@behinger
Copy link

behinger commented Jun 25, 2024

Any update on this one? I'm stumbling over it time and time again. Happy to help / facilitate in any way (time, programming, financial)

Also linking the maybe related #2895

@fonsp
Copy link
Owner

fonsp commented Jun 25, 2024

Hey Bene!

Simon and I had a call some time ago, for now our next steps are:

After this we will meet again 🧁☕️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants