样式化绘图元素#

选择绘图对象#

如果您想自定义 Bokeh 绘图的任何元素的外观,您首先需要确定要修改哪个对象。如 介绍 中所述,Bokeh 绘图是表示绘图不同部分的 Python 对象的组合,例如它的网格、轴和图形。

某些对象具有方便的方法来帮助您识别要处理的对象。请参见 样式化轴样式化网格样式化图例 获取示例。

要查询任何 Bokeh 绘图对象,请使用 Plot 上的 select() 方法。例如,要查找绘图中的所有 PanTool 对象

>>> p.select(type=PanTool)
[<bokeh.models.tools.PanTool at 0x106608b90>]

您也可以使用 select() 方法查询其他属性

>>> p.circle(0, 0, radius=1, name="mycircle")
<bokeh.plotting.figure at 0x106608810>

>>> p.select(name="mycircle")
[<bokeh.models.renderers.GlyphRenderer at 0x106a4c810>]

当您想样式化 样式化图形 的视觉属性时,此查询方法尤其有用。

样式化绘图#

除了单个绘图元素之外,Plot 对象本身也具有一些可以自定义的视觉特征,例如绘图的尺寸、背景、边框或轮廓。本节介绍如何更改 Bokeh 绘图的这些属性。

示例代码主要使用 bokeh.plotting 接口来创建绘图。但是,无论 Bokeh 绘图是如何创建的,这些说明都适用。

尺寸#

要更改 Plot 的宽度和高度,请使用其 widthheight 属性。这两个属性使用 屏幕单位。它们控制整个画布区域的大小,包括任何轴或标题(但不包括工具栏)。

如果您正在使用 bokeh.plotting 接口,您可以将这些值直接传递给 figure()

from bokeh.plotting import figure, show

# create a new plot with specific dimensions
p = figure(width=700)
p.height = 300

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

show(p)

响应式尺寸#

要自动调整绘图的宽度或高度以相对于浏览器中的可用空间,请使用绘图的 sizing_mode 属性。

要控制绘图如何缩放以填充其容器,请参见 布局 的文档,特别是 LayoutDOMsizing_mode 属性。

如果您将 sizing_mode 设置为除 fixed 以外的任何值,Bokeh 会在渲染绘图后立即调整 widthheight。但是,Bokeh 使用 widthheight 来计算绘图的初始纵横比。

绘图只会缩小到最小 100px(高度或宽度),以防止在显示绘图时出现问题。

标题#

要样式化绘图的标题,请使用 Title 注释,它作为 Plot.title 属性可用。

您可以使用大多数标准 文本属性。但是,text_aligntext_baseline 不适用。要将标题相对于整个绘图定位,请使用属性 alignoffset 代替。

例如,要设置标题文本的颜色和字体样式,请使用 plot.title.text_color

from bokeh.plotting import figure, show

p = figure(width=400, height=400, title="Some Title")
p.title.text_color = "olive"
p.title.text_font = "times"
p.title.text_font_style = "italic"

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

show(p)

背景#

要更改背景填充样式,请调整 Plot 对象的 background_fill_colorbackground_fill_alpha 属性

from bokeh.plotting import figure, show

p = figure(width=400, height=400)
p.background_fill_color = "beige"
p.background_fill_alpha = 0.5

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

show(p)

边框#

要调整边框填充样式,请使用 Plot 对象的 border_fill_colorborder_fill_alpha 属性。您还可以使用以下属性设置每侧的最小边框(以 屏幕单位 为单位)

  • min_border_left

  • min_border_right

  • min_border_top

  • min_border_bottom

此外,如果您设置 min_border,Bokeh 会方便地将最小边框设置应用于所有边。min_border 的默认值为 40px。

from bokeh.plotting import figure, show

p = figure(width=400, height=400)
p.border_fill_color = "whitesmoke"
p.min_border_left = 80

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

show(p)

轮廓#

Bokeh Plot 对象具有各种 线属性。要更改轮廓的外观,请使用以 outline_ 为前缀的那些线属性。

例如,要设置轮廓的颜色,请使用 outline_line_color

from bokeh.plotting import figure, show

p = figure(width=400, height=400)
p.outline_line_width = 7
p.outline_line_alpha = 0.3
p.outline_line_color = "navy"

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

show(p)

样式化图形#

