Python 通过再次单击按钮来反转Bokeh按钮操作

Python 通过再次单击按钮来反转Bokeh按钮操作,python,python-3.x,bokeh,Python,Python 3.x,Bokeh,我设想了一个仪表板,您可以单击几个按钮中的一个执行添加操作,然后再次单击按钮撤消操作。实际上,undo是一个错误的词,因为我不希望第二次单击将其恢复到原始状态,因为这可能会干扰另一个按钮的结果,但我希望第二次单击将其取出。例如,我遇到了以下问题,按下标有Apple的按钮,会向每个数据点添加3.0,从而更新圆图示符的绘图。我的问题是,“是否有办法设置代码,再次按下按钮将减去3.0?” 从bokeh.models导入ColumnDataSource,CustomJS,按钮 从bokeh.plotti

我设想了一个仪表板,您可以单击几个按钮中的一个执行添加操作,然后再次单击按钮撤消操作。实际上,undo是一个错误的词,因为我不希望第二次单击将其恢复到原始状态,因为这可能会干扰另一个按钮的结果,但我希望第二次单击将其取出。例如,我遇到了以下问题,按下标有
Apple
的按钮,会向每个数据点添加
3.0
,从而更新圆图示符的绘图。我的问题是,“是否有办法设置代码,再次按下按钮将减去
3.0
?”

从bokeh.models导入ColumnDataSource,CustomJS,按钮
从bokeh.plotting导入图形,输出_文件,显示
从bokeh.layouts导入列
输出文件(“js_on_change.html”)
x=[1.2,2.4,0.8,5.6,12.1,8.8]
y=[3.4,1.1,4.2,6.6,1.8,12.1]
z=[“苹果”、“苹果”、“橙色”、“橙色”、“橙色”、“橙色”]
数据=dict(x=x,y=y,z=z)
source=ColumnDataSource(数据)
绘图=图形(绘图宽度=400,绘图高度=400)
图.圆('x','y',源=源,大小=8,线α=0.6)
callback1=CustomJS(args=dict(source=source),code=“”
var数据=source.data;
var f=3.0
变量x=数据['x']
变量y=数据['y']
对于(变量i=0;i
一个可能的解决方案是在自定义JavaScript中添加第二张CD来计算点击次数

CustomJS(args=dict(source=source, counter=counter), code="...")
在JavaScript中,必须添加几行代码。如果单击次数为偶数,则添加
f
,否则减去它

var count = counter.data;
var c = count['counter']
if (c[0]%2==1) f = -1*f;
c[0]++
counter.change.emit();
创建的图形将如下所示:

完整代码

from bokeh.models import ColumnDataSource, CustomJS, Button, Range1d
from bokeh.plotting import Figure, output_notebook, show
from bokeh.layouts import column
output_notebook()

x = [1]
y = [3]
z = ['Apple']

data = dict(x=x, y=y, z=z)
source = ColumnDataSource(data)

counter = [0]
counter = dict(counter=counter)
counter = ColumnDataSource(counter)

plot = Figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source, size=8, line_alpha=0.6)
plot.y_range = Range1d(0,7)

callback1 = CustomJS(args=dict(source=source, counter=counter), code="""
    var f = 3.0
    
    var count = counter.data;
    var c = count['counter']
    if (c[0]%2==1) f = -1*f;
    c[0]++
    counter.change.emit();
    
    var data = source.data;
    var x = data['x']
    var y = data['y']
    for (var i = 0; i < x.length; i++) {
        y[i] = y[i] + f
    }
    source.change.emit();
""")

button = Button(label="Apple", button_type="success")
button.js_on_click(callback1)

layout = column(button, plot)

show(layout)
从bokeh.models导入ColumnDataSource、CustomJS、Button、Range1d
从bokeh.plotting导入图形,输出\ U笔记本,显示
从bokeh.layouts导入列
输出_笔记本()
x=[1]
y=[3]
z=['苹果']
数据=dict(x=x,y=y,z=z)
source=ColumnDataSource(数据)
计数器=[0]
计数器=指令(计数器=计数器)
计数器=列数据源(计数器)
绘图=图形(绘图宽度=400,绘图高度=400)
图.圆('x','y',源=源,大小=8,线α=0.6)
plot.y_范围=范围1d(0,7)
callback1=CustomJS(args=dict(source=source,counter=counter),code=“”
var f=3.0
var计数=计数器数据;
变量c=计数[“计数器”]
如果(c[0]%2==1)f=-1*f;
c[0]++
counter.change.emit();
var数据=source.data;
变量x=数据['x']
变量y=数据['y']
对于(变量i=0;i
谢谢,在我处理其他Bokeh功能时,我肯定会有更多关于堆栈溢出的问题要问。
from bokeh.models import ColumnDataSource, CustomJS, Button, Range1d
from bokeh.plotting import Figure, output_notebook, show
from bokeh.layouts import column
output_notebook()

x = [1]
y = [3]
z = ['Apple']

data = dict(x=x, y=y, z=z)
source = ColumnDataSource(data)

counter = [0]
counter = dict(counter=counter)
counter = ColumnDataSource(counter)

plot = Figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source, size=8, line_alpha=0.6)
plot.y_range = Range1d(0,7)

callback1 = CustomJS(args=dict(source=source, counter=counter), code="""
    var f = 3.0
    
    var count = counter.data;
    var c = count['counter']
    if (c[0]%2==1) f = -1*f;
    c[0]++
    counter.change.emit();
    
    var data = source.data;
    var x = data['x']
    var y = data['y']
    for (var i = 0; i < x.length; i++) {
        y[i] = y[i] + f
    }
    source.change.emit();
""")

button = Button(label="Apple", button_type="success")
button.js_on_click(callback1)

layout = column(button, plot)

show(layout)