首页 > 解决方案 > 在默认值之上添加特定的刻度

问题描述

我想确保在绘图的默认刻度顶部的 X 轴上可以看到几个特定的​​刻度。为此,我在文档FixedTicker 中找到了它,它允许我指定沿 X 轴的精确值,其中应该存在刻度。但是,如果我设置:

p.xaxis.ticker = FixedTicker(ticks=[-1,1])

...这将沿 X 轴的所有代码替换为我指定的两个(一个在 -1 和一个在 1)。我尝试使用 CompositeTicker“扩展”现有代码:

# compose whatever is there by default, adding the fixed points:
p.xaxis.ticker = CompositeTicker(tickers=[p.xaxis.ticker, FixedTicker(ticks=[-1,1])])

这似乎又不能满足我的需要。结果与使用普通的 FixedTicker 相同(我得到一个 X 轴,在位置 -1 和 1 处只有两个刻度)。就好像没有“组合”在进行。阅读文档,CompositeTicker 似乎不仅仅是“单个代码的总和”,因为我读到:

要以不同比例组合以生成刻度值的 Ticker 对象列表。提供的代码应该是有序的。具体来说,如果 S 在 T 之前,那么应该是这样的情况:S.get_max_interval() < T.get_min_interval()

如何在列数据源中的任何数据范围内使用默认的“线性”代码,而只是“突出显示”几个点(默认代码中可能存在也可能不存在)。

例如,一个简单的用例是绘制一个二次函数并在 X 轴上突出显示它的根。

标签: pythonbokeh

解决方案


嗯,这是可能的,但它目前不是内置的。并且“ticker”是正确的概念,因为ticker决定了tick位置应该是什么。然而,正如您所了解的,这CompositeTicker是为当前规模选择一个“最佳”股票(从许多可能中)(即在几个月的范围内选择好日子,在几年的范围内选择好月份)。要像您想要的那样“加入”两个股票代码,需要创建一个自定义扩展,不幸的是,目前这涉及很多样板文件。这是适用于 Bokeh 1.4.0 1的参考版本

from bokeh.core.properties import Float, List
from bokeh.models import BasicTicker
from bokeh.plotting import figure, show
from bokeh.util.compiler import TypeScript

TS_CODE = """
import * as p from "core/properties"
import {TickSpec} from "models/tickers/ticker"
import {BasicTicker} from "models/tickers/basic_ticker"

export namespace MyTicker {
  export type Attrs = p.AttrsOf<Props>
  export type Props = BasicTicker.Props & {
    extra_ticks: p.Property<Array<number>>
  }
}

export interface MyTicker extends MyTicker.Attrs {}

export class MyTicker extends BasicTicker {
  properties: MyTicker.Props

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

  get_ticks_no_defaults(data_low: number, data_high: number, cross_loc: any, desired_n_ticks: number): TickSpec<number> {
    const ticks = super.get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks)
    for (var i=0; i<this.extra_ticks.length; i++) {
      const et = this.extra_ticks[i]
      if (et >= data_low && et <= data_high)
        ticks.major.push(et)
    }
    return ticks
  }

  static init_MyTicker(): void {
    this.define<MyTicker.Props>({
      extra_ticks: [ p.Any ],
    })
  }
}
"""


class MyTicker(BasicTicker):
    __implementation__ = TypeScript(TS_CODE)
    extra_ticks = List(Float)


p = figure()
p.circle([1, 2, 3, 4, 6], [5, 7, 3, 2, 4], size=20)

p.xaxis.ticker = MyTicker(extra_ticks=[3.65])
p.xaxis.major_label_orientation = 1.2

show(p)

请注意,我也旋转了刻度,因为额外的刻度不参与计算以保持刻度“分开”,因此它们可能会重叠。

在此处输入图像描述

“加入”代码可能是一个合理的功能请求,对于新贡献者来说也是一项不错的任务。请随时打开一个GitHub 问题来提出建议。


1请注意,BokehJS 仍处于非常活跃的开发阶段。尽管它的 API 现在已经达到了一定程度的稳定性,但我们还不能保证自定义扩展的版本与版本之间的兼容性。


推荐阅读