Accessing Jupyter notebook widgets values - python

While trying to use the Jupyter widgets to control a different function I am stumbling over this issue and am searching for a workaround.
The widget is displayed and I can interact with it just fine. Reading the value, as stated in the documentation using w.value also works. But now reading the value continuously in a loop does not work. Whereas I uncheck the box the value in the while loop never changes.
How can I control python functions via the widgets if they are not updated with the current state of the widgets?

Hope this helps. My reference is this link.
from IPython.display import display
import ipywidgets as widgets
def f(x):
return 'value of checkbox is: ' + str(x)
w = widgets.Checkbox(value=True, description='Updated?')
interact(f,x=w)

Related

Jupyter Lab - Use input() while interacting with a ipywidget and for it to execute observe method and thus update the widget

In jupyterlab, I'm using a ipywidget consisting of nested Tab widgets with a HTML widget for each leaf Tab children. I was wondering is it possible to interact with this ipywidget while waiting for input using input() . I'm loading strings into the HTML widget when Tab.selected_index changes using observe() because jupyterlab complains about too many operations or something like that but because of input blocking nothing is happening.
So in pseudocode
I create the widget Tab_5 a Tab Widget which for each Tab has another Tab Widget associated with it. Eg Queries have associated tabs 1-10, 11-20 are top level tabs and Tabs 1,2,3,4,5,6,7,8,9,10 are nested under Tab 1 - 10 etc
create def on_value_change(change)
if len(Tab_5.children[Tab_5.selected_index].children[Tab_5.children[Tab_5.selected_index].selected_index].value) == 0:
index = 10 * Tab_5.selected_index + Tab_5.children[Tab_5.selected_index].selected_index
Tab_5.children[Tab_5.selected_index].children[Tab_5.children[Tab_5.selected_index].selected_index].value = "<div style ='line-height: normal;'>"+ descList[index] + "<br><br>"+ str(queryStrings[index]) + "<br><br>" + str(responses[index]) + "</div>"
assign it to the children widgets using Tab_5.children[i].observe(on_value_change, names='selected_index'), Tab_5.observe(on_value_change, names='selected_index')
So I looked at https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Asynchronous.html and didn't really understand it and tried doing stuff with the last example.
Basically I'm running some queries using an API and I want to see my past queries in the tabbed interface before choosing to continuing on with future queries with the same parameters apart from one which is incremented. But at the moment, the tabbed widget is not updating while waiting for input.
So previously I generated some Markdown as output but it become really slow. I also at one stage used
from IPython.core.getipython import get_ipython
shell = get_ipython()
payload = dict(
source='set_next_input',
text=contents,
replace=False,
)
shell.payload_manager.write_payload(payload, single = False)
create_new_cell("".join(output))
which created a new code cell which needed to be manually turned into a Markdown cell. (You can programmatically create a cell in Jupyter Notebook but not Jupyter Lab)
So do I need to do something with threads or asyncio? Is this possible or can I accomplish this in a better way by having a widget for the input?
Any suggestions?

Two ipython widgets for one variable

