Code Monkey home page Code Monkey logo

ipywidgets's Introduction

ipywidgets: Interactive HTML Widgets

Purpose Badges
Latest (main: future 8.0) Test Status Documentation Status: latest Binder:main
Stable Version Conda Version Documentation Status Binder:7.x
Communication Join the chat at https://gitter.im/ipython/ipywidgets Discourse

ipywidgets, also known as jupyter-widgets or simply widgets, are interactive HTML widgets for Jupyter notebooks and the IPython kernel.

Notebooks come alive when interactive widgets are used. Users gain control of their data and can visualize changes in the data.

Learning becomes an immersive, fun experience. Researchers can easily see how changing inputs to a model impact the results. We hope you will add ipywidgets to your notebooks, and we're here to help you get started.

The ipywidgets package is under the Jupyter-Widgets software subproject.

Core Interactive Widgets

The fundamental widgets provided by this library are called core interactive widgets. A demonstration notebook provides an overview of the core interactive widgets, including:

  • sliders
  • progress bars
  • text boxes
  • toggle buttons and checkboxes
  • display areas
  • and more

Jupyter Interactive Widgets as a Framework

Besides the widgets already provided with the library, the framework can be extended with the development of custom widget libraries. For detailed information, please refer to the ipywidgets documentation.

Cookiecutter template for custom widget development

A template project for building custom widgets is available as a cookiecutter. This cookiecutter project helps custom widget authors get started with the packaging and the distribution of their custom Jupyter interactive widgets. The cookiecutter produces a project for a Jupyter interactive widget library following the current best practices for using interactive widgets. An implementation for a placeholder "Hello World" widget is provided as an example.

Popular widget libraries such as bqplot, pythreejs and ipyleaflet follow exactly the same template and directory structure. They serve as more advanced examples of usage of the Jupyter widget infrastructure.

Popular custom widget examples

Examples of custom widget libraries built upon ipywidgets are

  • bqplot a 2d data visualization library enabling custom user interactions.
  • pythreejs a Jupyter - Three.js wrapper, bringing Three.js to the notebook.
  • ipyleaflet a leaflet widget for Jupyter.

Install

The stable version of ipywidgets can be installed with pip or conda.

With pip:

pip install ipywidgets

With conda:

conda install -c conda-forge ipywidgets

Developer install from source

Installing from source is more complicated and requires a developer install, see the detailed developer install instructions.

If you want to install ipywidgets from source, you will need the yarn package manager version 3 or later. To install the latest main version from the root directory of the source code, run dev-install.sh. To only build the Python package enter pip install -e ..

Usage

See the examples section of the documentation. The widgets are being used in a variety of ways; some uses can be seen in these notebooks: Demo notebook of interactive widgets

Change log

Change log

Version Compatibility with Front-End Clients

Refer to change log for more detail.

ipywidgets JupyterLab Classic Notebook nbclassic
main - TBD
7.6.3 0.2.6
Legacy
6.x -
5.x 4.2 -
4.1.x 4.1 -
4.0.x 4.0 -

Contributing to ipywidgets

Developer information

License

We use a shared copyright model that enables all contributors to maintain the copyright on their contributions.

See the LICENSE file in this repository for details.

Project Jupyter resources

Developer Meetings take place on zoom, on Tuesdays at 9:30AM Pacific Time (your time).

Minutes are taken at Hackmd.io.

ipywidgets's People

Contributors

afshin avatar blink1073 avatar bollwyvl avatar btel avatar carreau avatar chronitis avatar davidbrochart avatar dependabot[bot] avatar dwillmer avatar ellisonbg avatar fperez avatar ianhi avatar ibdafna avatar ivanov avatar jasongrout avatar jdemeyer avatar jdfreder avatar jtpio avatar maartenbreddels avatar martinrenou avatar mbektas avatar mgeier avatar minrk avatar mwcraig avatar pbugnion avatar sylvaincorlay avatar takluyver avatar vidartf avatar willingc avatar zerline avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ipywidgets's Issues

Output widget fails: can't clean datetime for JSON

Hi,

the Output widget doesn't appear to work with rich display data:

In the notebook,

from ipywidgets import Output
w = Output()
w.clear_output()

results in

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-c7669a04e60f> in <module>()
      1 from ipywidgets import Output
      2 w = Output()
----> 3 w.clear_output()