要样式化图形的填充、线或文本属性,您首先需要确定要自定义哪个 GlyphRenderer。如果您正在使用 bokeh.plotting 接口,图形函数将返回渲染器

>>> r = p.circle([1,2,3,4,5], [2,5,8,2,7], radius=1)
>>> r
<bokeh.models.renderers.GlyphRenderer at 0x106a4c810>

接下来,从 GlyphRenderer.glyph 属性获取图形本身

>>> r.glyph
<bokeh.models.glyphs.Circle at 0x10799ba10>

这是要为其设置填充、线或文本属性值的对象

from bokeh.plotting import figure, show

p = figure(width=400, height=400)
r = p.scatter([1,2,3,4,5], [2,5,8,2,7])

glyph = r.glyph
glyph.size = 60
glyph.fill_alpha = 0.2
glyph.line_color = "firebrick"
glyph.line_dash = [6, 3]
glyph.line_width = 2

show(p)

选中和未选中图形#

要自定义选中和未选中图形的样式,请设置 selection_glyphnonselection_glyph 属性GlyphRenderer。您可以手动设置它们,也可以将它们传递给 add_glyph()

下面的绘图使用 bokeh.plotting 接口来设置这些属性。单击或点击绘图上的任何圆圈,查看对选中和未选中图形的影响。要清除选择并恢复原始状态,请单击或点击绘图中圆圈之外的任何位置。

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

