3

I've searched a lot on this topic but I'm not a web developer so I know I'm missing some concepts.

When I run matplotlib locally and specify the 'webagg' backend, running plt.show() starts a lightweight webserver and opens the plot in my browser with full interactive functionality.

import matplotlib as mpl
mpl.use('webagg')
from matplotlib import pyplot as plt
import numpy as np

f,ax = plt.subplots(1)
ydata = np.random.randint(0,100,100)
xdata = np.linspace(1,100,100)
ax.plot(xdata,ydata,picker=5)
ax.set_title('Click the line to change the color')

def onpick(event):
    event.artist.set_color('red')

    f.canvas.draw_idle()
f.canvas.mpl_connect('pick_event', onpick)

plt.show()

My question is: Is it possible to use the webagg backend with my django website to serve neat interactive matplotlib figures to users? In other words, can I use the above code somewhere in my django site such that the plot will embed in a web page?

(I know about tools like mpld3, which are very cool, but don't fully recreate the widget/picker functionality in matplotlib).

Mike J
  • 47
  • 7

1 Answers1

3

There is one example of how to embed the interactive figures using the web_agg and Tornado. I successfully changed it to using Flask, but still using the Tornado web sockets. Try out running the example below first and see if the interactivity is 'good enough' for you. When I ran it, the response is not really super snappy (read last part if you want a bit more info on this).

Basically to implement it on a webpage you use a websocket to send/receive messages for the interactive part, and to send over the plot as binary data if it has to be redrawn.

Following the example it is quite straight forward to use with different frameworks/servers (check the above link for more details):

  • create your figure like normal.
  • create a manager for your figure with webagg backend
  • serve the mpl.js
  • implement a websocket object, it needs send_json and send_binary functions (these are called from the webagg python code when you add the websocket to the manager)
  • in the template that you serve on the client side. Use javascript to create a websocket and create a figure using mpl.js.

It is good to look through the webagg github stuff (webagg_core, webagg, mpl.js, maybe also nb_agg). I know this is not a complete answer, but hopefully it gives you some direction on what you need to do.

Bit off-topic about the comment in the first paragraph:

Unfortunately I am new to web development to determine if the response is a limit of how the web_agg is implemented in the example, or if it depends on how your server/backend/threading is set up. From what I can see the jupyter notebook nb_agg backend also uses part of the web_agg backend and seems to work a lot more responsive in the notebook. But I should probably make a separate question discussing these issues.