ipywidgets
ipywidgets copied to clipboard
Is there anyway to keep a widget state even after a kernel restart?
I have an issue. If I re-start my kernel then it will unlink my widgets (I get the little red broken chain symbol). Is there anyway to save the widget state in the notebook so even if I move that notebook to another kernel the widgets will remember their state? (saving the state json to a file maybe?)
You can save the widget state to the notebook (in classic notebook, see the Widget menu). However, it is basically just saving a snapshot. We can't reconstitute those widgets in a new kernel.
Not sure if this makes sense, but I am saving state in a json file. My business case is interactive sql query building so in that case once the user has selected schemas, tables and columns I save all in a json so that that sql can be rebuilt next time from the json. Also, I use the json to repopulate the widget values on each new run time.
Can this be done from the widget object like widget.to_json() and then widget.from_json()?
Not sure if this makes sense, but I am saving state in a json file. My business case is interactive sql query building so in that case once the user has selected schemas, tables and columns I save all in a json so that that sql can be rebuilt next time from the json. Also, I use the json to repopulate the widget values on each new run time.
@kfk, How do you save the widget state to a json file? I cannot find a function for that.
@chaffra there is a notebook option for it: https://ipywidgets.readthedocs.io/en/latest/embedding.html
The Download Widget State option triggers the downloading of a JSON file containing the serialized state of all the widget models currently in use,
@chaffra there is a notebook option for it: https://ipywidgets.readthedocs.io/en/latest/embedding.html
The Download Widget State option triggers the downloading of a JSON file containing the serialized state of all the widget models currently in use,
@hainm , yes but I was looking more for the python function I could use to save a widget to json and then another function to reload the values into the widget from json.
Perhaps https://ipywidgets.readthedocs.io/en/latest/embedding.html#python-interface from the ipywidgets docs is helpful here?
Thanks, embed_data can be used to save the state but how do I load the values back into the widget. I tried widget.set_state(state) unsuccessfully.
I'm not sure exactly what you are trying to do, but this may be trickier than it seems at first glance. The embed data here is the state of all widgets in the widget manager. Each widget has a unique id. Separately you have the code variables in your code, and we can't keep track of those - that's outside of the widget's knowledge.
Reconstituting object state probably involves matching those variable ids up to variables in the code. For example, suppose you have two sliders, with internal ids 'A123' and 'B456'. Your widget state here just says that slider A123 has these values, and slider B456 has these values. To reconstitute that into widgets, presumably you'll know you need two sliders, so you'll create two. But now you need to know which of these sliders you should reset with A123's values, and which slider you should reset with B456's values.
Another way to do this for a much simpler case is to just try to restore a single top-level widget. You ask for the state (recursively) of that one widget, and get back a json blob (I don't think there is a nice convenience function for this yet). Then there is a new function (that also doesn't exist yet), that can take that json blob, reconstitute the widgets, and hand you back the top-level widget, which you can then assign to a variable.
Perhaps it would be helpful if someone wrote down a very specific usecase, along with exactly the code they would like to work, with an explanation of what that code should do. Then if something like that is possible, we can help more clearly. If it is not possible currently, then that informs whoever wants to implement something like this.
Thanks for the thourough answer. If one could choose the model_id for each widget when it's created then the first solution might work. One would just have to compare the key in the stored (json) widget state to the recreated widget model_id. If the key matches the model_id the the stored value for that key is used to update the widget.
If this sounds reasonable I could try implementing a recursive function like that.
On Fri, Aug 16, 2019, 08:20 Jason Grout [email protected] wrote:
Perhaps it would be helpful if someone wrote down a very specific usecase, along with exactly the code they would like to work, with an explanation of what that code should do. Then if something like that is possible, we can help more clearly. If it is not possible currently, then that informs whoever wants to implement something like this.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jupyter-widgets/ipywidgets/issues/2369?email_source=notifications&email_token=AAQPAPIGATKFC7J72Z3V3ETQE3ASPA5CNFSM4HFOWD4KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4O45PY#issuecomment-522047167, or mute the thread https://github.com/notifications/unsubscribe-auth/AAQPAPM2UDGWVNHLXL5CZATQE3ASPANCNFSM4HFOWD4A .
I mean what's the point in having the option to save the widget state when there's no way to load it back?
Y
On Tue, Apr 27, 2021, 22:49 Pavlin Mavrodiev @.***> wrote:
I mean what's the point in having the option to save the widget state when there's no way to load it back?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/jupyter-widgets/ipywidgets/issues/2369#issuecomment-827775772, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQWTJ23DUZ3VMHERJZQ2JE3TK3W35ANCNFSM4HFOWD4A .
I mean what's the point in having the option to save the widget state when there's no way to load it back?
The purpose of saving the widget state is to provide a representation of the widgets in a document not connected to original kernel (for example, if the notebook is exported to html like our documentation, or as a preview of outputs that will be created when cells are run).
This is discussion is really relevant and appears to be still open. Would there be any progress in the development of saving widgets' state and reloading these into the notebook? Thank you for your comments
I don't know of any conversation beyond the conversation above about this topic.
Would there be any progress in the development of saving widgets' state and reloading these into the notebook?
Note that widget state already can be saved in the notebook, and the corresponding widgets are reloaded onto the page when the notebook is opened. What is not done is reconstitute those saved widgets in the kernel as "live" widgets.
Dear Jason Thank you for your reply, I am not sure if I understood what you meant with "note ,,, widgets are reloaded". Do you have a link to an example to what you mean with that? Thank you very much
I am not sure if I understood what you meant with "note ,,, widgets are reloaded"
In JupyterLab, if you have the Setting > Save Widget State Automatically checked, then any live widgets in the document are saved in the document when it is saved. If you close the notebook and shut down the kernel, then reopen the document, those widgets will appear. However, they will not be "live" in that they are not hooked up to anything in the kernel, but they still will be displayed.
Here is a use case and some selection strategies to illustrate the issue.
I would like to allow my users to select a template for the notebook from a list of predefined templates. Each template represents some colors, sizes, font type etc. The template is applied to auto generate some diagrams following the template specs. This way, the users are able to directly copy the resulting diagrams to their various project reports written in Word.
a) I created a custom template widget to allow the user to easily select the template with a DropDown:

