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

如何计算并绘制二维辐射数据的90% Highest Density Interval (HDI)

二维辐射数据的90% HDI计算与绘制方案

问题描述

拥有位置数组x、y,以及对应位置的归一化辐射值数组z(全空间积分和为1),需要计算并绘制90% HDI(最高密度区间)——即包含90%辐射积分的最小区域,逻辑与概率分布的HDI计算一致,但缺少具体实现思路。

示例数据

以下是与实际数据拓扑结构类似的生成代码:

import numpy as np 

## Spatial data, with randomness to show that it is not in a rectangular grid 
x = np.arange(-2,2, step=0.2)
x+= 0.1*np.random.rand(len(x)) 
y = np.arange(-2,2, step=0.2) 
y+= 0.1*np.random.rand(len(y)) 

z = np.zeros((len(x), len(y))) 
for i, ix in enumerate(x): 
    for k, iy in enumerate(y): 
        tmp = np.cos(ix)*np.sin(iy)
        if tmp>=0: 
            z[i,k] = tmp 
z=z/np.sum(z) 

解决思路与实现步骤

核心逻辑

HDI的核心是优先保留密度从高到低的点,直到累计辐射积分达到90%阈值,再提取这些点的区域边界。针对不规则网格数据,可通过以下步骤实现:

  1. 扁平化数据
    将二维的x、y、z转换为一维数组,便于排序和累加计算:
# 扁平化所有空间点
x_flat = x.repeat(len(y))
y_flat = np.tile(y, len(x))
z_flat = z.flatten()
  1. 按辐射值降序排序
    将所有点按照辐射值从大到小排序,确保高密度区域优先被纳入HDI:
# 按辐射值降序获取索引
sorted_indices = np.argsort(z_flat)[::-1]
sorted_z = z_flat[sorted_indices]
sorted_x = x_flat[sorted_indices]
sorted_y = y_flat[sorted_indices]
  1. 确定HDI区域内的点
    累加排序后的辐射值,找到累计和首次达到0.9的位置,提取该位置之前的所有点作为HDI区域内的点:
cumulative_sum = np.cumsum(sorted_z)
# 找到累计积分≥0.9的第一个索引
hdi_cutoff_idx = np.argmax(cumulative_sum >= 0.9)
# 提取HDI内的点集
hdi_x = sorted_x[:hdi_cutoff_idx+1]
hdi_y = sorted_y[:hdi_cutoff_idx+1]
  1. 绘制HDI边界
    使用凸包拟合HDI点集的边界,直观展示最小区域:
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt

# 计算凸包
hdi_points = np.column_stack((hdi_x, hdi_y))
hull = ConvexHull(hdi_points)

# 可视化原始数据与HDI边界
plt.scatter(x_flat, y_flat, c=z_flat, cmap='viridis', alpha=0.6)
# 绘制凸包边界线
for simplex in hull.simplices:
    plt.plot(hdi_points[simplex, 0], hdi_points[simplex, 1], 'r-', linewidth=2)
plt.colorbar(label='Normalized Radiation')
plt.title('90% HDI of Radiation Distribution')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()

替代方案:基于插值的轮廓线绘制

如果不需要凸包,可通过插值生成规则网格,再绘制对应90%积分的密度轮廓线:

from scipy.interpolate import griddata

# 创建规则网格用于插值
xi, yi = np.meshgrid(np.linspace(x.min(), x.max(), 100), np.linspace(y.min(), y.max(), 100))
zi = griddata((x_flat, y_flat), z_flat, (xi, yi), method='cubic')

# 计算90%积分对应的辐射值阈值
sorted_zi = zi.flatten()
sorted_zi.sort()[::-1]
cum_zi = np.cumsum(sorted_zi)
hdi_threshold = sorted_zi[np.argmax(cum_zi >= 0.9)]

# 绘制HDI轮廓线
plt.contour(xi, yi, zi, levels=[hdi_threshold], colors='red', linewidths=2)
plt.scatter(x_flat, y_flat, c=z_flat, cmap='viridis', alpha=0.6)
plt.colorbar(label='Normalized Radiation')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:22:37