散景动态添加箭头

问题描述 投票:0回答:1

我不了解使用Bokeh。对于我的项目,我正在尝试使用bokeh从一个点到另一个点制作箭头。因此,我先双击然后再单击一次绘制箭头。但这似乎无能为力。

from bokeh.models import Arrow, OpenHead
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.io import curdoc
from bokeh.events import DoubleTap, Tap

coordList=[]
source = ColumnDataSource(data=dict(x=[], y=[]))

#add a dot where the click happened
def callback(event):
    Coords=(event.x,event.y)
    coordList.append(Coords)
    source.data = dict(x=[i[0] for i in coordList], y=[i[1] for i in coordList])
    for x, y in coordList:
        if x == None and y ==  None:
            coordList.pop(0)
p = figure(plot_width=700, plot_height=700)

def draw(event):
    # Function to add arrows from the coordList
    p.add_layout(Arrow(end=OpenHead(line_color="firebrick", line_width=4),
                   x_start=1, y_start=1, x_end=4, y_end=4))

p.circle(source=source,x='x',y='y')
p.on_event(DoubleTap, callback)
p.on_event(Tap, draw)

curdoc().add_root(p)

任何帮助将不胜感激。谢谢

python data-visualization bokeh
1个回答
0
投票

是,是个错误:https://github.com/bokeh/bokeh/issues/8862

请查看我的内联评论。

from bokeh.events import DoubleTap, Tap
from bokeh.io import curdoc
from bokeh.models import Arrow, OpenHead, CustomJS
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure

p = figure(plot_width=700, plot_height=700)
# We need to have at least one renderer present for the plot
# to be able to compute the initial ranges. Otherwise, the very
# first double tap event will have no coordinates.
bogus_renderer = p.circle(x=[0], y=[0], fill_alpha=0, line_alpha=0)

# This is needed to make sure that PlotView recalculates
# all renderers' views when we call `add_layout`.
p.js_on_change('center', CustomJS(code='cb_obj.properties.renderers.change.emit();'))

source = ColumnDataSource(data=dict(x=[], y=[]))


def callback(event):
    # Removing the renderer to avoid messing with DataRange1d.
    bogus_renderer.data_source.data = dict(x=[], y=[])
    source.stream(dict(x=[event.x], y=[event.y]))


def draw(event):
    if source.data['x']:
        last_dot_x = source.data['x'][-1]
        lalt_dot_y = source.data['y'][-1]
        p.add_layout(Arrow(end=OpenHead(line_color="firebrick", line_width=4),
                           x_start=last_dot_x, y_start=lalt_dot_y, x_end=event.x, y_end=event.y))


p.circle(source=source, x='x', y='y')
p.on_event(DoubleTap, callback)
p.on_event(Tap, draw)

curdoc().add_root(p)
© www.soinside.com 2019 - 2024. All rights reserved.