如何防止 bqplot 中交互式绘图的递归?

How to prevent recursion with interactive plot in bqplot?

我使用 bqplot 创建了一个交互式散点图,您可以在其中拖动点(使用 enable_move=True)。

我不希望用户将点拖动到直线 y=x 上方。 如果他们这样做了,我希望该点回到最近的位置。

问题是我不确定如何避免这里的无限递归。

散点图需要知道它的点何时移动,以便检查移动并可能快速返回。 但是,当它开始回弹时,这种(点位置的)变化似乎会触发相同的回调。

谁能告诉我处理这个基本问题的“正确”方法?

import bqplot.pyplot as plt
import numpy as np

def on_point_move(change, scat):
    if np.any(newx < scat.y):
        scat.x = change['old']
    
fig = plt.figure(animation_duration=400)
xs = 1.0*np.arange(3) # make sure these are floats
ys = 1.0*np.arange(3)
scat = plt.scatter(xs, ys, colors=['Red'], default_size=400, enable_move=True)
scat.observe(lambda change: on_point_move(change, scat), names=['x'])
fig

您可以暂时禁用 on_point_move 功能中的观察。我也稍微改变了逻辑。

import bqplot.pyplot as plt
import numpy as np

def on_point_move(change):
    if np.any(scat.x < scat.y):
        scat.unobserve_all()
        if change['name'] == 'x':
            scat.x = change['old']
        elif change['name'] == 'y':
            scat.y = change['old']
        scat.observe(on_point_move, names=['x','y'])
    

fig = plt.figure(animation_duration=400)
xs = 1.0*np.arange(3) # make sure these are floats
ys = 1.0*np.arange(3)
scat = plt.scatter(xs, ys, colors=['Red'], default_size=400, enable_move=True)
scat.observe(on_point_move, names=['x','y'])

fig