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

使用Altair与Pandas关联MoMA两类特定数据实现热力图可视化

实现方法

你当前的预处理逻辑存在关联键缺失的问题:处理作品表时仅保留了Date字段且将Date设为索引,缺少两表关联必需的Artist ID字段,无法完成艺术家性别与作品时间的匹配。按以下步骤即可完成数据合并与热力图绘制:

1. 数据清洗、分箱与关联合并

首先需要修正预处理逻辑,统一两表的Artist ID格式,清洗非结构化的日期字段,按合适的时间粒度分箱后完成表关联,参考代码如下:

import pandas as pd
import altair as alt
import re

# 配置Altair解除大数据量行数限制
alt.data_transformers.enable('default', max_rows=None)

# 读取并清洗艺术家维度表
df_artists = pd.read_csv('artists.csv')
df_artists = df_artists.astype({'Artist ID': 'string'})
# 统一性别字段格式,缺失值标记为unknown
df_artists['Gender'] = df_artists['Gender'].str.lower().fillna('unknown')
df_artists = df_artists[['Artist ID', 'Gender']]

# 读取作品维度表
df_artworks = pd.read_csv('artworks.csv')
df_artworks = df_artworks.astype({'Artist ID': 'string'})

# 清洗日期字段:从非结构化的Date文本中提取有效创作年份
def extract_year(date_str):
    if pd.isna(date_str):
        return None
    # 匹配1800-2025范围内的第一个4位年份,过滤无关数字
    year_match = re.search(r'(18\d{2}|19\d{2}|20[0-2]\d)', str(date_str))
    return int(year_match.group()) if year_match else None

df_artworks['Year'] = df_artworks['Date'].apply(extract_year)
# 剔除年份无效的记录
df_artworks = df_artworks.dropna(subset=['Year'])
df_artworks['Year'] = df_artworks['Year'].astype(int)

# 按10年为粒度做时间分箱,避免单年份数据过散导致热力图可读性差
df_artworks['Decade'] = (df_artworks['Year'] // 10 * 10).astype(str) + 's'

# 通过Artist ID关联合并两张表
df_merged = pd.merge(
    df_artworks[['Artist ID', 'Decade']],
    df_artists,
    on='Artist ID',
    how='left'
)
df_merged['Gender'] = df_merged['Gender'].fillna('unknown')

# 聚合得到每个年代、每种性别对应的作品数量,用于绘图
df_plot = df_merged.groupby(['Decade', 'Gender']).size().reset_index(name='Count')

2. Altair热力图绘制

聚合完成的数据可直接传入Altair绘制热力图,额外添加数值标签可以提升图表可读性,参考代码如下:

# 绘制热力图矩形块
heatmap = alt.Chart(df_plot).mark_rect().encode(
    x=alt.X('Decade:O', title='创作年代', sort='ascending'),
    y=alt.Y('Gender:N', title='艺术家性别', sort=['male', 'female', 'other', 'unknown']),
    color=alt.Color('Count:Q', title='作品数量', scale=alt.Scale(scheme='blues')),
    tooltip=['Decade', 'Gender', 'Count']
).properties(
    title='MoMA馆藏不同年代作品的艺术家性别分布',
    width=800,
    height=300
)

# 添加单元格数值标签,根据色块深浅自动切换文字颜色
text_labels = heatmap.mark_text(baseline='middle').encode(
    text='Count:Q',
    color=alt.condition(
        alt.datum.Count > df_plot['Count'].quantile(0.7),
        alt.value('white'),
        alt.value('black')
    )
)

# 合并图层输出图表
final_chart = heatmap + text_labels
final_chart.show()

可按需调整的配置项

  • 时间分箱粒度:可以根据展示需求修改为5年、20年间隔,若数据量较小也可以直接用单年份统计
  • 数据过滤:如果不需要统计未明确标注性别的记录,可以提前过滤Gender为unknown的行
  • 视觉样式:可以替换热力图色卡(如oranges/purples)、调整图表宽高、修改坐标轴排序规则
  • 统计维度:如果需要统计去重后的艺术家数量而非作品数量,可以在聚合步骤替换为nunique('Artist ID')统计

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:09:25