Search code examples
pythonipythonjupyter-notebookjupyterbqplot

bqplot: performance issue


I was playing around with on_drag features of bqplot. and I noticed that it is slightly lagging.. I am not sure if this is

  • real issue
  • I do something inappropriate
  • meant to work like it is

so the code I have is the following

from bqplot import pyplot as plt
import numpy as np
fig=plt.figure()
lin=plt.plot([0,1],
             [0,0])
scatt1=plt.scatter([0],[0],colors=['Red'])
scatt2=plt.scatter([1],[0],enable_move=True)

plt.xlim(-3,3)
plt.ylim(-3,3)
fig.layout.height = '500px'
fig.layout.width = '500px'
plt.show()
def call_back2(name, value):
   #print(value,name)
   if value['point']:
       X=value['point']['x']
       Y=value['point']['y']
       lin.x=[scatt1.x[0],(X-scatt1.x)[0]]
       lin.y=[scatt1.y[0],(Y-scatt1.y)[0]]

scatt2.on_drag_start(call_back2)
scatt2.on_drag(call_back2)
scatt2.on_drag_end(call_back2)

it is simply two points connected and you can drag the blue one around what I notice is that the line ever so slightly lags behind the blue dot.


Solution

  • You can't directly drag a point on a line. Your method is only way to do it that I know of and so the line will always follow the scatter point. I couldn't get your code to go noticeably faster.

    from bqplot import pyplot as plt
    import numpy as np
    fig = plt.figure()
    lin=plt.plot([0,1],
                 [0,0])
    scatt1=plt.scatter([0],[0],colors=['Red'])
    scatt2=plt.scatter([1],[0],enable_move=True)
    # scatt2.update_on_move = True
    
    plt.xlim(-3,3)
    plt.ylim(-3,3)
    fig.layout.height = '500px'
    fig.layout.width = '500px'
    plt.show()
    def call_back2(name, value):
    #     with lin.hold_sync():
       lin.x=[lin.x[0], value['point']['x']]
       lin.y=[lin.y[0], value['point']['y']]    
    
    # scatt2.on_drag_start(call_back2)
    scatt2.on_drag(call_back2 )
    # scatt2.on_drag_end(call_back2)
    

    Edit:

    Actually it can be done. Use jslink. The traits must be the same type and length/size. In this case, the 'x' and 'y' traits for the line and scatter marks are arrays of length 2.

    from bqplot import pyplot as plt
    from ipywidgets import jslink
    
    fig = plt.figure()
    
    # Strange bug when 1st point is 0,0. Red point flickers.  
    lin=plt.plot([0.0001,1],
                 [0.0001,0])   
    
    scatt2=plt.scatter(lin.x, lin.y, enable_move = True, colors = ['Red','blue'])
    scatt2.update_on_move = True
    
    # Cover up 1st point so it can't be moved. 
    # Just remove this line if you want both points to be moveable
    scatt3=plt.scatter([lin.x[0]], [lin.y[0]], colors = ['Red']) 
    
    
    plt.xlim(-3,3)
    plt.ylim(-3,3)
    fig.layout.height = '500px'
    fig.layout.width = '500px'
    plt.show()
    
    jslink((scatt2, 'x'), (lin, 'x'))
    jslink((scatt2, 'y'), (lin, 'y'))
    

    Jslink doesn't need the Python kernel for the interactivity to work. You you can create a html file (and js directory) by:

    import ipyvolume.embed
    ipyvolume.embed.embed_html("bqplot.html", fig, offline=True, devmode=False)