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

Python实现2880×2880相似度矩阵径向热力图的方案咨询

问题概述

现有尺寸为2880×2880的相似度矩阵(共850万个数据点),使用Holoviews绘制径向热力图时,生成的HTML文件大小达500MB,打开时始终处于加载状态无法正常显示,需求为基于该矩阵生成圆形径向热力图。

问题详情
  • 数据源逻辑:数据源为10个不同点位一整年的监测数据,按月份-小时维度拆分数组:每个月对应24个数组(分别对应00:00至23:00各小时的聚合数据),单个数组长度为28-31(对应当月自然天数),数组单元格存储待分析的监测指标值。按该规则,单个点位对应24×12=288个数组,10个点位共计生成2880个数组;对所有数组两两计算相似度系数,最终得到2880×2880的相似度矩阵。
  • 可视化要求:参考Holoviews官方RadialHeatMap样式生成径向相似度矩阵图,不需要显示刻度与标签(2880行数据对应的Place01Jan0800格式标签过于冗余,不便查看),仅保留图形形状、色彩映射和分区效果即可,参考样式如下:
    径向热力图参考样式
  • 现存问题:基于现有逻辑生成的HTML文件体积达500MB,打开后始终为空白无法加载,最小复现代码如下(已使用随机生成的测试数据替代真实数据加载逻辑):
import sys
sys.setrecursionlimit(10000)

import random
import numpy as np
import pandas as pd
import holoviews as hv
from holoviews import opts
from bokeh.plotting import show
import gc

# 构造测试用例
def transformer():
    dimension = 2880
    dummy_matrix = ([[ random.random() for i in range(dimension)  ] for j in range(dimension)])

    col_vals = [str(i) for i in range(dimension*dimension)]
    row_vals = [str(i) for i in range(dimension*dimension)]
    val_vals = (np.reshape(np.array(dummy_matrix), -1)).tolist()
    idx_vals = [i for i in range(dimension*dimension)]

    return idx_vals, val_vals, row_vals, col_vals

idx_arr, val_arr, row_arr, col_arr = transformer()
df = pd.DataFrame({"values": val_arr, "x-label": row_arr, "y-label": col_arr}, index=idx_arr)

hv.extension('bokeh')
heatmap = hv.HeatMap(df, ["x-label", "y-label"])
heatmap.opts(opts.HeatMap(cmap="viridis", radial=True))

gc.collect()
show(hv.render(heatmap))
  • 已尝试方案:查阅Datashader网格渲染相关文档,希望通过其降低渲染后的文件体积,但未找到将Datashader接入径向热力图渲染的方法,Holoviews的径向热力图组件暂不支持datashade特性。
  • 需求补充:当前可视化仅用于演示,不需要悬停信息框、缩放交互等复杂功能,仅需要清晰的整体可视化概览效果即可,任何可行实现方案均接受。
可行实现方案

问题根源很明确:Holoviews搭配Bokeh渲染径向热力图时,会把850万个矩阵单元格作为独立矢量元素写入HTML,文件体积和浏览器渲染压力必然会达到无法正常加载的级别。既然不需要交互功能,完全没必要走前端矢量渲染的路线,直接用Matplotlib生成静态栅格图是效率最高的方案,生成的文件体积仅数MB,任意设备都能秒开,完全满足演示需求。

实现逻辑是直接在极坐标系下绘制栅格化的色块,关闭所有不需要的坐标轴元素,参考代码如下:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize

# 替换为你实际的2880*2880相似度矩阵
sim_matrix = np.random.rand(2880, 2880)
dim = sim_matrix.shape[0]

# 初始化画布,设置极坐标投影
fig = plt.figure(figsize=(10, 10), dpi=150)
ax = fig.add_subplot(111, projection='polar')
ax.set_axis_off() # 隐藏所有坐标轴、刻度、标签

# 生成极坐标网格
theta = np.linspace(0, 2 * np.pi, dim + 1)
r = np.linspace(0, 1, dim + 1)
Theta, R = np.meshgrid(theta, r)

# 绘制径向热力图
norm = Normalize(vmin=sim_matrix.min(), vmax=sim_matrix.max())
ax.pcolormesh(Theta, R, sim_matrix, cmap='viridis', norm=norm, shading='auto')

# 导出图片,去掉多余边距
plt.savefig('radial_heatmap.png', bbox_inches='tight', pad_inches=0, dpi=150)
plt.close()

如果需要HTML格式展示,直接把生成的PNG图片以<img>标签形式嵌入HTML即可,最终文件体积不到10MB,所有浏览器都能秒开。
如果需要添加分区分隔线,只需要计算分区对应的角度、半径位置,用ax.plot()绘制对应颜色的实线即可实现和参考样式一致的分区效果。

可选优化方案:如果一定需要保留基础的缩放、悬停交互,可以先把28802880的矩阵降采样到800800以内再用Holoviews渲染。对于演示用的概览图,2880的分辨率属于严重过剩,人眼无法区分单像素级的差异,降采样后生成的HTML体积会降到原来的1/13左右,基本可以正常加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:39:17