使用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
相关产品推荐
相关产品推荐

