等高线图#
等高线图用于在二维四边形网格中计算和渲染恒定值的线。可以使用单个函数调用来渲染线和线之间的填充区域。
简单示例#
以下是一个简单示例,它渲染等高线和填充的多边形区域。
import numpy as np
from bokeh.palettes import Sunset8
from bokeh.plotting import figure, show
# Data to contour is the sum of two Gaussian functions.
x, y = np.meshgrid(np.linspace(0, 3, 40), np.linspace(0, 2, 30))
z = 1.3*np.exp(-2.5*((x-1.3)**2 + (y-0.8)**2)) - 1.2*np.exp(-2*((x-1.8)**2 + (y-1.3)**2))
p = figure(width=550, height=300, x_range=(0, 3), y_range=(0, 2))
levels = np.linspace(-1, 1, 9)
contour_renderer = p.contour(x, y, z, levels, fill_color=Sunset8, line_color="black")
colorbar = contour_renderer.construct_color_bar()
p.add_layout(colorbar, "right")
show(p)
按照惯例,z
是要生成等高线的二维数组,它定义在 x
、y
网格上。这里,网格是一个等间距的笛卡尔网格。 levels
包含要生成等高线的级别序列。
line_color
和 fill_color
都是 contour()
的可选关键字参数。必须指定 line_color
来绘制等高线,并指定 fill_color
来绘制填充的等高线多边形。它们可以是标量或向量视觉属性。
注意
等高线的向量视觉属性的长度为 len(levels)
,而填充的等高线多边形的长度为 len(levels)-1
。
在此示例中,line_color
是一个标量,因此每条等高线都以黑色实线渲染。 fill_color
是一个向量,因此等高线级别之间的填充区域以不同的颜色渲染。
在图的右侧有一个颜色条,它使用 construct_color_bar()
获得。它会自动显示与等高线图相同的填充和线视觉属性。
极坐标网格示例#
以下是一个更复杂的示例,它展示了等高线图的其他可用功能。
import numpy as np
from bokeh.palettes import Cividis
from bokeh.plotting import figure, show
# Data to contour is a 2D sin wave on a polar grid.
radius, angle = np.meshgrid(np.linspace(0, 1, 20), np.linspace(0, 2*np.pi, 120))
x = radius*np.cos(angle)
y = radius*np.sin(angle)
z = 1 + np.sin(3*angle)*np.sin(np.pi*radius)
p = figure(width=550, height=400)
levels = np.linspace(0, 2, 11)
contour_renderer = p.contour(
x=x, y=y, z=z, levels=levels,
fill_color=Cividis,
hatch_pattern=["x"]*5 + [" "]*5,
hatch_color="white",
hatch_alpha=0.5,
line_color=["white"]*5 + ["black"] + ["red"]*5,
line_dash=["solid"]*6 + ["dashed"]*5,
line_width=[1]*6 + [2]*5,
)
colorbar = contour_renderer.construct_color_bar(title="Colorbar title")
p.add_layout(colorbar, "right")
show(p)
网格是极坐标网格,它本身环绕,并且还有许多其他视觉属性,包括 line
、fill
和 hatch
属性。其中许多是向量属性,因此可以突出显示例如正负等高线级别。
所有视觉属性都可以是标量或具有正确长度的向量。颜色视觉属性 line_color
、fill_color
和 hatch_color
支持一些额外的选项来指定它们的方式。
比所需长度更长或更短的颜色序列将使用
interp_palette()
进行重采样。长度为 256 的调色板(例如Cividis256
)在这里很有用。可以使用调色板集合,例如
Cividis
,它是一个字典,将调色板长度(颜色数量)映射到调色板。如果集合包含具有正确长度的调色板,则使用该调色板。如果所需长度超出集合中可用的长度,则使用最接近长度的调色板并进行线性插值。
construct_color_bar()
接受其他关键字参数,这些参数将传递给 ContourColorBar
构造函数以设置属性,例如此处显示的 title
。
动画等高线#
Bokeh 可以使用 bokeh serve
生成动画等高线图,因为等高线计算在 Python 中进行。以下是一个来自 examples/app/contour_animated.py
的示例
import numpy as np
from bokeh.driving import count
from bokeh.palettes import PiYG
from bokeh.plotting import curdoc, figure
from bokeh.plotting.contour import contour_data
x, y = np.meshgrid(np.linspace(-1, 1, 41), np.linspace(-1, 1, 41))
levels = np.linspace(-1.0, 1.0, 11)
def get_z(timestep):
delta = 0.08*np.cos(timestep*0.15)
amps = [0.95, 0.95, -0.95, -0.95]
xmids = [-0.4, 0.4, -0.4, 0.4]
ymids = [-0.4, 0.4, 0.4, -0.4]
rads = [0.4 + delta, 0.4 + delta, 0.4 - delta, 0.4 - delta]
z = np.zeros_like(x)
for amp, xmid, ymid, rad in zip(amps, xmids, ymids, rads):
z += amp*np.exp( -((x-xmid)**2 + (y-ymid)**2)/rad**2 )
return z
@count()
def callback(timestep):
z = get_z(timestep)
new_contour_data = contour_data(x, y, z, levels)
contour_renderer.set_data(new_contour_data)
fig = figure(width=600, height=450)
contour_renderer = fig.contour(x, y, get_z(0), levels, fill_color=PiYG,
line_color="black", line_width=[1]*5 + [3] + [1]*5)
colorbar = contour_renderer.construct_color_bar()
fig.add_layout(colorbar, 'right')
curdoc().add_periodic_callback(callback, 40)
curdoc().add_root(fig)
要在 Bokeh 服务器上运行此代码,请使用
bokeh serve --show contour_animated.py
执行动画的关键步骤序列为
像往常一样调用
contour()
,并将返回的ContourRenderer
存储起来。确定更新后的
z
数组,该数组可能来自文件读取或计算而来。将更新后的
z
和未更改的x
、y
和levels
传递给contour_data()
以生成等高线数据对象。使用新的等高线数据对象调用
set_data()
。从步骤 2 重复。
此处的动画示例假设网格、等高线级别和视觉属性没有改变。可以这样做,但需要小心处理更改的绘图边界并将视觉属性分配给等高线级别,因此在这些情况下,通常更容易删除旧的无用等高线图并用一个新的替换它。
高级细节#
contour()
的唯一必需关键字参数是 z
、levels
以及 fill_color
和 line_color
中的至少一个。 x
和 y
是可选的,如果未指定,则将使用笛卡尔网格,网格间距在两个方向上均为 1。
要从等高线计算中排除网格点,可以使用 z
的 NumPy 掩码数组,将排除的网格点掩盖,或者将这些网格点的 z
值设置为 np.nan
。
等高线使用 MultiLine
符号实现,填充的等高线多边形使用 MultiPolygons
符号实现,line_width
设置为零。
等高线的计算由 ContourPy
执行。有关此内容的信息,请参阅 ContourPy 文档。
注意
Bokeh 版本 3.0 中添加了等高线功能,并且计划在未来的版本中进行改进。