Python Bokeh:使用编辑工具时禁用自动测距

Python Bokeh:使用编辑工具时禁用自动测距,python,bokeh,Python,Bokeh,我在我的Bokeh图中加入了这个元素,让用户圈出点。当用户在绘图边缘附近绘制一条线时,该工具会展开轴,这通常会弄乱图形。当用户在绘图时,是否有方法冻结轴 我用的是Bokeh1.3.4 MRE: import numpy as np import pandas as pd import string from bokeh.io import show from bokeh.plotting import figure from bokeh.models import ColumnDataSour

我在我的Bokeh图中加入了这个元素,让用户圈出点。当用户在绘图边缘附近绘制一条线时,该工具会展开轴,这通常会弄乱图形。当用户在绘图时,是否有方法冻结轴

我用的是Bokeh1.3.4

MRE:

import numpy as np
import pandas as pd
import string

from bokeh.io import show
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, LabelSet
from bokeh.models import PolyDrawTool, MultiLine


def prepare_plot():
    embedding_df = pd.DataFrame(np.random.random((100, 2)), columns=['x', 'y'])
    embedding_df['word'] = embedding_df.apply(lambda x: ''.join(np.random.choice(list(string.ascii_lowercase), (8,))), axis=1)

    # Plot preparation configuration Data source
    source = ColumnDataSource(ColumnDataSource.from_df(embedding_df))
    labels = LabelSet(x="x", y="y", text="word", y_offset=-10,x_offset = 5,
                      text_font_size="10pt", text_color="#555555",
                      source=source, text_align='center')
    plot = figure(plot_width=1000, plot_height=500, active_scroll="wheel_zoom",
                      tools='pan, box_select, wheel_zoom, save, reset')

    # Configure free-hand draw
    draw_source = ColumnDataSource(data={'xs': [], 'ys': [], 'color': []})
    renderer = plot.multi_line('xs', 'ys', line_width=5, alpha=0.4, color='color', source=draw_source)
    renderer.selection_glyph = MultiLine(line_color='color', line_width=5, line_alpha=0.8)
    draw_tool = PolyDrawTool(renderers=[renderer], empty_value='red')
    plot.add_tools(draw_tool)

    # Add the data and labels to plot
    plot.circle("x", "y", size=0, source=source, line_color="black", fill_alpha=0.8)
    plot.add_layout(labels)
    return plot


if __name__ == '__main__':
    plot = prepare_plot()
    show(plot)

PolyDrawTool实际上更新了一个
ColumnDataSource
,以驱动绘制用户指示内容的图示符。你看到的行为是这个事实的自然结果,结合了Bookh的默认自动范围<代码> DATARange1D< /Cord>(默认情况下,在计算自动边界时也考虑每一个字形)。因此,您有两种选择:

  • 根本不要使用
    DataRange1d
    ,例如,调用
    图时可以提供固定的轴边界:

    p = figure(..., x_range=(0,10), y_range=(-20, 20)
    
    或者,您可以在事件发生后设置它们:

    p.x_range = Range1d(0, 10)
    p.y_range = Range1d(-20, 20)
    
    当然,使用这种方法,您将不再获得任何自动测距;您需要将轴范围精确设置为所需的起点/终点

  • 通过显式设置其
    渲染器
    属性,使
    DataRange1d
    更具选择性:

    r = p.circle(...)
    p.x_range.renderers = [r] 
    p.y_range.renderers = [r] 
    
    <>代码>数据DATARGANE/COD>模型只考虑圆的渲染器,计算自动的远程启动/结束。p>

是的,我可以尝试制作MRE。我刚意识到我可能说得那么糟糕。轴在定位直线时会展开,但如果直线在原始边界内结束,则会反弹。仅当绘制的线结束于原始边界之外时,更改才是永久性的。