plot = figure(width=400, height=400, tools="tap", title="Select a circle")
renderer = plot.scatter([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=50)

selected_scatter = Scatter(fill_alpha=1, fill_color="firebrick", line_color=None)
nonselected_scatter = Scatter(fill_alpha=0.2, fill_color="blue", line_color="firebrick")

renderer.selection_glyph = selected_scatter
renderer.nonselection_glyph = nonselected_scatter

show(plot)

如果您只需要设置选中或未选中图形的颜色或alpha参数,请为图形函数提供以 "selection_""nonselection_" 为前缀的颜色和alpha参数

from bokeh.plotting import figure, show

plot = figure(width=400, height=400, tools="tap", title="Select a circle")
renderer = plot.scatter(
    x=[1, 2, 3, 4, 5],
    y=[2, 5, 8, 2, 7],
    size=50,

    # set visual properties for selected glyphs
    selection_color="firebrick",

    # set visual properties for non-selected glyphs
    nonselection_fill_alpha=0.2,
    nonselection_fill_color="blue",
    nonselection_line_color="firebrick",
    nonselection_line_alpha=1.0,
)

show(plot)

如果您使用 bokeh.models 接口,请使用 add_glyph() 函数

p = Plot()
source = ColumnDataSource(dict(x=[1, 2, 3], y=[1, 2, 3]))

initial_circle = Circle(x='x', y='y', fill_color='blue', radius=1)
selected_circle = Circle(fill_alpha=1, fill_color="firebrick", line_color=None)
nonselected_circle = Circle(fill_alpha=0.2, fill_color="blue", line_color="firebrick")

p.add_glyph(source,
            initial_circle,
            selection_glyph=selected_circle,
            nonselection_glyph=nonselected_circle)

悬停检查#

要样式化悬停图形的外观,请将以 "hover_" 为前缀的颜色或alpha参数传递给您的渲染器函数。

或者,设置 selection_glyphnonselection_glyph 属性GlyphRenderer,就像上面 选中和未选中图形 中一样。

此示例使用第一种方法,即使用 "hover_" 前缀传递颜色参数

from bokeh.models import RELATIVE_DATETIME_CONTEXT, HoverTool
from bokeh.plotting import figure, show
from bokeh.sampledata.glucose import data

x = data.loc['2010-10-06'].index.to_series()
y = data.loc['2010-10-06']['glucose']

# Basic plot setup
p = figure(width=800, height=400, x_axis_type="datetime",
           tools="pan,wheel_zoom", title='Hover over points')
p.xaxis.formatter.context = RELATIVE_DATETIME_CONTEXT()
p.ygrid.grid_line_color = None
p.background_fill_color = "#fafafa"

p.line(x, y, line_dash="4 4", line_width=1, color='gray')

cr = p.scatter(
    x, y, size=20,
    fill_color="steelblue", alpha=0.1, line_color=None,
    hover_fill_color="midnightblue", hover_alpha=0.5,
    hover_line_color="white",
)

p.add_tools(HoverTool(tooltips=None, renderers=[cr], mode='hline'))

show(p)

覆盖非视觉属性#

字形允许覆盖任何数据驱动的属性,而不仅仅是视觉属性。这样,用户就可以例如在悬停时更改散点图中标记的大小,甚至可以将字形从其原始位置偏移。事实上,用户可以用一个完全无关的字形覆盖主字形(GlyphRenderer.glyph)(例如,用 Rect 替换 Circle)。

注意

只有主字形用于命中测试和其他功能。辅助字形(selection_glyphhover_glyph 等)用于绘画,只影响字形的视觉效果。

此示例显示了如何覆盖 Circle 字形的非视觉属性(radius 在悬停时)以及如何在选择时使用不同的字形

import numpy as np

from bokeh.core.properties import field
from bokeh.io import show
from bokeh.models import BoxAnnotation, Indexed, Rect, Tooltip
from bokeh.palettes import Spectral11
from bokeh.plotting import figure

N = 50

x = np.random.random(size=N)*100
y = np.random.random(size=N)*100
radii = np.random.uniform(1, 5, size=N)
radii_big = radii*2
colors = np.random.choice(Spectral11, size=N)

p = figure(tools=["hover", "box_select"], active_drag="box_select")

cr = p.circle(
    x, y, radius=radii,
    fill_color=colors, fill_alpha=0.8, line_color=None,
    hover_fill_alpha=0.5, # mix `hover_` attributes with manual setup below
)

# there is no `hover_radius` so we have set things manually
cr.data_source.data["radii_big"] = radii_big
cr.hover_glyph.radius = field("radii_big")

# make selection glyph unrelated while reusing existing data
cr.selection_glyph = Rect(
    line_color=None,
    fill_color=field("fill_color"),
    width=field("radii_big"),
    height=field("radius"),
)

p.hover.tooltips = None

tooltip = Tooltip(position=Indexed(renderer=cr, index=0), content="Hover over me!", visible=True)
p.elements.append(tooltip)

box = BoxAnnotation(left=40, right=80, top=80, bottom=40)
tooltip = Tooltip(position=box.nodes.top_center, content="Select me!", visible=True, attachment="above")
box.elements.append(tooltip)
p.renderers.append(box)

show(p)

样式化轴线#

本节重点介绍更改 Bokeh 图表轴线的各种视觉属性。

要在 Axis 对象上设置样式属性,请使用 xaxisyaxisaxis 方法,这些方法在 Plot 上首先获得图表的 Axis 对象。例如

>>> p.xaxis
[<bokeh.models.axes.LinearAxis at 0x106fa2390>]

由于可能存在多个轴线,因此此方法返回 Axis 对象列表。然而,为了方便起见,这些列表是可扩展的。这意味着您可以直接在此结果上设置属性,这些属性将应用于列表中的所有轴线。例如

p.xaxis.axis_label = "Temperature"

这会更改 p 的每个 x 轴的 axis_label 值,无论有多少个轴。

以下示例更详细地展示了 xaxisyaxisaxis 方法的使用情况

from bokeh.plotting import figure, show

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

# change just some things about the x-axis
p.xaxis.axis_label = "Temp"
p.xaxis.axis_line_width = 3
p.xaxis.axis_line_color = "red"

# change just some things about the y-axis
p.yaxis.axis_label = "Pressure"
p.yaxis.major_label_text_color = "orange"
p.yaxis.major_label_orientation = "vertical"

# change things on all axes
p.axis.minor_tick_in = -3
p.axis.minor_tick_out = 6

show(p)

标签#

要添加或更改轴线整体标签的文本,请使用 axis_label 属性。要在轴线标签中的文本中添加换行符,请在字符串中包含 \n

要控制标签文本的视觉外观,请使用任何带 axis_label_ 前缀的标准 文本属性。例如,要设置标签的文本颜色,请设置 axis_label_text_color

要更改轴线标签和主刻度标签之间的距离,请设置 axis_label_standoff 属性。

例如

from bokeh.plotting import figure, show

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

p.xaxis.axis_label = "Lot Number"
p.xaxis.axis_label_text_color = "#aa6666"
p.xaxis.axis_label_standoff = 30

p.yaxis.axis_label = "Bin Count"
p.yaxis.axis_label_text_font_style = "italic"

show(p)

边界#

要限制绘制轴线的边界,请将轴线对象的 bounds 属性设置为 2 元组的 (start, end)

from bokeh.plotting import figure, show

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

p.xaxis.bounds = (2, 4)

show(p)

刻度位置#

Bokeh 使用几个“刻度器”模型来决定在轴线(分类、日期时间、墨卡托、线性或对数刻度)上显示刻度的位置。要配置刻度的位置,请使用轴线的 .ticker 属性。

如果您使用 bokeh.plotting 接口,Bokeh 会自动选择合适的刻度器位置模型。

如果您需要控制要使用的刻度器位置模型,您也可以显式地定义刻度位置列表。将带有刻度位置列表的 FixedTicker 分配给轴线

from bokeh.plotting import figure
from bokeh.models.tickers import FixedTicker

p = figure()

# no additional tick locations will be displayed on the x-axis
p.xaxis.ticker = FixedTicker(ticks=[10, 20, 37.4])

作为快捷方式,您也可以直接将刻度列表提供给轴线的 ticker 属性

from bokeh.plotting import figure, show

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

p.xaxis.ticker = [2, 3.5, 4]

show(p)

刻度线#

要控制主刻度和次刻度的视觉外观,请设置相应的 线属性,分别带 major_tick_minor_tick_ 前缀。

例如,要设置主刻度的颜色,请使用 major_tick_line_color。要隐藏任一组刻度,请将颜色设置为 None

此外,要控制刻度在绘图区域内和外扩展的距离,请使用属性 major_tick_in/major_tick_outminor_tick_in/minor_tick_out。这些值以 屏幕单位 为单位。因此,您可以使用负值。

from bokeh.plotting import figure, show

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

p.xaxis.major_tick_line_color = "firebrick"
p.xaxis.major_tick_line_width = 3
p.xaxis.minor_tick_line_color = "orange"

p.yaxis.minor_tick_line_color = None

p.axis.major_tick_out = 10
p.axis.minor_tick_in = -3
p.axis.minor_tick_out = 8

show(p)

刻度标签格式#

要设置轴线标签文本的样式,请使用轴线 formatter 属性的 TickFormatter 对象。Bokeh 在不同的情况下默认使用许多刻度格式器

这些默认刻度格式器不会公开许多可配置属性。要以更细粒度的级别控制刻度格式,请使用以下描述的 NumeralTickFormatterPrintfTickFormatter 之一。

注意

要替换轴线上的刻度格式器,您必须设置实际 Axis 对象的 formatter 属性,而不是可扩展列表的属性。这就是以下示例使用 p.yaxis[0].formatter 等(带下标 [0])的原因。

NumeralTickFormatter#

NumeralTickFormatter 具有一个 format 属性,可用于控制轴线刻度的文本格式。

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

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

p.xaxis[0].formatter = NumeralTickFormatter(format="0.0%")
p.yaxis[0].formatter = NumeralTickFormatter(format="$0.00")

show(p)

还有许多其他格式可用。请参阅 NumeralTickFormatter 的完整文档,该文档位于 参考指南 中。

PrintfTickFormatter#

PrintfTickFormatter 具有一个 format 属性,可用于使用 printf 样式格式字符串控制轴线刻度的文本格式。

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

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

p.xaxis[0].formatter = PrintfTickFormatter(format="%4.1e")
p.yaxis[0].formatter = PrintfTickFormatter(format="%5.3f mu")

show(p)

有关格式的完整详细信息,请参阅 PrintfTickFormatter 的完整文档,该文档位于 参考指南 中。

CustomJSTickFormatter#

要完全自定义轴线刻度的格式,请将 CustomJSTickFormatter 与 JavaScript 代码段结合使用,作为其 code 属性。

变量 tick 包含未格式化的刻度值。它在渲染时在代码段或函数命名空间中可用

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

p = figure(width=500, height=500)
p.scatter([0, 2, 4, 6, 8, 10], [6, 2, 4, 10, 8, 0], size=30)

p.yaxis.formatter = CustomJSTickFormatter(code="""
    return Math.floor(tick) + " + " + (tick % 1).toFixed(2)
""")

show(p)

日期时间刻度上下文#

日期时间刻度格式器具有其他属性,用于在日期时间轴上的刻度中添加更多上下文。例如,上下文格式可能会在第一个刻度上显示年、月和日,而常规刻度会显示小时和分钟。

这在轴线可缩放的情况下特别有用。例如:当放大到秒级别时,刻度格式器上下文可以提供有关更宽时间单位(如天或月)的附加信息。

上下文选项为

context

用于在由 context_which 指定的刻度或刻度中添加上下文的格式。值是

context_which

要为其添加格式化上下文字符串的刻度或刻度。值是:"start""end""center""all"

context_location

相对于刻度标签文本基线,上下文应在何处呈现。值包括:"below""above""left""right"

有一个预定义的 RELATIVE_DATETIME_CONTEXT,它添加了上下文的级别,比当前级别高一级。下面的示例演示了这些选项。

from bokeh.models import RELATIVE_DATETIME_CONTEXT
from bokeh.plotting import figure, show
from bokeh.sampledata.glucose import data

x = data.loc['2010-10-06'].index.to_series()
y = data.loc['2010-10-06']['glucose']

p = figure(sizing_mode="stretch_width", x_axis_type="datetime",
           tools="xwheel_zoom")
p.xaxis.formatter.context = RELATIVE_DATETIME_CONTEXT()

p.line(x, y, line_dash="4 4", line_width=3, color='gray')

show(p)

可以将多个 DatetimeTickFormatter 实例“链接”在一起,以实现任意数量的上下文级别。例如

p.xaxis.formatter.context = DatetimeTickFormatter(...)
p.xaxis.formatter.context.context = DatetimeTickFormatter(...)

刻度标签方向#

要控制主要刻度标签的方向,请使用 major_label_orientation 属性。此属性接受值 "horizontal""vertical" 或一个浮点数,该浮点数给出从水平方向旋转的角度(以弧度为单位)。

from math import pi

from bokeh.plotting import figure, show

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

p.xaxis.major_label_orientation = pi/4
p.yaxis.major_label_orientation = "vertical"

show(p)

注意

您可以使用更多属性来配置 Bokeh 轴。有关可以在不同类型的 Bokeh 轴上设置的各种属性的完整列表,请参阅 部分的 参考指南

样式网格#

在本节中,您将学习如何设置 Bokeh 图表中网格线和网格带的视觉属性。

要获取图表的网格对象,请使用 xgridygridgrid 方法,这些方法位于 Plot 上。这与轴的便捷方法的工作原理类似。

>>> p.grid
[<bokeh.models.grids.Grid at 0x106fa2278>,
 <bokeh.models.grids.Grid at 0x106fa22e8>]

这些方法也返回可展开列表。您可以像对单个对象一样在列表上设置属性,并且该属性将针对列表的每个元素更改。

p.grid.line_dash = [4 2]

注意

xgrid 属性提供与 x 轴相交的网格对象(意味着垂直方向的对象)。相应地,ygrid 提供与 y 轴相交的网格对象(意味着水平方向的对象)。

线条#

要配置网格线的视觉外观,请使用 线条属性 的集合,并在其前加上 grid_

例如,要设置网格线的颜色,请使用 grid_line_color。要隐藏网格线,请将它们的线条颜色设置为 None

from bokeh.plotting import figure, show

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

# change just some things about the x-grid
p.xgrid.grid_line_color = None

# change just some things about the y-grid
p.ygrid.grid_line_alpha = 0.5
p.ygrid.grid_line_dash = [6, 4]

show(p)

次要线条#

要配置次要网格线的视觉外观,请使用 线条属性 的集合,并在其前加上 minor_grid_

例如,要设置网格线的颜色,请使用 minor_grid_line_color。默认情况下,次要网格线处于隐藏状态(这意味着它们的线条颜色设置为 None)。

from bokeh.plotting import figure, show

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

# change just some things about the y-grid
p.ygrid.minor_grid_line_color = 'navy'
p.ygrid.minor_grid_line_alpha = 0.1

show(p)

带状区域#

使用“带状区域”来显示相邻网格线之间的填充阴影带。要控制这些带状区域的视觉外观,请使用 填充属性网格属性 的集合,并在其前加上 band_

例如,要设置网格带状区域的颜色,请使用 band_fill_color。要隐藏网格带状区域,请将它们的填充颜色设置为 None(这是默认值)。

此示例定义了填充有纯色的带状区域。

from bokeh.plotting import figure, show

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

# change just some things about the x-grid
p.xgrid.grid_line_color = None

# change just some things about the y-grid
p.ygrid.band_fill_alpha = 0.1
p.ygrid.band_fill_color = "navy"

show(p)

此示例使用填充有网格图案的带状区域。

from bokeh.plotting import figure, show

p = figure(height=250, width=600, x_range=(0, 10), tools="", toolbar_location=None)
p.line(x=[0,1,2,3,4,5,6,7,8,9,10],
       y=[1,3,4,3,1,2,6,5,2,3,4])

p.ygrid.grid_line_color = None

ticks = [0, 2, 4, 6, 8, 10]
p.xaxis[0].ticker = ticks
p.xgrid[0].ticker = ticks

p.xgrid.band_hatch_pattern = "/"
p.xgrid.band_hatch_alpha = 0.6
p.xgrid.band_hatch_color = "lightgrey"
p.xgrid.band_hatch_weight = 0.5
p.xgrid.band_hatch_scale = 10

show(p)

边界#

要设置限制网格绘制位置的显式边界,请使用 (start, end) 的 2 元组。这与设置 轴的边界 相同。

from bokeh.plotting import figure, show

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

p.grid.bounds = (2, 4)

show(p)

注意

Bokeh 网格支持配置其他属性。有关可以在 Bokeh 图表网格上设置的各种属性的完整列表,请参阅 网格 部分的 参考指南

样式图例#

与轴和网格的便捷方法类似,Plot 上有一个 legend() 方法,您可以使用它来获取图表的 Legend 对象。

bokeh.models.plots.Plot.legend

>>> p.legend
[<bokeh.models.annotations.Legend at 0x106fa2278>]

此方法也返回可展开列表。因此,您可以像对单个对象一样在列表上设置属性,并且该属性将针对列表的每个元素更改。

p.legend.label_text_font = "times"

位置#

要控制图例标签的位置,请使用 location 属性。

在绘图区域内#

对于中央布局区域中的图例,例如由 bokeh.plotting 自动创建的图例,请将 location 设置为以下值之一:

"top_left"

"top_center"

"top_right"(默认值)

"center_right"

"bottom_right"

"bottom_center"

"bottom_left"

"center_left"

"center"

或一个 (x, y) 元组,指示屏幕坐标中的绝对位置(从左下角开始的像素)。

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

p.legend.location = "bottom_left"

show(p)

在绘图区域外#

要将图例放置在中央区域之外,请使用图表的 add_layout 方法。这需要直接创建 Legend 对象。

import numpy as np

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

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure(toolbar_location="above")

r0 = p.scatter(x, y)
r1 = p.line(x, y)

r2 = p.line(x, 2*y, line_dash=[4, 4], line_color="orange", line_width=2)

r3 = p.scatter(x, 3*y, marker="square", fill_color=None, line_color="green")
r4 = p.line(x, 3*y, line_color="green")

legend = Legend(items=[
    ("sin(x)"   , [r0, r1]),
    ("2*sin(x)" , [r2]),
    ("3*sin(x)" , [r3, r4]),
], location="center")

p.add_layout(legend, 'right')

show(p)

在这种情况下,您需要以绝对方式指定图例的位置。未来的版本将添加其他选项以自定义图例位置。

标题#

要添加或更改图例的标题,请使用其 title 属性。

plot.legend.title = "Division"

要控制图例标题的视觉外观,请使用任何标准的 文本属性,并在其前加上 title_。例如,要设置图例的字体样式,请使用 title_text_font_style

要设置标题与图例其余部分之间的距离(以像素为单位),请使用 title_standoff 属性。

import pandas as pd

from bokeh.palettes import Spectral4
from bokeh.plotting import figure, show
from bokeh.sampledata.stocks import AAPL, GOOG, IBM, MSFT

p = figure(width=800, height=250, x_axis_type="datetime")

for data, name, color in zip([AAPL, IBM, MSFT, GOOG], ["AAPL", "IBM", "MSFT", "GOOG"], Spectral4):
    df = pd.DataFrame(data)
    df['date'] = pd.to_datetime(df['date'])
    p.line(df['date'], df['close'], line_width=2, color=color, legend_label=name)

p.legend.location = "top_left"
p.legend.title = 'Stock'
p.legend.title_text_font_style = "bold"
p.legend.title_text_font_size = "20px"

show(p)

方向#

要控制图例的方向,请使用 orientation 属性。此属性的有效值为:

  • "vertical"

  • "horizontal"

默认方向为 "vertical"

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

p.legend.orientation = "horizontal"

show(p)

二维布局#

可以通过将正整数设置为属性 nrowsncols 来激活图例的二维布局。这提供了避免截断图例的机会。

nrowsncols 的默认值为 "auto",如果 orientation 属性为 "vertical",则导致一列,如果 orientation 属性为 "horizontal",则导致一行。

import numpy as np

from bokeh.layouts import column
from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
sinx = np.sin(x)

p1 = figure(title='Default legend layout', width=500, height=300)
[p1.line(x, (1 + i/20)*sinx, legend_label=f"{1+i/20:.2f}*sin(x)") for i in range(7)]

p2 = figure(title='Legend layout with 2 columns', width=500, height=300)
[p2.line(x, (1 + i/20)*sinx, legend_label=f"{1+i/20:.2f}*sin(x)") for i in range(7)]
p2.legend.ncols=2

p3 = figure(title='Legend layout with 3 rows', width=500, height=300)
[p3.line(x, (1 + i/20)*sinx, legend_label=f"{1+i/20:.2f}*sin(x)") for i in range(7)]
p3.legend.nrows=3

show(column(p1, p2, p3))

标签文本#

要控制图例标签的视觉外观,请使用任何标准的 文本属性,并在其前加上 label_。例如,要设置标签的字体样式,请使用 label_text_font_style

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

p.legend.label_text_font = "times"
p.legend.label_text_font_style = "italic"
p.legend.label_text_color = "navy"

show(p)

边框#

要控制图例边框的视觉外观,请使用 线条属性 的集合,并在其前加上 border_。例如,要设置边框的颜色,请使用 border_line_color。要使边框不可见,请将边框线条颜色设置为 None

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

p.legend.border_line_width = 3
p.legend.border_line_color = "navy"
p.legend.border_line_alpha = 0.5

show(p)

背景#

要控制图例背景的视觉外观,请使用 填充属性 的集合,并在其前加上 background_。例如,要设置背景的颜色,请使用 background_fill_color。要使背景透明,请将 background_fill_alpha 设置为 0

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

#  3*sin(x) curve should be under this legend at initial viewing, so
# we can see that the legend is transparent
p.legend.location = "bottom_right"
p.legend.background_fill_color = "navy"
p.legend.background_fill_alpha = 0.5

show(p)

尺寸#

要控制布局或标签组件间距等尺寸,请使用以下属性。

有几个属性可以用于控制图例组件的布局、间距等。

label_standoff = 5#
类型:

Int

标签与其关联的图形之间的距离(以像素为单位)。

label_width = 20#
类型:

Int

图例标签区域的最小宽度(以像素为单位)。

label_height = 20#
类型:

Int

图例标签区域的最小高度(以像素为单位)。

glyph_width = 20#
类型:

Int

渲染后的图例符号所占用的宽度(以像素为单位)。

glyph_height = 20#
类型:

Int

渲染后的图例符号所占用的高度(以像素为单位)。

padding = 10#
类型:

Int

图例内容周围的填充量。仅在边框可见时适用,否则会折叠为 0。

spacing = 3#
类型:

Int

图例条目之间的间距(以像素为单位)。

margin = 10#
类型:

Int

图例周围的边距。

import numpy as np

from bokeh.plotting import figure, show

x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)

p = figure()

p.scatter(x, y, legend_label="sin(x)")
p.line(x, y, legend_label="sin(x)")

p.line(x, 2*y, legend_label="2*sin(x)",
       line_dash=[4, 4], line_color="orange", line_width=2)

p.scatter(x, 3*y, marker="square", legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")

p.legend.label_standoff = 5
p.legend.glyph_width = 50
p.legend.spacing = 10
p.legend.padding = 50
p.legend.margin = 50

show(p)

设置渲染级别#

要指定绘制事物的顺序,请使用以下渲染级别之一

image:

“最低”渲染级别,在其他任何内容之前绘制

underlay:

网格的默认渲染级别

glyph:

所有图形的默认渲染级别(这意味着它们绘制在网格之上)

annotation:

注释渲染器的默认渲染级别

overlay:

“最高”渲染级别,用于工具覆盖

在给定级别内,渲染器按添加的顺序绘制。

要显式指定渲染级别,请在渲染器上使用 level 参数。

例如,要确保图像渲染在网格线之下,请在调用 image 渲染器时将渲染级别 "image" 分配给 level 参数

p.image(..., level="image")

您可以在颜色映射图像部分中看到带有输出的完整示例。