样式化绘图元素#

选择绘图对象#

如果你想自定义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 属性。

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

如果你将sizing_mode设置为不同于fixed的任何值,Bokeh会在绘图渲染时调整widthheight。然而,Bokeh使用widthheight来计算绘图的初始宽高比。

图表只会调整到最小100像素(高度或宽度),以防止显示图表时出现问题。

标题#

要为您的图表标题设置样式,请使用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)

边框#

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

  • 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)

样式化字形#

要为字形(glyph)的填充、线条或文本属性设置样式,首先需要确定你想要自定义的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)

已选择和未选择的字形#

要自定义选中和未选中字形(glyphs)的样式,可以设置selection_glyphnonselection_glyph属性,这些属性属于GlyphRenderer。你可以手动设置这些属性,或者通过将它们传递给add_glyph()来设置。

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

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)

renderer.selection_glyph = renderer.glyph.clone(fill_alpha=1, fill_color="firebrick", line_color=None)
renderer.nonselection_glyph = renderer.glyph.clone(fill_alpha=0.2, fill_color="blue", line_color="firebrick")

show(plot)

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

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_"前缀的颜色或透明度参数传递给渲染器函数。

或者,设置selection_glyphnonselection_glyph属性,就像在 Selected and unselected glyphs上面一样。

此示例使用第一种方法传递带有"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_glyph, hover_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绘图轴的各种视觉属性。

要在轴对象上设置样式属性,请使用xaxisyaxisaxis方法在Plot上首先获取绘图的轴对象。例如:

>>> 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属性设置为(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.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)

CustomJSTicker#

要完全自定义轴刻度的位置,请使用CustomJSTicker,并结合JavaScript代码片段作为其major_codeminor_code属性。

这些代码片段应返回刻度位置的列表:

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

xticker = CustomJSTicker(
    # always three equally spaced ticks
    major_code="""
        const {start, end} = cb_data.range
        const interval = (end-start) / 4
        return [start + interval, start + 2*interval, start + 3*interval]
    """,
    # minor ticks in between the major ticks
    minor_code="""
        const {start, end, major_ticks} = cb_data
        return [
            (start+major_ticks[0])/2,
            (major_ticks[0]+major_ticks[1])/2,
            (major_ticks[1]+major_ticks[2])/2,
            (major_ticks[2]+end)/2,
        ]
    """,
)

yticker = CustomJSTicker(major_code="return ['a', 'c', 'e', 'g']")

p = figure(y_range=list("abcdefg"))
p.scatter([1, 2, 3, 4, 5], ["a", "d", "b", "f", "c"], size=30)

p.xaxis.ticker = xticker

# keep the grid lines at all original tick locations
p.ygrid.ticker = p.yaxis.ticker
p.yaxis.ticker = yticker

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)

刻度标签格式#

要设置轴标签文本的样式,请使用轴的TickFormatter对象的formatter属性。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轴上设置的各种属性的完整列表,请参阅axes部分的参考指南

样式化网格#

在本节中,您将学习如何在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轴相交的网格对象(即水平方向的对象)。

线条#

要配置网格线的视觉外观,请使用一组line properties,并以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)

次要线路#

要配置次要网格线的视觉外观,请使用一组 line properties,前缀为 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)

乐队#

使用“bands”在相邻的网格线之间显示填充的、阴影的带。要控制这些带的视觉外观,请使用一组以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)

边界#

要设置明确的界限以限制网格的绘制位置,请使用一个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.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#
Type:

Int

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

label_width = 20#
Type:

Int

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

label_height = 20#
Type:

Int

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

glyph_width = 20#
Type:

Int

渲染的图例字形应占用的宽度(以像素为单位)。

glyph_height = 20#
Type:

Int

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

padding = 10#
Type:

Int

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

spacing = 3#
Type:

Int

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

margin = 10#
Type:

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:

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

annotation:

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

overlay:

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

在给定的层级内,渲染器按照它们被添加的顺序进行绘制。

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

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

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

您可以在章节 Color mapped images中查看带有输出的完整示例。