[IPython-dev] Widget example that uses classes instead of globals?

Brian Granger ellisonbg at gmail.com
Tue Sep 16 15:10:51 EDT 2014


https://github.com/ellisonbg/leaftletwidget/blob/master/leafletwidget/leaflet.py#L19

This mixin provides an interact method that allows you to interact
with any traitlet on a class. Just haven't had time to turn this into
a proper ipython PR...

On Tue, Sep 16, 2014 at 11:27 AM, Adam Hughes <hughesadam87 at gmail.com> wrote:
> Nicholas,
>
> This is an amazing example.  Thanks so much for helping us this much!  Will
> send you some updates when we are able to get it running with our data and
> credit you in this.  Is there a special way you'd like to be acknowledged or
> cited?
>
> On Mon, Sep 15, 2014 at 11:19 PM, Nicholas Bollweg <nick.bollweg at gmail.com>
> wrote:
>>
>> @antonino: I hadn't thought to use interact that way! __call__ might be
>> too magic to be used that way... but you can create a non-bound function
>> (not a method, though self would be in scope!) in the constructor of a
>> widget that will respond to interact:
>>
>>> from IPython.html.widgets import interact, ContainerWidget, HTMLWidget
>>>
>>> class Carousel(ContainerWidget):
>>>     def __init__(self, *args, **kwargs):
>>>         self.might_show = [HTMLWidget(value="<h1>%s</h1>" % i) for i in
>>> range(10)]
>>>         super(Carousel, self).__init__(*args, **kwargs)
>>>
>>>         def interact(n):
>>>             self.children = [self.might_show[n]]
>>>
>>>         self.show = show
>>>
>>> carousel = Carousel()
>>> interact(carousel.interact, n=(0, len(carousel.might_show)-1))
>>> carousel
>>
>>
>> I don't know much about how matplotlib interacts with widgets/traitlets...
>> but presumably the ImageWidget will accept them as its value.
>>
>> You could move even more behavior into the class itself, but eventually
>> one would likely need something more complicated than what interact provides
>> out of the box...
>>
>> @adam: Sorry it took me a while to respond. Here is an updated version of
>> the fake GUI, implemented as a series of classes: a standalone graph, a
>> couple reusable control components and the full-blown end user GUI. I tried
>> to put a few examples of different techniques in that we have used: link,
>> on_trait_changed, CSS, Bootstrap. I didn't do any custom Backbone, as that
>> is a whole other kettle of fish.
>>
>>> http://nbviewer.ipython.org/gist/bollwyvl/ddd4bf5d7c879012fa2c
>>
>>
>> There are a few more gotchas that would come along with this, such as
>> installing assets, if you end up using them, but there are a good number of
>> threads/examples out there for install_nbextension/load_nbextensions. In a
>> pinch, you could even cheat and have an HTML embed the style directly, I
>> guess!
>>
>> I didn't use the "wire" concept from before: while it has proven useful
>> for quickly hacking stuff together, i have found it might be a bit "cute"
>> for something that one actually wanted to release and/or expect people to be
>> able to extend. If i can figure out how to get it to easily un-listen for
>> things, it might be work saving, but in the meantime link and
>> on_trait_changed are good enough!
>>
>> Hope this helps!
>>
>> On Sat, Aug 30, 2014 at 2:21 PM, Antonino Ingargiola <tritemio at gmail.com>
>> wrote:
>>>
>>> Hi,
>>>
>>> Sorry for entering in the discussion on-fly...
>>>
>>> My question is more specific (but possibly very similar). Would be
>>> possible to call interact with a class object (i.e. a callable class)
>>> instead of a function? This would allow to store all the GUI specific state
>>> in the class (for example precomputing figures) without the need of using
>>> globals.
>>>
>>> When I quickly tried (with ipython 2.2), interact returned an error
>>> complaining about the number of parameters passed to the object. So I
>>> resorted to using globals. Below I attached the code I currently use to
>>> pre-compute a set of figures (a slider selects which figure to display). I
>>> would appreciate any comment on possibly improving this pattern.
>>>
>>> fig_cache = {}
>>> def plot_mfit_i(ich=0, nodisplay=False):
>>>     global fig_cache
>>>     if ich not in fig_cache:
>>>         fig = mfit.plot_mfit(fitter, ich=ich, residuals=True,
>>> return_fig=True)
>>>         fig_cache[ich] = fig
>>>         plt.close(fig)
>>>     if not nodisplay:
>>>         display(fig_cache[ich])
>>>
>>> for i in range(8): plot_mfit_i(i, nodisplay=True)  # Precompute all the
>>> figures
>>>
>>> interact(plot_mfit_i, ich=(0, 7), nodisplay=fixed(False));  # display the
>>> figure selected through the slider
>>>
>>> --
>>> Antonio
>>>
>>> On Sat, Aug 30, 2014 at 10:49 AM, Cyrille Rossant
>>> <cyrille.rossant at gmail.com> wrote:
>>>>
>>>> I think you can use the "display" function to render a widget instance,
>>>> does that answer your question?
>>>> ________________________________
>>>> De : Adam Hughes
>>>> Envoyé : ‎30/‎08/‎2014 18:43
>>>> À : IPython developers list
>>>> Objet : Re: [IPython-dev] Widget example that uses classes instead of
>>>> globals?
>>>>
>>>> And just to clarify, I presume that the notebook is actively "looking"
>>>> for particular functions or something in the cell that let's the notebook
>>>> know "hey, this is widget/GUI code, I need to output it as so".  I had
>>>> worried that if this critical piece was buried in a class, the notebook
>>>> wouldn't recognize it, and the GUI wouldn't display.
>>>>
>>>>
>>>> On Sat, Aug 30, 2014 at 1:41 PM, Adam Hughes <hughesadam87 at gmail.com>
>>>> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> This question follows directly from this recent thread on the
>>>>> feasiblity of widgets
>>>>> (http://python.6.x6.nabble.com/Feasilibity-of-widgets-layout-for-mimicking-this-td5068197.html)
>>>>> but I thought was specific enough to be a new thread.
>>>>>
>>>>> In all of the notebook examples I've seen, a GUI is defined in its own
>>>>> cell with global variables that are shared between functions.  I'd really
>>>>> like to see a complete, simple example of a GUI build as a class, where most
>>>>> of the events, updates and default values are set within the class.  And
>>>>> then when the class is instantiated, the notebook somehow can still output
>>>>> the GUI.
>>>>>
>>>>> For example, would something of this design be compatible with the
>>>>> current widget design pattern:
>>>>>
>>>>> class Foo(object):
>>>>>
>>>>>    variable = defaultvalue
>>>>>
>>>>>    def update_variable(self):
>>>>>       ....
>>>>>
>>>>>    def redraw(self):
>>>>>       ...
>>>>>
>>>>> # Instantiate the class
>>>>> f = Foo()
>>>>> f.variable_widget.on_trait_change(update_variable, 'value')
>>>>>
>>>>> Or is this type of design pattern out of the question?  We're trying to
>>>>> move in this direction so that we can compartmentalize and template as much
>>>>> behavior as possible, and make a simple framework for building up more
>>>>> complex GUIs.  It's just now clear to me if such a pattern is possible.  If
>>>>> anyone has any insights or examples, would you mind sharing?
>>>>>
>>>>> THanks
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> IPython-dev mailing list
>>>> IPython-dev at scipy.org
>>>> http://mail.scipy.org/mailman/listinfo/ipython-dev
>>>>
>>>
>>>
>>> _______________________________________________
>>> IPython-dev mailing list
>>> IPython-dev at scipy.org
>>> http://mail.scipy.org/mailman/listinfo/ipython-dev
>>>
>>
>>
>> _______________________________________________
>> IPython-dev mailing list
>> IPython-dev at scipy.org
>> http://mail.scipy.org/mailman/listinfo/ipython-dev
>>
>
>
> _______________________________________________
> IPython-dev mailing list
> IPython-dev at scipy.org
> http://mail.scipy.org/mailman/listinfo/ipython-dev
>



-- 
Brian E. Granger
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgranger at calpoly.edu and ellisonbg at gmail.com



More information about the IPython-dev mailing list