/home/rick/src/ipywidgets/ipywidgets/widgets/widget_output.py in clear_output(self, *pargs, **kwargs)
     36     def clear_output(self, *pargs, **kwargs):
     37         with self:
---> 38             clear_output(*pargs, **kwargs)
     39 
     40     def __enter__(self):

/home/rick/src/ipython/IPython/core/display.py in clear_output(wait)
    900     from IPython.core.interactiveshell import InteractiveShell
    901     if InteractiveShell.initialized():
--> 902         InteractiveShell.instance().display_pub.clear_output(wait)
    903     else:
    904         from IPython.utils import io

/home/rick/src/notebook/src/ipykernel/ipykernel/zmqshell.py in clear_output(self, wait)
     92         self.session.send(
     93             self.pub_socket, u'clear_output', content,
---> 94             parent=self.parent_header, ident=self.topic,
     95         )
     96 

/home/rick/src/ipywidgets/ipywidgets/widgets/widget_output.py in send_hook(stream, msg_or_type, content, parent, ident, buffers, track, header, metadata)
     61             # If this is a message type that we want to forward, forward it.
     62             if stream is kernel.iopub_socket and msg_type in ['clear_output', 'stream', 'display_data']:
---> 63                 self.send(msg)
     64             else:
     65                 send(stream, msg, ident=ident, buffers=buffers, track=track)

