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

关于Altair中mark_text()图层模糊与重复问题的技术咨询

热图叠加文本模糊重复问题解决

我尝试制作带叠加文本的热图,参考Altair官方教程适配示例数据时一切正常,但使用自有数据集运行以下代码后,mark_text()图层出现模糊、重复的情况:

import altair as alt, pandas as pd, numpy as np

quarters = ['2022-Q1', '2022-Q2', '2022-Q3', '2022-Q4', '2023-Q1', '2023-Q2', '2023-Q3', '2023-Q4']
risk_bands = ['A++', 'A+', 'A', 'B', 'C', 'R']
vintages = [2020, 2021, 2022, 2023]

cpr = pd.DataFrame({
    'quarter': np.random.choice(quarters, 1000),
    'GEN5_RISK_BAND_CALC': np.random.choice(risk_bands, 1000),
    'VINTAGE_YEAR': np.random.choice(vintages, 1000),
    'cpr': np.random.randint(0, 40, 1000)
})


base = alt.Chart(cpr).mark_rect().encode(
    x=alt.X('quarter:O', axis=(alt.Axis(labelAngle=45))),
    y='VINTAGE_YEAR:O',
)

heatmap = base.mark_rect().encode(
    color=alt.Color(
        'cpr:Q',
        scale=alt.Scale(
            range=['white', 'red'],
            ),
        legend=alt.Legend(direction='vertical', orient='left', title='cpr')
    ),
)

text = base.mark_text(
    baseline='middle',
    dx=0,

).encode(
    text='cpr',
    tooltip=[]
)

chart = alt.layer(base + heatmap + text).facet(
    'GEN5_RISK_BAND_CALC:N', 
    columns=2
)

chart

运行后效果如图:
运行效果

问题原因

原始数据中,每个热图单元格(由quarter、VINTAGE_YEAR、GEN5_RISK_BAND_CALC共同确定)对应多条记录,文本图层会将每条记录的cpr值都绘制在同一位置,导致文字重叠、模糊。

解决方法

先对数据按热图的分组维度进行聚合,得到每个单元格的唯一统计值(示例中取均值,可根据需求替换为求和、中位数等),再基于聚合后的数据绘图:

import altair as alt, pandas as pd, numpy as np

quarters = ['2022-Q1', '2022-Q2', '2022-Q3', '2022-Q4', '2023-Q1', '2023-Q2', '2023-Q3', '2023-Q4']
risk_bands = ['A++', 'A+', 'A', 'B', 'C', 'R']
vintages = [2020, 2021, 2022, 2023]

cpr = pd.DataFrame({
    'quarter': np.random.choice(quarters, 1000),
    'GEN5_RISK_BAND_CALC': np.random.choice(risk_bands, 1000),
    'VINTAGE_YEAR': np.random.choice(vintages, 1000),
    'cpr': np.random.randint(0, 40, 1000)
})

# 按分组维度聚合,计算每个单元格的cpr均值
cpr_agg = cpr.groupby(['quarter', 'VINTAGE_YEAR', 'GEN5_RISK_BAND_CALC'])['cpr'].mean().reset_index()
# 可选:将均值取整,让文本更整洁
cpr_agg['cpr'] = cpr_agg['cpr'].round(0).astype(int)

base = alt.Chart(cpr_agg).mark_rect().encode(
    x=alt.X('quarter:O', axis=(alt.Axis(labelAngle=45))),
    y='VINTAGE_YEAR:O',
)

heatmap = base.mark_rect().encode(
    color=alt.Color(
        'cpr:Q',
        scale=alt.Scale(
            range=['white', 'red'],
            ),
        legend=alt.Legend(direction='vertical', orient='left', title='cpr')
    ),
)

text = base.mark_text(
    baseline='middle',
    dx=0,
    color='black'  # 可选:设置文本颜色,与背景区分更明显
).encode(
    text='cpr',
    tooltip=[]
)

chart = alt.layer(heatmap + text).facet(
    'GEN5_RISK_BAND_CALC:N', 
    columns=2
)

chart

额外优化说明

  • 聚合时可根据业务需求选择合适的统计函数(如sum()、median())
  • 可设置文本颜色(如color='black'),让文字与热图背景对比更清晰
  • 移除了冗余的base图层叠加,因为heatmap已经包含了矩形标记

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:12:03