You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Holoviews栅格分类数据可视化配置外部图例?

Holoviz hvplot绘制分类栅格:自定义色图、匹配图例、外部图例及缺失类别处理

最优解决方案代码

以下代码直接满足你的全部需求,通过xarray分类数据类型实现稳健的类别-颜色映射,自动生成正确图例并支持外部放置:

import holoviews as hv
import hvplot.xarray
import numpy as np
import xarray as xr

# 定义土地覆盖类别与对应十六进制色码
color_key = {
    "No Data": "#000000",
    "Saturated / Defective": "#ff0000",
    "Dark Area Pixels": "#2f2f2f",
    "Cloud Shadows": "#643200",
    "Vegetation": "#00a000",
    "Bare Soils": "#ffe65a",
    "water": "#0000ff",
    "Clouds low probability / Unclassified": "#808080",
    "Clouds medium probability": "#c0c0c0",
    "Clouds high probability": "#ffffff",
    "Cirrus": "#64c8ff",
    "Snow / Ice": "#ff96ff",
}

# 生成模拟数据(故意排除类别1,模拟数据缺失部分类别的场景)
nx = 40
ny = 70
xcoords = [37 + 0.1 * i for i in range(nx)]
ycoords = [5 + 0.2 * i for i in range(ny)]
data = np.random.choice([0,2,3,4,5,6,7,8,9,10,11], size=nx*ny).reshape(nx, ny)
da = xr.DataArray(
    data,
    dims=["x", "y"],
    coords={"x": xcoords, "y": ycoords},
)

# 将数值型数据转换为分类类型,绑定所有预定义类别
value_to_class = {i: cls for i, cls in enumerate(color_key.keys())}
da_class = da.map_blocks(lambda x: np.vectorize(value_to_class.get)(x)).astype('category')
da_class = da_class.cat.set_categories(list(color_key.keys()))

# 可视化配置
plot = da_class.hvplot(
    cmap=color_key,  # 直接传入类别-颜色映射字典
    rasterize=True,  # 大栅格数据推荐开启,提升渲染性能
    legend='right',  # 图例置于绘图区域右侧(可选:left/top/bottom/top_right等)
    legend_opts={
        'title': '土地覆盖类别',
        'label_width': 220,  # 调整标签宽度避免文本换行
        'padding': 10,
    },
    frame_width=550,
    frame_height=350
)

# 渲染绘图
hv.render(plot)

关键功能实现说明

  1. 自定义分类色图
    直接将color_key字典传入cmap参数,hvplot会自动将每个类别名称与对应十六进制颜色绑定,无需手动转换为颜色元组。

  2. 带类别标签的图例
    通过xarray的分类数据类型(astype('category') + cat.set_categories()),强制保留所有预定义类别。即使数据中缺失部分类别,图例依然会完整显示所有条目,颜色与标签严格匹配。

  3. 处理缺失类别的场景
    传统直接传入颜色元组的方式会因数据缺失类别导致颜色索引错位,而分类数据类型通过类别名称而非数值索引匹配颜色,彻底解决了这个问题。

  4. 外部图例设置
    通过legend参数指定图例位置(如'right'、'top_right')即可将图例移至绘图区域外部,同时可通过legend_opts调整图例标题、标签宽度等样式,优化视觉效果。


基于原代码的优化方案(保留NdOverlay方式)

如果你想沿用原有的NdOverlay图例实现,只需关闭原栅格图的色条并设置图例位置:

# 关闭原栅格图的色条,避免重复显示
raster_plot = da.hvplot().opts(cmap=tuple(color_key.values()), colorbar=False)

# 构建自定义图例并设置外部位置
legend = hv.NdOverlay(
    {k: hv.Points([0,0], label=k).opts(color=v, size=0, apply_ranges=False) 
     for k,v in color_key.items()},
    "Classification"
).opts(legend_position='right', legend_opts={'title': '类别'})

# 组合绘图
final_plot = raster_plot * legend
hv.render(final_plot)

此方式需手动确保数值与颜色索引严格对应,适用于简单场景,但稳健性不如分类数据方案。

内容的提问来源于stack exchange,提问作者sir_olf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:25:17