等高线图#
等高线图用于计算和渲染二维四边形网格中的等值线。通过一次函数调用,可以同时渲染线条和线条之间的填充区域。
简单示例#
这里是一个简单的示例,展示了等高线和填充多边形区域的渲染。
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的笛卡尔网格。
要从等高线计算中排除网格点,可以使用NumPy的掩码数组来处理z,将被排除的网格点掩码掉,或者将这些网格点的z值设置为np.nan。
等高线使用MultiLine字形实现,填充的等高线多边形则使用MultiPolygons字形实现,并将line_width设置为零。
轮廓的计算由ContourPy执行。有关此信息的更多详情,请参阅ContourPy文档。
注意
等高线功能已添加到Bokeh 3.0版本中,并计划在未来的版本中进行改进。