0

我正在尝试了解如何实现散景自定义扩展来创建一些我想要用于我的数据项目的小部件。我试图在此处遵循此示例,但在运行 bokeh 提供的示例扩展时遇到了问题。我目前正在返回一个错误

ValueError:期望 HasProps 的子类,得到类 'bokeh.models.sources.ColumnDataSource'

这是当 DrawTool 类在第 80 行调用 source = Instance(ColumnDataSource) 时引起的。我不确定我现在做错了什么,但我的第一个想法是它与我正在使用的 IDE 有关吗?我目前正在使用 spyder(python 3.6) 并拥有最新的散景更新 2.1.0。

这是我第一次体验散景扩展,所以我很无知,我一直在网上寻找帮助,但找不到太多。我当前的代码正是他们在示例站点上的代码,但为了方便起见,我将其发布在这里,

from bokeh.core.properties import Instance
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, Tool
from bokeh.plotting import figure
from bokeh.util.compiler import TypeScript

output_file('tool.html')

TS_CODE = """
import {GestureTool, GestureToolView} from "models/tools/gestures/gesture_tool"
import {ColumnDataSource} from "models/sources/column_data_source"
import {PanEvent} from "core/ui_events"
import * as p from "core/properties"

export class DrawToolView extends GestureToolView {
  model: DrawTool

  //this is executed when the pan/drag event starts
  _pan_start(_ev: PanEvent): void {
    this.model.source.data = {x: [], y: []}
  }

  //this is executed on subsequent mouse/touch moves
  _pan(ev: PanEvent): void {
    const {frame} = this.plot_view

    const {sx, sy} = ev
    if (!frame.bbox.contains(sx, sy))
      return

    const x = frame.xscales.default.invert(sx)
    const y = frame.yscales.default.invert(sy)

    const {source} = this.model
    source.get_array("x").push(x)
    source.get_array("y").push(y)
    source.change.emit()
  }

  // this is executed then the pan/drag ends
  _pan_end(_ev: PanEvent): void {}
}

export namespace DrawTool {
  export type Attrs = p.AttrsOf<Props>

  export type Props = GestureTool.Props & {
    source: p.Property<ColumnDataSource>
  }
}

export interface DrawTool extends DrawTool.Attrs {}

export class DrawTool extends GestureTool {
  properties: DrawTool.Props
  __view_type__: DrawToolView

  constructor(attrs?: Partial<DrawTool.Attrs>) {
    super(attrs)
  }

  tool_name = "Drag Span"
  icon = "bk-tool-icon-lasso-select"
  event_type = "pan" as "pan"
  default_order = 12

  static init_DrawTool(): void {
    this.prototype.default_view = DrawToolView

    this.define<DrawTool.Props>({
      source: [ p.Instance ],
    })
  }
}
"""


class DrawTool(Tool):
    __implementation__ = TypeScript(TS_CODE)
    source = Instance(ColumnDataSource)


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

plot = figure(x_range=(0, 10), y_range=(0, 10), tools=[DrawTool(source=source)])
plot.title.text = "Drag to draw on the plot"
plot.line('x', 'y', source=source)

show(plot)
4

2 回答 2

0

您的代码在 Bokeh 2.1.0 中对我来说效果很好。并且不应该与 IDE 有任何关系,因为它不应该影响代码的运行时属性。当然,您可以使用 Python 手动运行脚本。

如果这仍然给您错误,那么您的 Bokeh 安装可能已损坏。毕竟bokeh.models.sources.ColumnDataSource 的子类HasProps。尝试从头开始创建虚拟环境。

这是我在运行您的代码并与绘图进行一些交互时看到的内容:

工作图示例

于 2020-06-18T04:12:54.560 回答
0

以防万一将来有人遇到这个问题,我想我会在这里为那些不熟悉创建自定义扩展并且找不到解决方案的人发布我所做的事情。

事实证明,正如尤金所指出的那样,我的散景装置已损坏。我继续按照Getting Started上的 Bokehs 文档对 bokeh 进行了全面重建。在 fork 最新的 bokeh 存储库之后,我遇到了 anaconda 环境尝试运行此步骤的问题,在该步骤中我发现了一些阻止我创建环境的 Openssl 损坏文件。

在 GitHub 上找到了这个修复程序,它对我有用,还有其他可能的解决方案。完成其余步骤后,我成功地让自定义扩展在本地运行。

TLDR:问题是散景安装损坏。如果您对此不熟悉并计划进行自定义扩展或使用散景模型,请分叉并克隆散景的本地构建,而不是依赖快速安装方法。

于 2020-06-18T20:10:16.337 回答