If the user re-executes the full notebook, the selection falls back to the default template (=first option of the selection widget).
However, I want that the previously selected and saved template is kept permanently, even when rerunning the cell that creates the widget. The template should only change if the widget selection is changed by the user.
b) A workaround would be to use a code cell, and force the user to adapt the code to make the selection:

When re-running that code cell, the selected/wanted template would still be valid because it is saved with the code cell. A disadvantage of this approach is that the users do not immediately see the available options. They would first need to inspect the imported templates. Or I would need to add some comment line, listing the available options.
c) In a mixed approach I could pass an initial value to the template control. However, that would also force the user to change the code to get a permanent selection.
from isi.widgets import template_selection
template_select = template_selection(initial_value=Template.FORECAST)
d) Maybe it would be possible to store the widget state in terms of tags of the cell containing the widget. When the constructor of the widget is called, it checks if its parent cell already has some tags, determining the initial state of the widget. If the selection changes, the widget adapts the tags of its containing cell. For me it would be fine if a cell is only allowed to contain one of this "tag widgets".
=> Does option d) make sense for you? Or is there a better approach?
Here is some selection widget to play with:
import ipywidgets as widgets
selection = widgets.Dropdown(
options=['foo', 'baa', 'qux'],
description='My custom option that should be permanent',
style={'description_width': 'initial'},
layout=widgets.Layout(width='50%')
)
selection
Select 'baa' and then rerun the cell. => Selection is lost.
In JupyterLab, if you have the Setting > Save Widget State Automatically checked, then any live widgets in the document are saved in the document when it is saved. If you close the notebook and shut down the kernel, then reopen the document, those widgets will appear. However, they will not be "live" in that they are not hooked up to anything in the kernel, but they still will be displayed.
@jasongrout This isn't what I'm seeing currently in 3.4.7. The state is saved in the notebook (verified that) but when I kill the kernel and re-open the notebook I'm getting "Error displaying widget: model not found" -- it seems as though display is querying the new kernel and not using any saved/embedded state?
I am also experiencing the same "Error displaying widget: model not found" error after reopening a notebook on 3.6.2.
I can replicate this with a fresh conda Python 3.10 environment:
jupyterlab 3.5.3
ipywidgets 8.0.4
Automatically save widget state enabled.
Create new Jupyter notebook in Jupyter lab with two cells:
import ipywidgets as widgets
widgets.Label('Hello World!')
Close & open Notebook (new kernel): "Error displaying widget: model not found".
Open same notebook in Jupyter Notebooks: label is rendered.
This is an important user experience issue to me, too.
After instantiation, user input becomes available to the kernel, even 'continuous update' is possible. Saved user input could also be conveyed the same way to the kernel upon object creation, so the widget's value is initialized with saved data.
An explicit initialization should be avoided by the user in that case, of course.
I think there's a bug with Jupyterlab for loading ipywidgets after re-opening a notebook, below is my test.
Today is 2023-12-04 OS: Windows 11 Browser: Chrome jupyterlab: 4.0.9 ipywidgets: 8.1.1 jupyterlab-widgets: 3.0.9 Steps:
- Open a notebook in jupyterlab
- Run the following Python code:
import datetime
import ipywidgets as widgets
out_sim_calls = widgets.Output(layout={'border': '1px solid black'})
display(out_sim_calls)
with out_sim_calls:
print(f"{datetime.datetime.now()} search started.")
for i in range(10): print(f"{i=}")
with out_sim_calls:
print(f"{datetime.datetime.now()} search finished.")
- Close jupyterlab (both Chrome and jupyter server)
- Re-open the same notebook in Jupyterlab Expected output:
2023-12-04 07:42:39.847378 search started.
2023-12-04 07:42:39.853357 search finished.
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
Actual output:
Error displaying widget: model not found
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9