I am trying to make a interactive function where I can control the input with 2 widgets for the same variable. I Trying this because I want to have the option to slider the values (for a quick view) and also pick one specific (typing one value). I tried this linking the widgets with the ipywidget.jslink. I guessed once the widgets where linked I could input the values in any of them to pass to the variable. However, it is not what happens: below, only the values I set in the Slider updates the function (in other words, typing a value in the widget doesn't update the output). Why doesn't jslink work? In this link I found that substituting ipw.jslink for traitlets.linkworks fine.
import ipywidgets as ipw
from IPython.display import display
def f(x):
return x**2
a=ipw.IntSlider(min=-10,max=20,step=1,value=10)
b=ipw.IntText(min=-10,max=20,step=1,value=10)
ipw.jslink((a,'value'),(b,'value'))
wid=ipw.interactive(f, x=a)
display(wid,b)
If the issue is the Python objects not updating on the backend, it is probably because you are using jslink instead of link [ref]. Otherwise, I think this is an old issue with a previous version. I recreated with captured output and both the slider and Text call the function f(x):
from IPython.display import display
output = ipw.Output()
#output.capture()
def f(x):
print(x**2)
return x**2
a=ipw.IntSlider(min=-10,max=20,step=1,value=10)
b=ipw.IntText(min=-10,max=20,step=1,value=10)
ipw.jslink((a,'value'),(b,'value'))
wid=ipw.interactive(f, x=a)
display(wid,b)
display(output)

Is there a way to hide a displayed object using IPython?

I am using the IPython module in a Jupyter Notebook.
I am using the display module to display buttons.
from ipywidgets import widgets
import IPython.display as dsply
def click_reset(b):
print("reset domains button")
restoreDomains()
resetButton = widgets.Button(description="Reset Domains")
resetButton.on_click(click_reset)
dsply.display(resetButton)
This works fine, but I am trying to find a way to programatically hide certain buttons. Based off the execution of my other code, I want certain buttons to be removed from the UI. Is there anything like hide(resetButton) that I can use?
You can hide a widget using
resetButton.layout.visibility = 'hidden'
to let the widget still consume space, or
resetButton.layout.display = 'none'
to let the widget not consume space anymore.
The top-level attribute resetButton.visible = False is not longer supported.
When I use #SergeyGornostaev's answer, I still have a residual cross showing up on the left side of the cell output. I found the following command removes the widget all together:
resetButton.close()
You can hide every widget by setting it's property visible to False
resetButton.visible = False

How to sort key names in ipywidgets interactive widgets (slider)?

I am trying to make interactive sliders with ipywidgets on jupyter notebook to change the data of a plot when a user changes a slider Widget, which is simple and we can find example codes easily. The problem that I have is twofold: 1) when there are many parameters (= variables,sliders) in my function to be displayed, sliders are vertically arranged so that it is getting hard to control them without scrolling the jupyter page. Is there any way to arrange sliders as I wish like m by n grid? 2) To pass a large number of integer-/float-valued sliders, I made a single dictionary to be passed to the function interactive. Here, the key (=slider/variable/parameter) names are displayed seemingly in random order. I tried to pass the dictionary after sorting by the key names beforehand, but it does not still resolve the issue.
I'd appreciate it if you can share any ideas.
def myfun(**var_dict):
v = [value for value in var_dict.values()]
return np.sum(v)
var_dict = {'var1':1,'var2':2,'var3':3,'var4':4}
w = interactive(myfun,**var_dict)
display(w)
ipywidgets interactive sliders
You will not be able to solve this using **kwargs. As stated in PEP468
"The only reason they [keyword arguments] don't work is because the interpreter throws that ordering information away."
"Starting in version 3.5 Python will preserve the order of keyword arguments as passed to a function"
So if you want to get this behavior you should either:
name your arguments when you use 'interactive':
from ipywidgets import interactive
from IPython.display import display
import numpy as np
def myfun(**kwargs):
return np.sum(list(kwargs.itervalues()))
w=interactive(myfun,var1=1,var2=2,var3=3,var4=4)
display(w)
or, if you really want to use a dict, as far as I know, the best is to build the widgets yourself, without the use of 'interactive'.
You could do this this way:
from IPython.display import display,clear_output
from ipywidgets import widgets
from collections import OrderedDict
var_dict = OrderedDict([('var1',1),('var2',2),('var3',3),('var4',4)])
def myfct(change,list_widgets):
clear_output()
print np.sum([widget.value for widget in list_widgets])
list_widgets=[]
# create the widgets
for name,value in var_dict.iteritems():
list_widgets.append(widgets.IntSlider(value=value,min=value-2,max=value+2,description=name))
# link the widgets with the function
for widget in list_widgets:
widget.observe(lambda change:myfct(change,list_widgets),names='value',type='change')
# group the widgets into a FlexBox
w = widgets.VBox(children=list_widgets)
# display the widgets
display(w)
Enjoy :-)

gtk.notebook_set_window_creation_hook function return

I'm having difficulty in understanding what it is that the gtk.notebook_set_window_creation_hook_function is looking for in terms of a return value.
According to the documentation, it's looking for a return value of another notebook you drop it into or None if the drag is cancelled.
Here is my callback example:
def notebook_creation_hook_callback( notebook, page, x, y ):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
page.reparent(window)
window.move(x,y)
return None
Note: I'm trying to use this function to pull the contents of a notebook tab( page) into its own window without appending it to another notebook. The action works, and I can successfully create the window with the given page, but I get TypeError: GtkNotebook window creation hook function return should be a GtkNotebook or None
everytime I do it. And on occasion, a window created in this manner sometimes crashes the entire application with a seg fault.
Can I use this callback function to create a new window out of a dragged page? If not, are there any other methods I could try?
I couldn't find an answer to my question. But from what I gather with my testing and with the documentation, the gtk.notebook_set_window_creation_hook function is used to drag n drop a notebook tab from one notebook to another. Dropping it into a new window that doesn't contain a notebook, even with reparenting of the widget leads to glitchy behavior and seg faults.
Here is an example of how the callback function for this function hook can look like if you're creating a new notebook.
def notebook_creation_hook_callback( notebook, page, x, y ):
new_notebook = gtk.Notebook
new_notebook.set_group_id(notebook.get_group_id()) #Id must be the same as original notebook
window = gtk.Window( gtk.WINDOW_TOPLEVEL )
window.add( new_notebook)
window.show_all()
window.move( x,y )
return new_notebook #Return the new notebook on success

Categories