注释#
Bokeh 包含几种不同类型的 annotations,你可以使用它们来为你的可视化添加补充信息。
标题#
使用Title
注释来添加描述性文本,这些文本会在图表的边缘呈现。
如果您使用bokeh.plotting 接口,添加基本标题的最快方法是将文本作为title
参数传递给figure()
:
from bokeh.plotting import figure, show
p = figure(title="Basic Title", width=300, height=300)
p.scatter([1, 2], [3, 4])
show(p)
默认标题通常位于图的上方,左对齐。
标题文本可能包含换行符,这将导致标题多行显示。
p = figure(title="A longer title\nwith a second line underneath")
要定义标题相对于图表的位置,请使用
title_location
参数。标题可以位于图表的上面、下面、左边或
右边。例如:
from bokeh.plotting import figure, show
p = figure(title="Left Title", title_location="left",
width=300, height=300)
p.scatter([1, 2], [3, 4])
show(p)
使用你的图表的.title
属性来自定义默认的Title
。使用标准的文本属性来定义视觉属性,如字体、边框和背景。
此示例使用 .title
属性来设置字体和背景属性,以及标题文本和标题对齐方式:
from bokeh.plotting import figure, show
p = figure(width=300, height=300)
p.scatter([1, 2], [3, 4])
# configure visual properties on a plot's title attribute
p.title.text = "Title With Options"
p.title.align = "right"
p.title.text_color = "orange"
p.title.text_font_size = "25px"
p.title.background_fill_color = "#aaaaee"
show(p)
请注意,align
属性是相对于文本方向的。例如:如果您将标题放置在图的左侧,将 align
属性设置为 "left"
意味着您的文本将在左下角呈现。
要向文档中添加更多标题,您需要创建额外的Title
对象。使用绘图的add_layout()
方法将这些额外的Title
对象包含在您的文档中:
from bokeh.models import Title
from bokeh.plotting import figure, show
p = figure(title="Left Title", title_location="left",
width=300, height=300)
p.scatter([1, 2], [3, 4])
# add extra titles with add_layout(...)
p.add_layout(Title(text="Bottom Centered Title", align="center"), "below")
show(p)
如果标题和工具栏放置在图的同一侧,它们将占据相同的空间:
from bokeh.plotting import figure, show
p = figure(title="Top Title with Toolbar", toolbar_location="above",
width=600, height=300)
p.scatter([1, 2], [3, 4])
show(p)
如果绘图尺寸足够大,这可能会导致绘图更加紧凑。 然而,如果绘图尺寸不够大,标题和工具栏可能会在视觉上重叠。
图例#
为您的图表添加图例的最简单方法是在调用glyph方法时包含任何legend_label、legend_group或legend_field属性。Bokeh随后会自动为您创建一个Legend
对象。
为了更高级地控制图例,可以直接访问Legend
对象
directly。
基本图例标签#
为了为字形提供一个简单的显式标签,请传递legend_label
关键字参数:
p.circle('x', 'y', legend_label="some label")
如果你将相同的标签名称分配给多个字形,所有字形将被合并成一个具有该标签的图例项。
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, size=3, marker="square", legend_label="sin(x)", line_color="green")
p.line(x, y, legend_label="sin(x)", line_color="green")
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, legend_label="3*sin(x)", size=7, fill_color=None)
p.line(x, 3*y, legend_label="3*sin(x)")
show(p)
自动分组(Python端)#
如果你的数据是以ColumnDataSource的形式存在,Bokeh可以从ColumnDataSource的某一列中的字符串生成图例条目。这样,你可以基于一组字形创建图例条目。
要使用来自ColumnDataSource列的数据生成图例,请将列名作为legend_group
关键字参数传递给glyph方法:
p.circle('x', 'y', legend_group="colname", source=source)
因为 legend_group
引用了 ColumnDataSource 的一列,所以你也需要始终为 glyph 方法提供 source
参数。此外,包含标签名称的列必须在该数据源中存在:
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
orange, blue = '#ef8a62', '#67a9cf'
source = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=[orange, blue, orange, blue, orange, blue],
label=['hi', 'lo', 'hi', 'lo', 'hi', 'lo'],
))
p = figure(x_range=(0, 7), y_range=(0, 3), height=300, tools='save')
# legend field matches the column in the source
p.circle('x', 'y', radius=0.5, color='color',
legend_group='label', source=source)
show(p)
使用 legend_group
意味着 Bokeh 会立即对图例条目进行分组。
因此,任何后续的 Python 代码都可以在 Legend.items
属性中看到各个图例
条目。这样,您可以随时重新排列或修改
图例。
自动分组(浏览器端)#
您还可以选择仅在浏览器中的JavaScript 端对图例中的元素进行分组。如果您想要对仅在 JavaScript 端计算的列进行分组,使用浏览器端分组是有意义的。
p.circle('x', 'y', legend_field="colname", source=source)
在这种情况下,Python代码不会看到Legend.items
中的多个项目。
相反,只有一个代表分组的项目,并且分组是在浏览器中进行的。
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show
orange, blue = '#ef8a62', '#67a9cf'
source = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=[orange, blue, orange, blue, orange, blue],
label=['hi', 'lo', 'hi', 'lo', 'hi', 'lo'],
))
p = figure(x_range=(0, 7), y_range=(0, 3), height=300, tools='save')
# legend field matches the column in the source
p.circle('x', 'y', radius=0.5, color='color',
legend_field='label', source=source)
show(p)
隐藏图例项#
要手动控制单个图例项的可见性,请将visible
属性设置为True
或False
。
import numpy as np
from bokeh.plotting import figure, show
x = np.linspace(0, 4*np.pi, 100)
y = np.cos(x)
p = figure(height=300)
# create two renderers with legend labels
p.scatter(x, y, legend_label="cox(x)")
p.line(x, 2*y, legend_label="2*cos(x)",
line_dash=[4, 4], line_color="orange", line_width=2)
# set legend label visibility for second renderer to False
p.legend.items[1].visible = False
show(p)
注意
如果图例中的所有项目都不可见,整个图例将被隐藏。
此外,如果您使用
浏览器端的自动分组
并将legend_field
项目的可见性设置为False
,整个
组将不可见。
二维图例#
要获取具有多列或多行的图例,可以设置nrows
或ncols
属性为Legend
的正整数。如果一行中没有足够的空间来放置所有图例项,并且可以避免图例被截断,这将非常有用。行和列的定义取决于图例的orientation
。
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))
手动图例#
要手动构建图例,不要使用任何legend
参数,而是直接为Legend
对象的各个属性赋值。
要查看创建上述图形的源代码,请访问完整的 legend example 单页。
显式索引#
要明确指定在ColumnDataSource中使用哪个索引来显示图例,请设置index
属性的LegendItem
。
这对于在使用由多个部分渲染的图形符号(如
MultiLine
(multi_line()
) 或
Patches
patches()
)时,显示图例中的多个条目非常有用。
from bokeh.models import Legend, LegendItem
from bokeh.plotting import figure, show
p = figure()
r = p.multi_line([[1,2,3], [1,2,3]], [[1,3,2], [3,4,3]],
color=["orange", "red"], line_width=4)
legend = Legend(items=[
LegendItem(label="orange", renderers=[r], index=0),
LegendItem(label="red", renderers=[r], index=1),
])
p.add_layout(legend)
show(p)
交互式图例#
您可以使用图例作为交互元素来控制图表外观的某些方面。点击或轻触交互式图例条目可以控制与该图例条目相关的符号的可见性。
请参阅用户指南中的交互式图例以获取更多信息和示例。
颜色条#
要创建一个ColorBar
,你可以传递一个包含颜色调色板的ColorMapper
实例,例如:
color_bar = ColorBar(color_mapper=color_mapper, padding=5)
然而,对于许多字形,如果字形已经配置了颜色映射,你可以在字形方法返回的渲染器上调用construct_color_bar
来自动创建颜色条:
color_bar = r.construct_color_bar(padding=5)
颜色条可以位于图表的内部、左侧、右侧、下方或上方。在使用add_layout()
方法将ColorBar
对象添加到图表时,指定颜色条的位置。
import numpy as np
from bokeh.models import LogColorMapper
from bokeh.plotting import figure, show
def normal2d(X, Y, sigx=1.0, sigy=1.0, mux=0.0, muy=0.0):
z = (X-mux)**2 / sigx**2 + (Y-muy)**2 / sigy**2
return np.exp(-z/2) / (2 * np.pi * sigx * sigy)
X, Y = np.mgrid[-3:3:200j, -2:2:200j]
Z = normal2d(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*normal2d(X, Y, 1.0, 1.0)
image = Z * 1e6
color_mapper = LogColorMapper(palette="Viridis256", low=1, high=1e7)
plot = figure(x_range=(0,1), y_range=(0,1), toolbar_location=None)
r = plot.image(image=[image], color_mapper=color_mapper,
dh=1.0, dw=1.0, x=0, y=0)
color_bar = r.construct_color_bar(padding=1)
plot.add_layout(color_bar, "right")
show(plot)
比例尺#
ScaleBar
是一个视觉指示器,用于衡量图上特征的大小。这在处理地图或像CT或MRI扫描这样的图像时特别有用,尤其是在使用坐标轴不合适或过于繁琐的情况下。
要创建一个ScaleBar
,用户至少需要提供一个Range
,无论是显式的还是隐式的。
from bokeh.models import Range1d, ScaleBar
scale_bar = ScaleBar(range=Range1d(start=0, end=1000))
plot.add_layout(scale_bar)
范围也可以与图表共享:
from bokeh.models import Range1d, ScaleBar
scale_bar = ScaleBar(range=plot.y_range)
plot.add_layout(scale_bar)
ScaleBar
的默认范围是 "auto"
,它使用与比例条关联的图表的默认 x 或 y 范围,具体取决于比例条的方向("horizontal"
方向使用 Plot.x_range
,"vertical"
方向使用 Plot.y_range
)。
此外,用户可以提供测量单位(ScaleBar.dimensional
,它接受Dimensional
模型的实例)和数据范围的单位(ScaleBar.unit
)。默认的测量单位是由MetricLength
模型表示的米制长度,默认的数据范围单位是米("m"
),与默认测量系统的基本单位相同。
如果数据范围的单位与基本单位不同,用户可以通过适当更改ScaleBar.unit
来指示这一点。例如,如果范围是以公里为单位,那么用户可以通过以下方式指示:
from bokeh.models import ScaleBar, Metric
scale_bar = ScaleBar(
range=plot.y_range,
unit="km",
)
plot.add_layout(scale_bar)
可以通过配置ScaleBar.dimensional
属性来提供其他测量单位。这可以是其他预定义的测量单位,如英制长度(ImperialLength
)或角度单位(Angular
)。用户还可以定义自定义的测量单位。例如,为了定义涉及电子伏特(eV)的图表的自定义公制单位,用户将使用Metric(base_unit="eV")
作为基础:
from bokeh.models import ScaleBar, Metric
scale_bar = ScaleBar(
range=plot.y_range,
unit="MeV",
dimensional=Metric(base_unit="eV"),
)
plot.add_layout(scale_bar)
非公制单位可以使用CustomDimensional
模型来构建。例如,角度测量单位可以定义如下:
from bokeh.models import ScaleBar
from bokeh.models.annotations.dimensional import CustomDimensional
units = CustomDimensional(
basis={
"°": (1, "^\\circ", "degree"),
"'": (1/60, "^\\prime", "minute"),
"''": (1/3600, "^{\\prime\\prime}", "second"),
}
ticks=[1, 3, 6, 12, 60, 120, 240, 360]
)
scale_bar = ScaleBar(
range=plot.y_range,
unit="''",
dimensional=units,
)
plot.add_layout(scale_bar)
一个带有自定义测量单位的比例尺的完整示例:
import numpy as np
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Metric, RangeTool, ScaleBar
from bokeh.plotting import figure, show
n_points = 3000
x_values = np.linspace(0, 100, n_points)
y_values = np.random.randn(n_points).cumsum()
source = ColumnDataSource(data=dict(x=x_values, y=y_values))
detailed_plot = figure(
width=800,
height=300,
tools=["xpan", "xzoom_in", "xzoom_out", "reset", "wheel_zoom"],
toolbar_location="above",
active_scroll="wheel_zoom",
background_fill_color="#efefef",
x_range=(22, 30),
y_axis_location=None,
)
detailed_plot.line("x", "y", source=source)
scale_bar = ScaleBar(
range=detailed_plot.y_range,
unit="MeV",
dimensional=Metric(base_unit="eV"),
orientation="vertical",
location="top_left",
background_fill_color=None,
border_line_color=None,
)
detailed_plot.add_layout(scale_bar)
select_plot = figure(
width=detailed_plot.width,
height=150,
y_range=detailed_plot.y_range,
y_axis_location=None,
tools="",
toolbar_location=None,
background_fill_color=detailed_plot.background_fill_color,
)
select_plot.line("x", "y", source=source)
select_plot.x_range.range_padding = 0
select_plot.ygrid.grid_line_color = None
range_tool = RangeTool(x_range=detailed_plot.x_range)
range_tool.overlay.fill_color = "navy"
range_tool.overlay.fill_alpha = 0.2
select_plot.add_tools(range_tool)
show(column(detailed_plot, select_plot))
箭头#
你可以使用Arrow
注释来连接图形和标签注释。箭头也可以帮助突出显示绘图区域。
箭头是复合注释。这意味着它们使用额外的ArrowHead
对象作为它们的start
和end
。默认情况下,Arrow
注释是单侧箭头:end
属性设置为OpenHead
类型的箭头(看起来像开放背楔形样式),而start
属性设置为None
。如果你想创建双侧箭头,将start
和end
属性都设置为可用的箭头之一。
可用的箭头样式有:
使用这些属性控制箭头的显示效果:
使用
size
属性来控制任何箭头的大小使用标准的线条属性,例如
line_color
和line_alpha
来控制箭头轮廓的外观。使用
fill_color
和fill_alpha
来控制箭头头部的内表面外观(如果适用)。
Arrow
对象本身具有标准的 line properties。设置这些属性以控制箭头轴的颜色和外观。例如:
my_arrow.line_color = "blue"
my_arrow.line_alpha = 0.6
可选地,您可以设置x_range
和y_range
属性,使箭头注释引用额外的非默认x或y范围。这与双轴的工作方式相同。
from bokeh.models import Arrow, NormalHead, OpenHead, VeeHead
from bokeh.palettes import Muted3 as color
from bokeh.plotting import figure, show
p = figure(tools="", toolbar_location=None, background_fill_color="#efefef")
p.grid.grid_line_color = None
p.circle(x=(0, 1, 0.5), y=(0, 0, 0.7), radius=0.1, color="#fafafa")
vh = VeeHead(size=35, fill_color=color[0])
p.add_layout(Arrow(end=vh, x_start=0.5, y_start=0.7, x_end=0, y_end=0))
nh = NormalHead(fill_color=color[1], fill_alpha=0.5, line_color=color[1])
p.add_layout(Arrow(end=nh, line_color=color[1], line_dash=[15, 5],
x_start=1, y_start=0, x_end=0.5, y_end=0.7))
oh = OpenHead(line_color=color[2], line_width=5)
p.add_layout(Arrow(end=oh, line_color=color[2], line_width=5,
x_start=0, y_start=0, x_end=1, y_end=0))
show(p)
乐队#
一个Band
注释是一个与图中数据维度相关联的彩色条纹。带状注释的一个常见用途是指示与一系列测量相关的不确定性。
import numpy as np
import pandas as pd
from bokeh.models import Band, ColumnDataSource
from bokeh.plotting import figure, show
# Create some random data
x = np.random.random(2500) * 140 +20
y = np.random.normal(size=2500) * 2 + 6 * np.log(x)
df = pd.DataFrame(data=dict(x=x, y=y)).sort_values(by="x")
df2 = df.y.rolling(window=300).agg({"y_mean": "mean", "y_std": "std"})
df = pd.concat([df, df2], axis=1)
df["lower"] = df.y_mean - df.y_std
df["upper"] = df.y_mean + df.y_std
source = ColumnDataSource(df.reset_index())
p = figure(tools="", toolbar_location=None, x_range=(40, 160))
p.title.text = "Rolling Standard Deviation"
p.xgrid.grid_line_color=None
p.ygrid.grid_line_alpha=0.5
p.scatter(x="x", y="y", color="blue", marker="dot", size=10, alpha=0.4, source=source)
p.line("x", "y_mean", line_dash=(10, 7), line_width=2, source=source)
band = Band(base="x", lower="lower", upper="upper", source=source,
fill_alpha=0.3, fill_color="yellow", line_color="black")
p.add_layout(band)
show(p)
框注释#
一个BoxAnnotation
是一个矩形框,你可以用它来突出显示特定的绘图区域。使用屏幕单位或数据单位来定位一个框注释。
要定义这些框的边界,请使用left
/right
或top
/
bottom
属性。如果只提供一个边界(例如,一个left
值但没有right
值),则框将延伸到未指定维度的可用绘图区域的边缘。
from bokeh.models import BoxAnnotation
from bokeh.plotting import figure, show
from bokeh.sampledata.glucose import data
TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
#reduce data size
data = data.loc['2010-10-06':'2010-10-13'].reset_index()
p = figure(x_axis_type="datetime", tools=TOOLS)
p.line("datetime", "glucose", source=data, color="gray", legend_label="glucose")
low_box = BoxAnnotation(top=80, fill_alpha=0.2, fill_color='#D55E00')
mid_box = BoxAnnotation(bottom=80, top=180, fill_alpha=0.2, fill_color='#0072B2')
high_box = BoxAnnotation(bottom=180, fill_alpha=0.2, fill_color='#D55E00')
p.add_layout(low_box)
p.add_layout(mid_box)
p.add_layout(high_box)
p.title.text = "Glucose Range"
p.xgrid.grid_line_color=None
p.ygrid.grid_line_alpha=0.5
p.xaxis.axis_label = 'Time'
p.yaxis.axis_label = 'Value'
p.legend.level = "overlay"
p.legend.location = "top_left"
show(p)
多边形注释#
一个 PolyAnnotation
是一个多边形,其顶点可以在 屏幕单位 或
数据单位 中。
要定义多边形的顶点,请向xs
和ys
属性提供一系列坐标。Bokeh会自动将最后一个顶点连接到第一个顶点以创建闭合形状。
from datetime import datetime as dt
import pandas as pd
from bokeh.models import PolyAnnotation
from bokeh.plotting import figure, show
from bokeh.sampledata.stocks import GOOG
p = figure(height=200, x_axis_type="datetime",
background_fill_color="#efefef", title="Google stock")
df = pd.DataFrame(GOOG)
df["date"] = pd.to_datetime(df["date"])
p.line(df["date"], df["close"], line_width=1.5, color="grey")
start_date = dt(2008, 11, 24)
start_y = df.loc[df["date"] == start_date]["close"].values[0]
end_date = dt(2010, 1, 4)
end_y = df.loc[df["date"] == end_date]["close"].values[0]
polygon = PolyAnnotation(
fill_color="blue", fill_alpha=0.2,
xs=[start_date, start_date, end_date, end_date],
ys=[start_y - 100, start_y + 100, end_y + 100, end_y - 100],
)
p.add_layout(polygon)
show(p)
标签#
标签是带有关于字形或绘图区域附加信息的矩形框。
要创建单个文本标签,请使用Label
注释。以下是此注释的最重要属性:
一个
text
属性,包含要在标签内显示的文本。x_offset
和y_offset
属性用于指定标签相对于其x
和y
坐标的位置。标准的文本属性以及其他样式参数,例如
border_line
和background_fill
属性。
Label(x=100, y=5, x_units='screen', text='Some Stuff',
border_line_color='black', border_line_alpha=1.0,
background_fill_color='white', background_fill_alpha=1.0)
text
可能包含换行符,这将导致标签显示为多行。
Label(x=100, y=5, text='A very long label\nwith mutiple lines')
要一次性创建多个标签,请使用LabelSet
注解。要配置标签集的标签,请使用包含标签属性数据列的数据源,例如text
、x
和y
。如果直接为属性(如x_offset
和y_offset
)赋值而不是列名,则该值将用于标签集的所有标签。
LabelSet(x='x', y='y', text='names',
x_offset=5, y_offset=5, source=source)
以下示例说明了Label
和LabelSet
的使用:
from bokeh.models import ColumnDataSource, Label, Node
from bokeh.plotting import figure, show
source = ColumnDataSource(data=dict(
height=[66, 71, 72, 68, 58, 62],
weight=[165, 189, 220, 141, 260, 174],
names=["Mark", "Amir", "Matt", "Greg", "Owen", "Juan"],
))
p = figure(title="Dist. of 10th Grade Students", x_range=(140, 275))
p.xaxis.axis_label = "Weight (lbs)"
p.yaxis.axis_label = "Height (in)"
p.scatter(x="weight", y="height", size=8, source=source)
p.text(x="weight", y="height", text="names",
x_offset=5, y_offset=5, anchor="bottom_left", source=source)
frame_left = Node(target="frame", symbol="left", offset=5)
frame_bottom = Node(target="frame", symbol="bottom", offset=-5)
citation = Label(
x=frame_left,
y=frame_bottom,
anchor="bottom_left",
text="Collected by Luke C. 2016-04-01",
padding=10,
border_radius=5,
border_line_color="black", background_fill_color="white",
)
p.add_layout(citation)
show(p)
LabelSet
的 text
值可能包含换行符,这将导致多行标签。
斜率#
Slope
注释是从图的一个边缘到另一个边缘以特定角度绘制的线条。
这是此注解最常用的属性:
gradient
: 直线的斜率,单位为数据单位。y_intercept
: 直线的y截距,单位为数据单位。标准的line properties。
import numpy as np
from bokeh.models import Slope
from bokeh.palettes import Sunset10
from bokeh.plotting import figure, show
# linear equation parameters
slope, intercept = 2, 10
x = np.arange(0, 20, 0.2)
y = slope * x + intercept + np.random.normal(0, 4, 100)
blue, yellow = Sunset10[0], Sunset10[5]
p = figure(width=600, height=600, x_axis_label='x', y_axis_label='y',
background_fill_color="#fafafa")
p.y_range.start = 0
p.scatter(x, y, size=8, alpha=0.8, fill_color=yellow, line_color="black")
slope = Slope(gradient=slope, y_intercept=intercept,
line_color=blue, line_dash='dashed', line_width=4)
p.add_layout(slope)
show(p)
跨度#
Span
注释是与图表的x轴或y轴正交的线条。
它们具有单一维度(宽度或高度),并从图表区域的一个边缘延伸到相对的边缘。
这是此注解最常用的属性:
dimension
: 跨度线的方向。方向可以是以下两个值之一:*"height"
表示与图表的x轴平行的线,或者"width"
表示与图表的y轴平行的线。location
: 沿着由dimension
指定的轴的跨度位置。标准的line properties。
from datetime import datetime as dt
from bokeh.models import Span
from bokeh.plotting import figure, show
from bokeh.sampledata.daylight import daylight_warsaw_2013
p = figure(height=350, x_axis_type="datetime", y_axis_type="datetime",
title="2013 Sunrise and Sunset in Warsaw with DST dates marked",
y_axis_label="Time of Day", background_fill_color="#fafafa")
p.y_range.start = 0
p.y_range.end = 24 * 60 * 60 * 1000
p.line("Date", "Sunset", source=daylight_warsaw_2013,
color='navy', line_dash="dotted", line_width=2, legend_label="Sunset")
p.line("Date", "Sunrise", source=daylight_warsaw_2013,
color='orange', line_dash="dashed", line_width=2, legend_label="Sunrise")
dst_start = Span(location=dt(2013, 3, 31, 2, 0, 0), dimension='height',
line_color='#009E73', line_width=5)
p.add_layout(dst_start)
dst_end = Span(location=dt(2013, 10, 27, 3, 0, 0), dimension='height',
line_color='#009E73', line_width=5)
p.add_layout(dst_end)
p.yaxis.formatter.days = "%Hh"
p.xgrid.grid_line_color = None
show(p)
胡须#
一个Whisker
注释是一个与图中数据维度相连的“茎”。您可以使用数据单位或屏幕单位来定义此注释。
whisker注释的一个常见用途是表示单点测量的误差范围或不确定性。
这是此注解最常用的属性:
lower
: 须线低端的坐标。upper
: 须的上端坐标。dimension
: 胡须的方向。方向可以是以下两个值之一:*"width"
表示胡须平行于图表的x轴。或者"height"
表示胡须平行于图表的y轴。base
: 沿着dimension
指定的维度,whisker的位置。标准的line properties。
from bokeh.models import ColumnDataSource, Whisker
from bokeh.plotting import figure, show
from bokeh.sampledata.autompg2 import autompg2 as df
from bokeh.transform import factor_cmap, jitter
classes = list(sorted(df["class"].unique()))
p = figure(height=400, x_range=classes, background_fill_color="#efefef",
title="Car class vs HWY mpg with quantile ranges")
p.xgrid.grid_line_color = None
g = df.groupby("class")
upper = g.hwy.quantile(0.80)
lower = g.hwy.quantile(0.20)
source = ColumnDataSource(data=dict(base=classes, upper=upper, lower=lower))
error = Whisker(base="base", upper="upper", lower="lower", source=source,
level="annotation", line_width=2)
error.upper_head.size=20
error.lower_head.size=20
p.add_layout(error)
p.scatter(jitter("class", 0.3, range=p.x_range), "hwy", source=df,
alpha=0.5, size=13, line_color="white",
color=factor_cmap("class", "Light7", classes))
show(p)