样式化绘图元素#
选择绘图对象#
如果你想自定义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的宽度和高度,请使用其width和
height属性。这两个属性使用屏幕单位。它们
控制整个画布区域的大小,包括任何轴或标题(但不包括工具栏)。
如果您使用的是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的文档,特别是LayoutDOM的sizing_mode属性。
如果你将sizing_mode设置为不同于fixed的任何值,Bokeh会在绘图渲染时调整width和height。然而,Bokeh使用width和height来计算绘图的初始宽高比。
图表只会调整到最小100像素(高度或宽度),以防止显示图表时出现问题。
标题#
要为您的图表标题设置样式,请使用Title注释,它作为Plot的.title属性可用。
你可以使用大多数标准的文本属性。然而,text_align 和
text_baseline 不适用。要将标题相对于整个图表进行定位,请使用属性 align 和
offset 来代替。
例如,要设置标题文本的颜色和字体样式,请使用
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_color和background_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_color 和
border_fill_alpha 属性,这些属性属于 Plot 对象。您还可以使用以下属性设置每侧的最小边框(以 屏幕单位 为单位):
min_border_leftmin_border_rightmin_border_topmin_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_glyph和nonselection_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_glyph和nonselection_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绘图轴的各种视觉属性。
要在轴对象上设置样式属性,请使用xaxis、yaxis和axis方法在Plot上首先获取绘图的轴对象。例如:
>>> p.xaxis
[<bokeh.models.axes.LinearAxis at 0x106fa2390>]
因为可能有多于一个轴,这个方法返回一个Axis对象的列表。然而,为了方便起见,这些列表是可展开的。这意味着你可以直接在结果上设置属性,这些属性将被应用到列表中的所有轴。例如:
p.xaxis.axis_label = "Temperature"
这会改变p的每个x轴的axis_label的值,无论有多少个。
下面的示例更详细地展示了xaxis、yaxis和axis方法的使用:
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_code和minor_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_out 和 minor_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在不同情况下默认使用多种刻度格式化器:
BasicTickFormatter— 线性轴的默认格式化器。CategoricalTickFormatter— 分类轴的默认格式化器。DatetimeTickFormatter— 日期时间轴的默认格式化器。LogTickFormatter— 对数轴的默认格式化器。
这些默认的刻度格式化器没有暴露许多可配置的属性。
要在更细粒度的级别上控制刻度格式化,请使用下面描述的
NumeralTickFormatter 或 PrintfTickFormatter 之一。
注意
要替换轴上的刻度格式化器,您必须在实际的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指定的刻度或刻度添加上下文的格式。值为:无,未添加上下文
一个标准的
DatetimeTickFormatter格式字符串,这个单一的格式在所有尺度上使用另一个
DatetimeTickFormatter实例,用于添加与比例相关的上下文
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图表上设置网格线和网格带的视觉属性。
要获取图表的网格对象,请使用xgrid、ygrid和grid方法在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)
样式化图例#
类似于轴和网格的便捷方法,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)
二维布局#
可以通过将正整数设置为属性nrows或ncols来激活图例的二维布局。这提供了避免图例被截断的机会。
nrows 和 ncols 的默认值是 "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)
维度#
要控制标签组件的布局或间距等尺寸,请使用以下属性:
有几种属性可以用来控制图例组件的布局、间距等:
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中查看带有输出的完整示例。