【导语】通过上一节的学习,相信我们对bokeh有了一个基本的认识。那么这篇文章主要内容是通过bokeh实现布局,交互和标注。
一、布局
- 横向布局:主要使用
row()
函数- 纵向布局:主要使用
column()
函数
from bokeh.io import output_notebook, show
from bokeh.layouts import row, column
from bokeh.plotting import figure
output_notebook()
x = list(range(10))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 3) for i in x]
# 绘制三张图
s1 = figure(plot_width=250, plot_height=250)
s1.circle(x, y0, size=12, color="pink", alpha=0.8)
s2 = figure(plot_width=250, plot_height=250)
s2.triangle(x, y1, size=12, color="lightblue", alpha=0.8)
s3 = figure(plot_width=250, plot_height=250)
s3.square(x, y2, size=12, color="orange", alpha=0.8)
layout = row(column(s1, s2), s3)
output_notebook()
show(layout)
- 网格布局:
gridplot()
- 选项卡式布局:
Panel()
,Tabs()
from bokeh.io import output_notebook, show
from bokeh.layouts import gridplot
from bokeh.plotting import figure
x = list(range(11))
y0 = x
y1 = [10 - i for i in x]
y2 = [abs(i - 5) for i in x]
# 绘制三张图
s1 = figure(background_fill_color="#fafafa")
s1.circle(x, y0, size=12, alpha=0.8, color="#53777a")
s2 = figure(background_fill_color="#fafafa")
s2.triangle(x, y1, size=12, alpha=0.8, color="#c02942")
s3 = figure(background_fill_color="#fafafa")
s3.square(x, y2, size=12, alpha=0.8, color="#d95b43")
# 网格布局,并设置绘图大小
grid3 = gridplot([s1, s2, s3], ncols=2, plot_width=250, plot_height=250)
output_notebook()
show(grid3)
如果希望在两个可视化文件之间进行全尺寸切换,而不必将它们压缩到彼此相邻或重叠的位置,则选项卡式布局是一个不错的选择
from bokeh.io import show, output_notebook
from bokeh.models import Panel, Tabs
from bokeh.plotting import figure
p1 = figure(plot_width=300, plot_height=300)
p1.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=20, color="navy", alpha=0.5)
tab1 = Panel(child=p1, title="circle")
p2 = figure(plot_width=300, plot_height=300)
p2.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=3, color="navy", alpha=0.5)
tab2 = Panel(child=p2, title="line")
output_notebook()
show(Tabs(tabs=[tab1, tab2]))
二、交互
- 链接平移(Linked Panning)
- 链接选择(Linked Brushing)
通常需要在许多绘图之间进行链接平移。启用此功能所需要做的就是在figure()函数中共享范围。运行下列代码,尝试拖拽其中任一绘图,看看其它绘制是否跟着一起动。
from bokeh.io import output_notebook, show
from bokeh.layouts import gridplot
from bokeh.plotting import figure
x = list(range(11))
y0 = x
y1 = [10-xx for xx in x]
y2 = [abs(xx-5) for xx in x]
# 绘制 s1
s1 = figure(plot_width=250, plot_height=250, title=None)
s1.circle(x, y0, size=10, color="navy", alpha=0.5)
# 绘制 s2 并且共享一个范围
s2 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)
s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5)
# 绘制 s3 并且共享一个范围
s3 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, title=None)
s3.square(x, y2, size=10, color="olive", alpha=0.5)
p = gridplot([[s1, s2, s3]], toolbar_location=None)
# 显示结果
output_notebook()
show(p)
运行下列代码,尝试使用绘图右上角的工具来对图进行操作,当鼠标悬停在工具图标上时,也会显示工具名称。
- BoxSelectTool:名为 'box_select',在绘图区域上拖动鼠标来定义矩形选择区域;
- LassoSelectTool:名为 'lasso_select',在绘图区域上拖动鼠标来定义要选择的任意区域。
from bokeh.io import output_notebook, show
from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
y1 = [xx**2 for xx in x]
# 创建图片共享的列数据源
source = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))
# 自定义选择外观
TOOLS = "box_select,lasso_select,help"
# create a new plot and add a renderer
left = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
left.circle('x', 'y0', source=source)
# create another new plot and add a renderer
right = figure(tools=TOOLS, plot_width=300, plot_height=300, title=None)
right.circle('x', 'y1', source=source)
p = gridplot([[left, right]])
output_notebook()
show(p)
三、标注(注释)
- 图例
1)legend_label
2)legend_group- 悬停工具
legend_label
要为字形提供简单的显式标签,在绘图时,需要传入legend_label
参数:如果给多个字形赋予了相同的标签,则它们将全部合并为带有该标签的单个图例项。
import numpy as np
from bokeh.plotting import figure, output_notebook, show
x = np.linspace(0, 4*np.pi, 100)
y = np.sin(x)
p = figure()
# 通过lagend_label参数添加图例标签
p.circle(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.square(x, 3*y, legend_label="3*sin(x)", fill_color=None, line_color="green")
p.line(x, 3*y, legend_label="3*sin(x)", line_color="green")
output_notebook()
show(p)
legend_group()
通常希望通过对数据源列中的值进行分组操作来生成多个图例项。 将legend_group参数传入字形方法,Bokeh可以执行这样的分组
from bokeh.models import ColumnDataSource
from bokeh.palettes import RdBu3
from bokeh.plotting import figure, output_notebook, show
c1 = RdBu3[2] # red
c2 = RdBu3[0] # blue
source = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=[c1, c2, c1, c2, c1, c2],
label=['hi', 'lo', 'hi', 'lo', 'hi', 'lo']
))
p = figure(x_range=(0, 7), y_range=(0, 3), plot_height=300, tools='save')
# 图例字段与数据源中的 label 匹配
p.circle( x='x', y='y', radius=0.5, color='color', legend_group='label', source=source)
output_notebook()
show(p)
以@开头的字段名称与 ColumnDataSource 中的内容相关联。运行下方代码,尝试将鼠标悬停在点上面,看看是否有内容展示
from bokeh.plotting import ColumnDataSource, figure, output_notebook, show
source = ColumnDataSource(data=dict(
x=['1', '5', '6', '3', '4', '7'],
y=[123, 153, 89, 107, 98, 23],
desc=['A', 'b', 'C', 'd', 'e','f'],
))
TOOLTIPS = [
("index", "$index"),
("(x,y)", "($x, $y)"),
("desc", "@desc"),
]
p = figure(plot_width=400, plot_height=400, tooltips=TOOLTIPS,
title="Mouse over the dots")
p.circle('x', 'y', size=20, source=source)
output_notebook()
show(p)
希望本文的内容对大家的学习或者工作能带来一定的帮助,每天进步一点点,加油。
网友评论