[IPython-dev] Fwd: notebook plots via javascript

Zoltán Vörös zvoros at gmail.com
Mon Jun 4 11:15:31 EDT 2012


Dear John,

Many thanks for your comments! I certainly didn't expect that you would 
chip in. Here are a couple of thoughts.
>> On the issue of interaction (pan/zoom/add or remove line) in the
>> notebook.  While I appreciate that there is value in
>> what-you-see-is-what-you-get vis-a-vis code in the notebook vs the
>> saved figure, I don't think it is our job to overly limit what the
>> user does.  Persistence is only one thing notebooks are good for,
>> others will use them as an interactive scratch pad, and interacting
>> with the figure in all sorts of ways is useful.
I definitely agree with this, and this is why I have said earlier that 
first we should sort out how interactive plots are going to be used. 
There are two things to consider, however. The first is that if one 
wants to have full interactivity, somewhere at the level of the Qt4, or 
GTK backends, then one has to go no further than Ludwig Schwardt's HTML5 
backend. The dependency on the extra web server could be removed, and 
everything could be handled in the ipython kernel. So, if this is indeed 
the case, then we should just slim down Ludwig's backend, and we are done.
The other comment I would add here is that once the decorators in the 
notebook are implemented (I have been given to understand that this is 
high on the list of the core developers), interactivity with the figure 
could be handled in a much easier way. Thus, I would probably not invest 
too much time in implementing a full-blown javascript backend.
>> After they have
>> played around and want to persist the notebook, they always have the
>> option of re-running the cell to restore the original generated code
>> sans interaction.  I think it best to give people the maximally useful
>> thing, and let them make the right decisions about how they want to
>> use it.
But this argument can be turned around: if I want to plot something else 
(e.g., remove a dataset from the plot), I can do that on the command 
line. Also, your argument hangs on the assumption that ipython is 
running in the background. But what if I print out the notebook with the 
"wrong" figures? I believe, this would lead to problems later on. The 
difficulty is that in the notebook you can see the code that actually 
generated the figure, while in Origin you can't, so it won't confuse 
you. Also, if you don't care about whether the figure that you see is 
related to the code above it, you could just use the notebook with the 
Qt4, or GTK backend. Then you would have interactivity, and in fact, 
there are already ways to connect all kinds of fancy functions to those 
backends. But you know this much better than me:)

But again, it would be great, if we could first sort out what is 
expected of the notebook.
>> In that vein, if you try to add rich interactions in a javascript
>> backend, I do think you will hit a wall at some point because the
>> backends are fairly dumbed down in mpl.  They are mostly a collection
>> of geometric primitives in display coordinates.  Eg, the axis tick
>> doesn't know it is part of the axis at the backend level, so
>> implementing interactive navigation might be challenging without
>> client/server cross-talk.
You are absolutely right, and simple things, like zooming, are already 
quite difficult with the present toolkit. What one could do in the 
notebook is return only the plot as javascript function, but then it 
would have to be "decorated" with helper functions that could be passed 
in from the python console. I believe, this is doable, though, not very 
elegant.
>> Another approach might be to not implement a backend at all, but a
>> matplotlib.figure.Figure persistence mechanism that outputs javascript
>> code.  Eg, if you hi-jacked the Figure.draw method, you might be able
>> to output more intelligent javascript because you would know "this is
>> the figure, this is the axes, this is the axis" and would have a
>> better view of the transformations, etc.  Just a thought about an
>> alternative approach.
Thanks for the pointer! I will try to look into that.
>> We are also open to modifying the mpl
>> middle-ware to pass you more information as needed to the backend to
>> make sure you have what you need at the backend level.  Eg, we already
>> have the open_group/close_group methods, motivated by SVG to define
>> clickable groups (suppose you want to change the font of all the
>> ticklabels in inkscape), and we could extend this concept to pass
>> additional meta-data through.  Eg, the Axis open_group call could pass
>> "self" through if you wanted to grab some of the data from the
>> instance you were rendering.
>>
>> I have been concerned for some time that the need for interactive
>> javascript plotting in the notebook would push efforts into yet
>> another plotting library, and hence fragment community resources.  If
>> we can get the job done in mpl, I would be very happy, and I'm sure we
>> can come up with some resources on our end to help you.
This sounds great, many thanks for offering your help! What could be 
useful is a tag for each path that would tell the user what that path 
belongs to. Whether it is a data point (if so, which dataset it belongs 
to), a tickmark, part of the legend, axis label and so on. So, instead 
of the code

  for points, control in path.iter_segments(transform, clip=None):
             if contol == Path.MOVETO:
                 ctx.moveTo(points[0], points[1])


it would be useful to have something like this

  for points, control, belongsto in path.iter_segments(transform, 
clip=None):
             if contol == Path.MOVETO:
                 if belongsto == path.TICKMARK:
                     pass
                 else;
                     ctx.moveTo(points[0], points[1])

or something like that. I just don't know what the least obtrusive way 
would be; my example would probably wreak havoc in other parts of the 
code. As you said above, some notion of the underlying data would be 
quite beneficial.

Beyond the notebook, having static, but interactive backends would be 
useful, anyway, because at this point, there is no easy way of producing 
an web-embeddable interactive figure. However, it is not clear to me, 
how one would handle the interactivity in the python code that produces 
the figures. Keyword arguments could, perhaps, do...?

Cheers,
Zoltán




More information about the IPython-dev mailing list