范围和轴#

设置范围#

默认情况下,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属性中配置具有“额外”命名范围的图表。然后,您可以在添加新的glyph方法时以及在添加新的轴对象时引用这些命名范围,使用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)