范围和轴#

设置范围#

默认情况下,Bokeh 尝试自动设置绘图的数据边界,以紧密贴合数据。但是,您可能需要显式设置绘图的范围。为此,请使用 Range1d 对象设置 x_range 和/或 y_range 属性,该对象允许您设置所需范围的起始结束点。

p.x_range = Range1d(0, 100)

为了方便起见,figure() 函数还可以接受(start, end) 元组作为 x_rangey_range 参数的值。以下是如何使用这两种方法来设置范围

from bokeh.models import Range1d
from bokeh.plotting import figure, show

# create a new plot with a range set with a tuple
p = figure(width=400, height=400, x_range=(0, 20))

# set a range using a Range1d
p.y_range = Range1d(0, 15)

p.scatter([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)

show(p)

范围还具有 bounds 属性,允许您指定绘图的限制,超出这些限制用户无法平移或缩放。

# set a range using a Range1d
p.y_range = Range1d(0, 15, bounds=(0, None))

轴类型#

上面所有示例都使用默认的线性轴。此轴适用于需要在线性刻度上显示数值数据的绘图。但是,您可能拥有分类数据,或者需要在日期时间或对数刻度上显示数值数据。本节向您展示如何在使用 bokeh.plotting 接口时指定轴类型。

分类轴#

要创建分类轴,请为绘图的其中一个范围指定 FactorRange 或要转换为一个范围的因子列表。以下是一个示例

from bokeh.plotting import figure, show

factors = ["a", "b", "c", "d", "e", "f", "g", "h"]
x = [50, 40, 65, 10, 25, 37, 80, 60]

p = figure(y_range=factors)

p.scatter(x, factors, size=15, fill_color="orange", line_color="green", line_width=3)

show(p)

日期时间轴#

注意

本节中的示例需要网络连接,并依赖于开源 Pandas 库来呈现真实的时间序列数据。

对于时间序列或任何涉及日期或时间的数据,您可能希望使用适合不同日期和时间刻度的标签轴。

figure() 函数接受 x_axis_typey_axis_type 作为参数。要指定日期时间轴,请为这两个参数中的任何一个传递 "datetime" 作为值。

import pandas as pd

from bokeh.plotting import figure, show
from bokeh.sampledata.stocks import AAPL

df = pd.DataFrame(AAPL)
df['date'] = pd.to_datetime(df['date'])

# create a new plot with a datetime axis type
p = figure(width=800, height=250, x_axis_type="datetime")

p.line(df['date'], df['close'], color='navy', alpha=0.5)

show(p)

注意

Bokeh 的未来版本将尝试自动检测何时适合使用日期时间轴,并自动添加它们。

对数刻度轴#

呈指数增长或涵盖多个数量级的数据通常需要一个轴处于对数刻度。对于具有幂律关系的数据,您可能希望在两个轴上都使用对数刻度。

您可以使用相同的 figure() 参数 x_axis_typey_axis_type 将一个或两个轴设置为 "log"

默认情况下,Bokeh 计算对数轴范围以适应正值数据。有关如何设置您自己的范围的信息,请参阅 设置范围

from bokeh.plotting import figure, show

x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
y = [10**xx for xx in x]

# create a new plot with a log axis type
p = figure(width=400, height=400, y_axis_type="log")

p.line(x, y, line_width=2)
p.scatter(x, y, fill_color="white", size=8)

show(p)

墨卡托轴#

墨卡托轴可用于瓦片源。您可以使用相同的 figure() 参数 x_axis_typey_axis_type 将一个或两个轴设置为 "mercator"

from bokeh.plotting import figure, show

# range bounds supplied in web mercator coordinates
p = figure(x_range=(-2000000, 2000000), y_range=(1000000, 7000000),
           x_axis_type="mercator", y_axis_type="mercator")

p.add_tile("CartoDB Positron", retina=True)

show(p)

双轴#

您可以向单个绘图添加多个表示不同范围的轴。为此,请使用 extra_x_rangeextra_y_range 属性配置绘图,其中包含“额外”的命名范围。然后,在添加新的图形方法以及使用 Plotadd_layout 方法添加新的轴对象时,您可以参考这些命名范围。以下是一个示例

from numpy import arange, linspace, pi, sin

from bokeh.layouts import column
from bokeh.models import (CustomJS, LinearAxis, Range1d, Select,
                          WheelZoomTool, ZoomInTool, ZoomOutTool)
from bokeh.palettes import Sunset6
from bokeh.plotting import figure, show

x = arange(-2*pi, 2*pi, 0.2)
y = sin(x)
y2 = linspace(0, 100, len(x))

blue, red = Sunset6[2], Sunset6[5]

p = figure(x_range=(-2*pi, 2*pi), y_range=(-1, 1), tools="pan,box_zoom,save,reset")
p.background_fill_color = "#fafafa"

blue_circles = p.scatter(x, y, line_color="black", fill_color=blue, size=12)
p.axis.axis_label = "light blue circles"
p.axis.axis_label_text_color = blue

p.extra_x_ranges['foo'] = Range1d(-2*pi, 2*pi)
p.extra_y_ranges['foo'] = Range1d(0, 100)
red_circles = p.scatter(x, y2, color=red, size=8,
    x_range_name="foo",
    y_range_name="foo",
)

ax2 = LinearAxis(
    axis_label="red circles",
    x_range_name="foo",
    y_range_name="foo",
)
ax2.axis_label_text_color = red
p.add_layout(ax2, 'left')

ax3 = LinearAxis(
    axis_label="red circles",
    x_range_name="foo",
    y_range_name="foo",
)
ax3.axis_label_text_color = red
p.add_layout(ax3, 'below')

wheel_zoom = WheelZoomTool()
p.add_tools(wheel_zoom)

p.toolbar.active_scroll = wheel_zoom

zoom_in_blue = ZoomInTool(renderers=[blue_circles], description="Zoom in blue circles")
zoom_out_blue = ZoomOutTool(renderers=[blue_circles], description="Zoom out blue circles")
p.add_tools(zoom_in_blue, zoom_out_blue)

zoom_in_red = ZoomInTool(renderers=[red_circles], description="Zoom in red circles")
zoom_out_red = ZoomOutTool(renderers=[red_circles], description="Zoom out red circles")
p.add_tools(zoom_in_red, zoom_out_red)

select = Select(title="Zoom together:", options=["none", "cross", "all"], value=wheel_zoom.zoom_together)
select.js_on_change("value", CustomJS(
    args=dict(select=select, wheel_zoom=wheel_zoom),
    code="""\
export default ({select, wheel_zoom}) => {
  wheel_zoom.zoom_together = select.value
}
""",
))
show(column(select, p))

固定位置轴#

默认情况下,Bokeh 将轴放置在绘图的两侧,但可以通过设置其 fixed_location 属性将轴定位在范围内的任何位置

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(-6, 6, 500)
y = 8*np.sin(x)*np.sinc(x)

p = figure(width=800, height=300, title="", tools="",
           toolbar_location=None, match_aspect=True)

p.line(x, y, color="navy", alpha=0.4, line_width=4)
p.background_fill_color = "#efefef"
p.xaxis.fixed_location = 0
p.yaxis.fixed_location = 0

show(p)