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

如何为含子数组的特定值设置matplotlib imshow自定义配色

解决方案

imshow要求输入纯单值的二维数值数组,没法直接用带嵌套子数组的数据绘图,所以必须先做数据转换,再用现有matplotlib工具实现需求,具体步骤如下:

1. 统一数据格式:将子数组映射为唯一单值

你提到总共只有11种不同的可能值(含子数组),可以先给每种情况分配唯一整数ID:

  • 比如整理所有值类型(包括子数组),把列表转成元组(列表不能当字典键),创建映射表:
    # 示例映射,根据你的11种实际情况补充完整
    value_to_id = {
        4: 0,
        5: 1,
        6: 2,
        8: 3,
        10: 4,
        (4,5,6): 5
    }
    
  • 遍历原始值数组,把每个元素替换为对应ID,得到纯单值数组:
    values = [6,10,8,[4,5,6],4]
    id_values = []
    for v in values:
        if isinstance(v, list):
            id_values.append(value_to_id[tuple(v)])
        else:
            id_values.append(value_to_id[v])
    # 转换后结果:[2,4,3,5,0]
    

2. 构建自定义配色映射

用ListedColormap创建对应11种值的色图,配合BoundaryNorm实现离散值的颜色映射:

from matplotlib.colors import ListedColormap, BoundaryNorm
import numpy as np

# 自定义11种颜色(可根据需求调整)
colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', 
          '#00FFFF', '#800000', '#008000', '#000080', '#808000', '#800080']
cmap = ListedColormap(colors)

# 设置边界,确保每个ID对应独立颜色区间
bounds = np.arange(-0.5, len(value_to_id)+0.5, 1)
norm = BoundaryNorm(bounds, cmap.N)

3. 坐标转二维网格并绘图

将坐标元组对应的值ID填充到二维数组中(空位置用NaN留白),再调用imshow绘图:

import matplotlib.pyplot as plt

# 示例坐标数组
coords = [(0,0), (0,1), (0,2), (0,3), (0,4)]

# 创建二维网格(根据你的坐标范围调整尺寸)
grid = np.full((1, len(coords)), np.nan)
for idx, (x,y) in enumerate(coords):
    grid[y, x] = id_values[idx]

# 绘图
plt.imshow(grid, cmap=cmap, norm=norm, extent=[-0.5, len(coords)-0.5, -0.5, 0.5])

# 添加颜色条并标注原始值
cbar = plt.colorbar(ticks=np.arange(len(value_to_id)))
id_to_value = {v:k for k,v in value_to_id.items()}
cbar.ax.set_yticklabels([str(id_to_value[i]) for i in range(len(value_to_id))])

plt.show()

关键提醒

  • 子数组的转换逻辑可按需调整:如果子数组代表取值范围,也可以用均值、中位数替代唯一ID,只要保证最终是单值即可。
  • 若坐标是不规则分布,需先确定x、y轴的最大最小值,创建对应尺寸的空网格后再填充值。

内容的提问来源于stack exchange,提问作者MatMad-B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:12:54