Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Initial, very rough, comm-based backend#2524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Any comments on setting this up for testing etc.@jasongrout? |
jasongrout commentedOct 18, 2013
It doesn't work just yet (I was able to get an image to display, but not the interactive tools to load). You'll need IPython withipython/ipython#4195 applied. And actually, there were some changes in the IPython pull request that may necessitate changes in this pull request. Also, I was testing against the Sage Cell Server---the IPython notebook will be very similar, but I didn't have time to test against it yet. Probably the first thing to do would be to set up IPython with that pull request mentioned above and get familiar with the Comm API (there are some simple examples on the ticket). Then updating this to use the refactored communication framework that Michael pointed out on the mailing list. |
jasongrout commentedNov 15, 2013
I updated this and it works now with IPython master. Execute this in an IPython notebook cell frommatplotlib.backends.backend_webagg_coreimport (FigureManagerWebAgg,new_figure_manager_given_figure)importjsonfromIPython.displayimportdisplay,Javascript,HTMLfromIPython.kernel.commimportCommfromuuidimportuuid4asuuidfrombase64importb64encodedisplay(Javascript(FigureManagerWebAgg.get_javascript()))classCommFigure(object):def__init__(self,figure):self.figure=figureself.manager=new_figure_manager_given_figure(id(figure),figure)self.comm=CommSocket(self.manager)self.comm.open()classCommSocket(object):""" A websocket for interactive communication between the plot in the browser and the server. In addition to the methods required by tornado, it is required to have two callback methods: - ``send_json(json_content)`` is called by matplotlib when it needs to send json to the browser. `json_content` is a JSON tree (Python dictionary), and it is the responsibility of this implementation to encode it as a string to send over the socket. - ``send_binary(blob)`` is called to send binary image data to the browser. """supports_binary=Falsedef__init__(self,manager):self.manager=managerself.uuid=str(uuid())display(HTML("<div id='%s'></div>"%self.uuid))self.comm=Comm('matplotlib',data={'id':self.uuid})defopen(self):# Register the websocket with the FigureManager.self.manager.add_web_socket(self)self.comm.on_msg(self.on_message)defon_close(self):# When the socket is closed, deregister the websocket with# the FigureManager.self.manager.remove_web_socket(self)self.comm.close()defsend_json(self,content):self.comm.send({'data':json.dumps(content)})defsend_binary(self,blob):data_uri="data:image/png;base64,{0}".format(b64encode(blob))self.comm.send({'data':data_uri})defon_message(self,message):# The 'supports_binary' message is relevant to the# websocket itself. The other messages get passed along# to matplotlib as-is.# Every message has a "type" and a "figure_id".message=json.loads(message['content']['data'])ifmessage['type']=='supports_binary':self.supports_binary=message['value']else:self.manager.handle_json(message)Javascript("""var comm_websocket = function(comm) { var ws = {}; // MPL assumes we have a websocket that is not open yet // so we run the onopen handler after they have a chance // to set it. ws.onopen = function() {}; setTimeout(ws.onopen(), 0); ws.close = function() {comm.close()}; ws.send = function(m) { comm.send(m); console.log('sending',m); }; comm.on_msg(function(msg) { console.log('receiving', msg); ws.onmessage(msg['content']['data']) }); return ws;}var figures = [];mpl.mpl_figure_comm = function(comm, msg) {var id = msg.content.data.id;var element = $("#"+id);var c = comm_websocket(comm) var m = new mpl.figure(id, c, function() {console.log('download')}, element.get(0)); figures.push(m); container.show();}IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);""") and then you can do something like: frommatplotlib.figureimportFigureimportnumpyasnpfig=Figure()a=fig.add_subplot(111)t=np.arange(0.0,3.0,0.01)s=np.sin(2*np.pi*t)a.plot(t,s)CommFigure(fig) |
jasongrout commentedNov 15, 2013
Here are a few points to still be cleaned up:
|
This is looking really good. Obviously there are a couple of trivial UI enhancements to add (the button icons, resize, download button doesn't work etc.) and it 'feels' like there is a latency issue which I didn't have with the WebAgg backend (perhaps that is the cost of using base 64 vs binary) but generally this is and absolutelyhuge step towards the feature that we all want to see in matplotlib/IPython. I think the next steps are to look at some of the issues above, and to thrash out whether we need to consider compressing the data payload (and decompressing in JS on the other side). It'd also be nice if server side rendering errors (which I got because I didn't build mpl properly after updating) were tracebacked on the client, and another nice to have would be to have some sort of debug panel, which can tell us the FPS etc. Awesome stuff. What are your plans from here@jasongrout? |
… the webagg backendThis is so that the javascript generation works before any plots have been initialized.
jasongrout commentedNov 15, 2013
On 11/15/13 4:01 AM, Phil Elson wrote:
The image data is already compressed (png). I agree that it still feels
+1
Get it working in the Sage cell server. ... Done! http://sagecell.sagemath.org/?q=ilpajg (for a sage plotting example) http://sagecell.sagemath.org/?q=spadja (for one of the examples from the |
@jasongrout - is it worth merging the machinery that you've had to add even if we don't actually have the CommFigure class? |
jasongrout commentedJan 10, 2014
I think probably not. Let's wait to get a commfigure class. I've been working a ton with the IPython folks on their widget infrastructure, and it's helping me understand how best to approach things. |
Closing this as I this was the base of nbagg which has sense been merged. |
DO NOT MERGE. This is a rough draft. I'm creating a pull request just to make commenting on it easier.