You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python绘制兼具分类色彩与连续透明度的热力图

如何用Python绘制兼具分类色彩与连续透明度的热力图

嘿,这个需求我刚好折腾过,其实不用搞你想的那种复杂自定义色卡,直接用matplotlib的基础绘图功能就能轻松实现,每个单元格单独设置颜色和透明度,思路超直接!

核心逻辑很简单:seaborn的heatmap是基于单一数值映射色卡的,没法同时独立控制颜色和透明度这两个维度。那我们换个思路——手动给每个单元格画矩形,这样每个矩形都能单独指定facecolor(填充色)和alpha(透明度),完美匹配你的需求。

直接上可运行的完整代码,我给你加了详细注释:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# 你的示例数据
colors = pd.DataFrame([['b','g','r'],['black','orange','purple'],['r','yellow','white']])
transparency = pd.DataFrame([[0.1,0.2,0.3],[0.9,0.1,0.2],[0.1,0.6,0.3]])

# 获取数据的行列数
rows, cols = colors.shape

# 创建画布和绘图轴
fig, ax = plt.subplots(figsize=(6, 4))

# 每个单元格的宽高,这里设为1,你可以根据需求调整
cell_size = 1

# 遍历每一个单元格
for i in range(rows):
    for j in range(cols):
        # 取出当前单元格的颜色和透明度
        current_color = colors.iloc[i, j]
        current_alpha = transparency.iloc[i, j]
        # 计算矩形的位置:matplotlib的y轴默认从下往上递增,所以要反转行索引,保证数据第一行在图的最上方
        x_pos = j * cell_size
        y_pos = (rows - 1 - i) * cell_size
        # 创建矩形对象:设置填充色、透明度,再加个白色边框区分单元格
        rect = Rectangle((x_pos, y_pos), cell_size, cell_size, 
                         facecolor=current_color, alpha=current_alpha, edgecolor='white')
        # 把矩形添加到绘图轴上
        ax.add_patch(rect)

# 设置坐标轴的范围,刚好覆盖所有单元格
ax.set_xlim(0, cols * cell_size)
ax.set_ylim(0, rows * cell_size)

# 设置刻度,让刻度标签显示在每个单元格的中间位置
ax.set_xticks([j * cell_size + cell_size/2 for j in range(cols)])
ax.set_yticks([(rows - 1 - i) * cell_size + cell_size/2 for i in range(rows)])
ax.set_xticklabels(colors.columns)
ax.set_yticklabels(colors.index)

# 调整刻度的位置,避免和单元格重叠
ax.tick_params(axis='both', which='major', pad=15)

# 可选:添加颜色图例,方便查看每个分类对应的颜色
unique_colors = colors.stack().unique()
color_legend_patches = [Rectangle((0,0), 1, 1, facecolor=color) for color in unique_colors]
ax.legend(color_legend_patches, unique_colors, bbox_to_anchor=(1.05, 1), 
          loc='upper left', title='颜色')

# 自动调整布局,防止图例或刻度被截断
plt.tight_layout()
plt.show()

这里有几个关键点要跟你说清楚:

  • alpha参数刚好是0到1的范围,和你的transparency数据完全匹配——1是完全不透明,0是完全透明,完全符合你要的“10%透明度”这种需求;
  • 矩形位置的计算:因为matplotlib的y轴默认是从下往上数的,而你的数据第一行要显示在图的最上面,所以用rows - 1 - i反转了行索引,保证每个单元格的位置和你数据里的位置完全对应;
  • 我给每个单元格加了白色边框edgecolor='white',这样不同单元格之间区分度更高,你要是觉得没必要可以直接删掉这个参数。

这个方法比你之前想的自定义色卡简单太多了,完全不需要把颜色转成整数再混合,每个单元格单独控制属性,想改哪个改哪个,灵活得很!

备注:内容来源于stack exchange,提问作者andbeonetraveler

火山引擎 最新活动