/home/rick/src/ipywidgets/ipywidgets/widgets/widget.py in send(self, content, buffers)
    303             Binary buffers to send with message
    304         """
--> 305         self._send({"method": "custom", "content": content}, buffers=buffers)
    306 
    307     def on_msg(self, callback, remove=False):

/home/rick/src/ipywidgets/ipywidgets/widgets/widget.py in _send(self, msg, buffers)
    454     def _send(self, msg, buffers=None):
    455         """Sends a message to the model in the front-end."""
--> 456         self.comm.send(data=msg, buffers=buffers)
    457 
    458 

/home/rick/src/notebook/src/ipykernel/ipykernel/comm/comm.py in send(self, data, metadata, buffers)
    127         """Send a message to the frontend-side version of this comm"""
    128         self._publish_msg('comm_msg',
--> 129             data=data, metadata=metadata, buffers=buffers,
    130         )
    131 

/home/rick/src/notebook/src/ipykernel/ipykernel/comm/comm.py in _publish_msg(self, msg_type, data, metadata, buffers, **keys)
     75         with open('/home/rick/foo', 'at') as f:
     76             f.write('Sending %s\n\n' % dict(data=data, comm_id=self.comm_id, **keys))
---> 77         content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
     78         self.session.send(self.iopub_socket, msg_type,
     79             content,

/home/rick/src/notebook/src/ipykernel/ipykernel/jsonutil.py in json_clean(obj)
    161         out = {}
    162         for k,v in iteritems(obj):
--> 163             out[unicode_type(k)] = json_clean(v)
    164         return out
    165 

/home/rick/src/notebook/src/ipykernel/ipykernel/jsonutil.py in json_clean(obj)
    161         out = {}
    162         for k,v in iteritems(obj):
--> 163             out[unicode_type(k)] = json_clean(v)
    164         return out
    165 

/home/rick/src/notebook/src/ipykernel/ipykernel/jsonutil.py in json_clean(obj)
    161         out = {}
    162         for k,v in iteritems(obj):
--> 163             out[unicode_type(k)] = json_clean(v)
    164         return out
    165 

/home/rick/src/notebook/src/ipykernel/ipykernel/jsonutil.py in json_clean(obj)
    161         out = {}
    162         for k,v in iteritems(obj):
--> 163             out[unicode_type(k)] = json_clean(v)
    164         return out
    165 

/home/rick/src/notebook/src/ipykernel/ipykernel/jsonutil.py in json_clean(obj)
    165 
    166     # we don't understand it, it's probably an unserializable object
--> 167     raise ValueError("Can't clean for JSON: %r" % obj)

ValueError: Can't clean for JSON: datetime.datetime(2015, 5, 26, 16, 13, 44, 86776)

I can't tell if more of the message header is being directed down the comm channel than it should be, bringing in the datetime, or of the datetime should have been converted to a string at some point (or some other problem...)

Remove .mailmap

@minrk is it okay if we remove this file? What is it for? It looks like a contributor list, have you already simplified it for the widget contributors?

IPython SelectMultiple widget does not always reflect selected_labels

I have been working with the IPython SelectMultiple widget and it does not always correctly display the selected labels on the widget. The easiest way to reproduce this is to set selected_labels before displaying.

Minimal code to reproduce:

from ipywidgets import widgets
from IPython.display import display

sm = widgets.SelectMultiple(options=['a', 'b', 'c'], selected_labels=['a', 'b', 'c'])
display(sm)
print sm.value
print sm.selected_labels

Workaround, shows as expected:

sm2 = widgets.SelectMultiple(options=['a', 'b', 'c'])
display(sm2)
sm2.selected_labels = ['a', 'b', 'c']
print sm2.value
print sm2.selected_labels

Requested Version info:

python -c "import IPython; print(IPython.sys_info())"
{'commit_hash': u'0b5f4a8',
 'commit_source': 'installation',
 'default_encoding': 'UTF-8',
 'ipython_path': '/redacted_path/.local/lib/python2.7/site-packages/IPython',
 'ipython_version': '4.0.0-dev',
 'os_name': 'posix',
 'platform': 'Linux-2.6.32-431.20.3.el6.x86_64-x86_64-with-redhat-6.5-Santiago',
 'sys_executable': '/redacted_path/anaconda/bin/python',
 'sys_platform': 'linux2',
 'sys_version': '2.7.10 |Anaconda 2.3.0 (64-bit)| (default, May 28 2015, 17:02:03) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]'}

Css issue with the slider.

The background : none css property of the ui-slider div is not being applied (see line 118 in widgets.less).
This causes this div, which is supposed to be invisible to partly hide the slider track.

The reason is that the css from hbox is overriding this property.

interact_manual: way to make <enter> press the button

I've a lookup widget, which is implemented as a function with a single string argument:

def table_by_name(name=""):
    if name == "":
        display(HTML("<strong>Nothing to do</strong>"))
    else:
        # do some pandas merging and dicing, which results in `df`...
        display(HTML(df._repr_html_()))
interact_manual(table_by_name)

It would be nice if there would be some way to specify that pressing enter in the input box will trigger the button.

Displaying to output widget from button click callback throws exception

Here's a minimal example:

%matplotlib inline

from IPython.html import widgets
from IPython.display import display

def click(b):
    with out:
        print 'Hello world'

out=widgets.Output()
button=widgets.Button(description='Click Me')
button.on_click(click)
display(out)
display(button)

Executing a notebook cell with this code and clicking the button results in the following exception being thrown:

NameError: global name 'get_ipython' is not defined

This is with the Anaconda ipython / ipython-notebook version 3.2.1 packages on Windows.

This issue can be resolved by adding

from IPython import get_ipython

to IPython/html/widgets/widget_output.py, but I'm not familiar enough with the code to be sure if this is the correct place to make that change, or if the fix should be further upstream.

Leading whitespace on select widgets causes KeyError

@deeplycloudy reported this in ipython/ipython#8580


See error below. The KeyError shows that the whitespace has been removed, and therefore doesn't match the options dict.

Forcing the options list to have no leading whitespace avoids this bug, but I discovered this accidentally when doing options = [{0:6.2f deg}.format(ang) for ang in angles], which someone might stumble across again.

>>> widgets.Select(description='Angle', options=(' 1.2 deg', ' 5.7 deg'))

Followed by a click on either option results in

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/html/widgets/widget.pyc in _handle_msg(self, msg)
    347             if 'sync_data' in data:
    348                 sync_data = data['sync_data']
--> 349                 self.set_state(sync_data) # handles all methods
    350 
    351         # Handle a state request.

/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/html/widgets/widget.pyc in set_state(self, sync_data)
    251                 from_json = self.trait_metadata(name, 'from_json', self._trait_from_json)
    252                 with self._lock_property(name, json_value):
--> 253                     setattr(self, name, from_json(json_value))
    254 
    255     def send(self, content):

/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/utils/traitlets.pyc in __set__(self, obj, value)
    443             # we explicitly compare silent to True just in case the equality
    444             # comparison above returns something other than True/False
--> 445             obj._notify_trait(self.name, old_value, new_value)
    446 
    447     def _validate(self, obj, value):

/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/html/widgets/widget.pyc in _notify_trait(self, name, old_value, new_value)
    371         # registered validation to be processed prior to allowing the widget
    372         # machinery to handle the state.
--> 373         LoggingConfigurable._notify_trait(self, name, old_value, new_value)
    374 
    375         # Send the state after the user registered callbacks for trait changes

/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/utils/traitlets.pyc in _notify_trait(self, name, old_value, new_value)
    600                     c(name, new_value)
    601                 elif nargs + offset == 3:
--> 602                     c(name, old_value, new_value)
    603                 else:
    604                     raise TraitError('a trait changed callback '

/Users/ebruning/anaconda/lib/python2.7/site-packages/IPython/html/widgets/widget_selection.pyc in _selected_label_changed(self, name, old, new)
    134         if self.value_lock.acquire(False):
    135             try:
--> 136                 self.value = self._options_dict[new]
    137             finally:
    138                 self.value_lock.release()

KeyError: u'1.2 deg'

Typescript

Should we convert the widgets to Typescript?
Or instead to ES6?

My feeling is that as long as we can maintain easy (unchanged) access to our Javascript users, we should give Typescript a shot.

Adding to next week's dev meeting.

bower dependencies

It looks like the bower.json file contains lots of unnecessary dependencies. Especially a lot since it installs to the bower_components directory, and it appears that that directory is never touched or used. Should we delete it?

JavaScript widget toolkit without jquery

The IPython widgets framework allows for other backbone view types than the usual JQuery-based, and neither widget.js nor manager.js really depends on JQuery.

However, we still use bootstrap and JQuery for the core basic IPython widgets like button / slider / date picker, dropdown.

I was wondering what is the best JavaScript widget framework that we could use as a replacement, and that would play well with phosphor. I am not sure if it is in the scope of phosphor to reimplement those. Apparently, it is possible to use bootstrap's css without the JQuery extension. There are replacements to this extension such as https://github.com/tagawa/bootstrap-without-jquery

What do you guys think about it?

Live collaboration with widgets

As discussed in the dev meeting, we should use something more persistent than gitter for this kind of things since the team is spread over multiple time zones. @Carreau @jasongrout @sccolbert

Here are some thoughts on widget-specific aspects of live collab:

  • You cannot have two users moving a slider at the same time. I think that when a user grabs a slider, it should lock that slider for other users, by default, and only release it after he has stopped changing the widget state for a while (e.g. half a second). - Race conditions would be resolved by the server: if the widget was not (yet) displayed as locked by another user when you started touching it but it is when your change reaches the server, you lose, and the widget is locked
  • Indeed, since widgets have arbitrary internal logics, it would be difficult to have a different behavior by default than a total lock of the widget.
  • For finer user-by-user widget behavior, you could imagine having special widget attributes that are user-based, (like a selection in a text area). These user-by-user attributes should not be accessible from the kernel, but only by the server, and should only impact the way the widget is displayed to different users. i.e. only be used for rendering.

While for a collaborative text editor, you can imagine different people modifying different parts of the state (different sections of the document), but for a general widget, since the logic can be completely arbitrary, I don't see how to be more atomic than the entire widget.

collab

Creating a new "model_ready" event in widget.js

I encountered the following problem with widgets that create sub-widgets from the JavaScript side in their JavaScript model constructor:

For example the gamepad widget creates subwidgets for the buttons and axes in its constructor. Once the connected trait attribute is set to True, the user may wire things to the gamepad buttons...

However, in the case of a page reload, I would like these widgets not to be replaced by new ones, when the constructor of the JavaScript side is executed. The part of the constructor containing the creation of the children should only occur after the state request resolves.

One way to solve this issue would be to create a model-ready event for that, of have a certain promise that gets resolved right away in the case of a new model, and after the state request resolves in case of page reload.

Suggestions welcome.

@jdfreder @jasongrout

Widget-subarea does not enlarge if widget does not have a fixed weight

With IPython 3 the widget-subarea div would enlarge to use up the whole available width. With IPython 4 this doesn't happen and the width is super narrow. Only by setting a fixed width on the widget itself it will be displayed correctly.

IPython used to have the CSS property flex: 2 1 0%; on widget-subarea which is gone now. If I re-add temporarily in the browser's developer tools, the sizing works again as expected.

Missing components

I have tried running pip install -e . both inside and outside a virtualenv (jupyter notebook is installed in both cases), and I keep getting errors. This appears to be the most relevant part of the terminal output:

    > [email protected] css /home/jkersulis/Documents/ipywidgets
    > node build_css.js

    > lessc --include-path=./less_include ./ipywidgets/static/widgets/less/widgets.less ./ipywidgets/static/widgets/css/widgets.css
    FileError: '/components/bootstrap/less/variables.less' wasn't found. Tried - /components/bootstrap/less/variables.less,/home/jkersulis/Documents/ipywidgets/ipywidgets/static/widgets/less/components/bootstrap/less/variables.less,/home/jkersulis/Documents/ipywidgets/less_include/components/bootstrap/less/variables.less in /home/jkersulis/Documents/ipywidgets/ipywidgets/static/widgets/less/widgets.less on line 2, column 1:
    1 // minimal imports from bootstrap - only variables and mixins
    2 @import "/components/bootstrap/less/variables.less";
    3 @import "/components/bootstrap/less/mixins.less";

    `lessc --include-path=./less_include ./ipywidgets/static/widgets/less/widgets.less ./ipywidgets/static/widgets/css/widgets.css` failed with status=1

The directory ipywidgets/static/widgets/less/components is indeed missing, but perhaps it is supposed to be generated during the installation process. Any idea what's going on here? Thank you for your time.

request_state promise and update message

When requesting state from the back-end, a regular update message is sent back, and a complicated logic to match the message id is applied to resolve the promise correctly. Another consequence is that the resolution of the request_state promise is external to the promise code itself.

I think that the response to a request state should not be a regular update but a separate message type.

Plot showing more often than it should

@ahhsia originally reported:


I get an every increasing set of plots from a single interact cell in the notebook when running a SelectWidget and changing the plot function.

Originally, I was using subplot instead of just plot because I was attempting to get 2 different types graphs to change simultaneously with the interactive widgets. So, while the test case below doesn't really need subplot, it is the simplest testcase I have that showcases the odd behavior.

If I run this:

w1= widgets.SelectWidget(values=[4,5,6], value=4)
@interact(a = w1)
def viewer(a):
    fig,ax=plt.subplots()
    #ax.plot(range(a))
    ax.plot(range(a+1))

And then go back and change the ax.plot command,(e.g. reverse the commenting on the ax.plot commands shown here), rerun the cell and select a new value, I will end up with 2 figures.
The more times I change the plot command, the longer the chain of figures I will end up with.

ghost

Build failed on Mac OS

Hi,
I've tried to build this project (using pip3 install -e .) but I am getting this error.

FileError: '/components/bootstrap/less/variables.less' wasn't found. Tried - /components/bootstrap/less/variables.less,/Users/jendas/Google drive/Active projects/ipywidgets/ipywidgets/static/widgets/less/components/bootstrap/less/variables.less,/Users/jendas/Google drive/Active projects/ipywidgets/less_include/components/bootstrap/less/variables.less in /Users/jendas/Google drive/Active projects/ipywidgets/ipywidgets/static/widgets/less/widgets.less on line 2, column 1:
1 // minimal imports from bootstrap - only variables and mixins
2 @import "/components/bootstrap/less/variables.less";
3 @import "/components/bootstrap/less/mixins.less";
`lessc --include-path=./less_include ./ipywidgets/static/widgets/less/widgets.less ./ipywidgets/static/widgets/css/widgets.css` failed with status=1

I am not much into npm packager so I don't know how to fix it.

Output widget appears to size itself smaller than its contents

This seems to be a regression (or new feature!) as it does not happen with 3.0.0 (Anaconda on Windows with 3.0.0 ipython, ipython-notebook packages).

This can be highlighted by displaying an inline matplotlib plot, rendered by default with the png backend:

%matplotlib inline
import matplotlib.pyplot as plt

from IPython.html import widgets
from IPython.display import display

out=widgets.Output()
display(out)

with out:
    plt.plot([0,1],[0,1])
    display(plt.gcf())

plt.plot([0,1],[0,1]);

In my tests with Anaconda on Windows and the 3.2.1 IPython packages, the plot in the output widget gets scaled down:
image

This doesn't happen with 3.0.0:
image

A variation can be seen by switching to the svg backend with:

%config InlineBackend.figure_formats=set(['svg'])

In this case, the plot is not resized, but scrollbars appear on the output widget:
image

Dropdown Widget cut off at the end of the notebook

I'm facing an issue when the dropdown is cut off the end of the notebook (see attached screenshot). I've worked around this in the past by adding empty cells below this cell, but I currently have a list of 300 options and I'm trying to find a better fix. I'm running IPython Notebook 3.2.1.

screen shot 2015-07-17 at 3 58 38 pm

Persistence issues with widgets holding other widgets

Re-instantiating all valid widget models

Let' s say that we have a container widget with id id1 holding two widgets of id id2 and id3. (For example, HBox([Button(), Button()])). We save the notebook and the states of the three widgets are saved to the local storage.

id1
 |
 +--- id2
 |
 +--- id3

Then we change the content initial container wigdet, so that we are in the situation

id1
 |
 +--- id4
 |
 +--- id5

then, without saving the notebook, we reload the page.

Since id1 is a valid comm, we request it' s state, but when de-serializing its state, we fail at instantiating the widget models id4 , id5 because they were not recreated. (more precisely, get_model will return undefined.) Errors are displayed in the console.

This shows that we should re-instantiate all the valid widget models regardless of whether they were in the local storage.

External state request

The issue is that we need to retrieve the _model_name and the _model_module, which are part of the state to instantiate the model and make a state request.

Hence, the state request should probably be external to the widget, and sent via the bare comm object.

Removing styling attributes from the base DOMWidget model?

The following attributes are accessible in the base widget model:

'color'
'background'
'width'
'height'
'border-color'
'border-width'
'border-style'
'font-style'
'font-weight'
'font-size'
'font-family'
'padding'
'margin'
'border-radius'

I am conflicted about exposing them because I like the idea of widget models to only contain the relevant information. Besides, these names can be quite overloaded, and you could imagine a 'color' or 'margin' attribute name having nothing to do with a styling attribute.

Could not open comm

I installed Jupyter Notebook according to the latest README then followed by installing ipywidgets

When opening the Widget Basics example notebook, the import cell worked fine, but the cells creating widgets failed. These errors were shown in the browser console from executing IntSlider():

Error: Could not open comm
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)
Error: Couldn't process kernel message
    at new Error (native)
    at Error.WrappedError (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12706:25)
    at reject (http://192.168.100.100:8888/static/notebook/js/main.min.js?v=5481c6cbbfa3491e70ffb5a7c79f89f7:12785:33)

@lbustelo

JS initialized widgets initial state overridden by backend

Assuming a Point widget and PointModel are defined,

                    var that = this;
                    this.model.widget_manager.create_model({
                        model_name: 'PointModel', 
                        widget_class: 'paper.Point'})
                        .then(function(model) {
                            model.set('x', point.x);
                            model.set('y', point.y);
                            model.save_changes(that.callbacks());
// ...

I also tried

                    var that = this;
                    this.model.widget_manager.create_model({
                        model_name: 'PointModel', 
                        widget_class: 'paper.Point'})
                        .then(function(model) {
                            model.state_change = model.state_change.then(function() {
                                model.set('x', point.x);
                                model.set('y', point.y);
                                model.save_changes(that.callbacks());
// ...

despite point.x and point.y being non-zero, the 0 values of the backend class always override the values set by the frontend during construction. See a log of the sent&recieved msgs, from the front end's perspective:

send Object {x: 146, y: 62}
paper_widget.js:132 3
widget.js:171 recv Object {version: 0, msg_throttle: 3, y: 0, x: 0, _view_name: null…}

Test framework improvements or total redesign.

The tests should

  • always show the notebook Python output / error on failure
  • javascript console output / error on failure
  • test error on failure
  • should use promises if written in Javascript
  • should be clearer about the three contexts (kernel, browser, and tests)
  • if written in javascript, ES6 template strings or something better should be used for embedding python
  • should have an easy way to expose/export the test notebook, so the dev can interact with the tests to see why they are failing
  • should have nice mechanisms for debugging

Decouple the widgets from the Notebook.

Decoupling the widgets from the Notebook should make it easier for people to embed the widgets in their own non-notebook environment. For example, @rgbkrk has already expressed interest in doing this with his BitJet widget and Sidecar app.

This means splitting the WidgetManager into a WidgetManager or WidgetManagerBase (depending on whether or not it can be used without being inherited) and a NotebookWidgetManager.

We also may want to think about the installation a little more carefully, which we will have to do soon anyways. Users may want to install (A) for use with the notebook (B) for standalone use. If @SylvainCorlay 's proposal for kernel resource/extensions is implemented, (A) is instead to a specific kernel, not the notebook.

Backbone native view example

@jdfreder do you think we should provide an example using a backbone.NativeView with the widgets? This would require shipping NativeView but it would be interesting for people willing to make custom widgets without jquery.

HTML outputs suppressed by widgets

It looks like display(*widgets) suppresses any other html outputs:

from IPython.html.widgets import Button
from IPython.display import HTML, display
b = Button(description='Say Hello')
def cb(value):
    HTML('<h1>hello</h1>')
    print('hello')

b.on_click(cb)
display(b)

Clicking the button does not produce the HTML output:

screen shot 2015-08-10 at 6 06 43 pm

Random JavaScript test failures

As discussed with @jdfreder, I sometimes see that one of the two js test suites that is failing. A simple restart generally solves it.
I have not observed it when running it locally, but it is probably not related to the Travis env.

display: flex missing

It seems that a fluke in the less means that generated CSS is:

.hbox,.vbox,.widget-area,.widget-area .widget-subarea,.widget-hbox,.widget-hslider,.widget-radio-box,.widget-vbox,.widget-vslider,.widget-vslider .ui-slider {
    display: -webkit-box
}

and the display for the widget-subarea is set to -webkit-box, rather than flex.

container.pack doesn't work well

This example from the Widget Styling example notebook doesn't work:

buttons = [widgets.Button(description=str(i)) for i in range(3)]
display(*buttons)
container = widgets.HBox(children=buttons)
display(container)
container.width = '100%'
container.pack = 'center'

Is supposed to center the buttons. We should fix it or change the example.

Static widgets

Depends on #13

Originally planned for 3.0, static widgets allow widgets to be exported using nbconvert. The mechanism of state storage has yet to be decided.

Interact with simple plot function now flickers on update

The commit 68f771f on interact now displays the functions return value, which has the side-effect of causing "flickering" when interacting with a simple matplotlib plot.

Here's an example that used to be a smooth interactive plot with sliders:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, HTML, FloatSlider
from IPython.display import clear_output, display

def make_plot(magnitude=5.0, phase=0.0):
    x = np.arange(0, 10, 0.1)
    y = magnitude*np.sin(x+phase)
    plt.plot(x, y)
    plt.ylim(-10, 10)

interact(make_plot, magnitude=(0, 10, 0.1), phase=(0, 4*np.pi, 0.1))

Unfortunately, because make_plot returns None, None is printed, which somehow breaks the smooth updating that interact previously exhibited. Now the plot is erased, the rest of the web interface jumps up to fill the gap, then the plot is replaced... repeatedly and rapidly while the slider is being interacted with. This drastically reduces the interactivity and aesthetic appeal of simple tools like this.

Here is an example without interact which currently runs fine and demonstrates the smooth behavior that interact previously had:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, HTML, FloatSlider
from IPython.display import clear_output, display

slider1 = FloatSlider(description='magnitude', min=0, max=10, step=0.1)
slider2 = FloatSlider(description='phase', min=0, max=4*np.pi, step=0.1)

def update_plot():
    magnitude = slider1.value
    phase = slider2.value
    x = np.arange(0, 10, 0.1)
    y = magnitude*np.sin(x+phase)
    fig = plt.figure()
    plt.plot(x, y)
    plt.ylim(-10, 10)

    clear_output(True)

slider1.on_trait_change(update_plot, 'value')
slider2.on_trait_change(update_plot, 'value')

display(slider1, slider2)
update_plot()

Interestingly, adding display(None) to the end of update_plot() brings back the flickering from the interact example, demonstrating that the display of text is causing the flicker. Hmmm... apparently displaying an empty HTML object removes the flicker... I guess that would be the workaround. If I add return HTML() to the first example's make_plot() function, it updates smoothly now.

I don't know if there is a better solution to this. I wish text and figures could both be updated smoothly without the "flickering effect," but until that is implemented, I'd at least like the option to turn off display of function output for interact or perhaps not display output when output is None so that the smooth behavior isn't disrupted simply to display None. Documenting the workaround of returning HTML() in an example might be useful in lieu of other solutions (I haven't searched thoroughly to see if this has been done/documented before...).

edit: fixed 2nd example - had left out the slider definitions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.