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

Altair中基于日期转换列的选择器无法显示图表对象求助

问题描述

使用Altair基于一战轰炸事件CSV制作可视化,目标实现两个筛选图表:点击时间图表(bombing_over_time)中的事件后,分别展示同年、同月的所有轰炸事件。已从MSNDATE列提取month和year(int64类型),数据集头部如下:

# the head of the dataset
 month  year  
   10  1917  
   10  1917  
   10  1917  
   10  1917  
   10  1917  

转换及图表代码如下:

df_filtered.loc[:, 'month'] = pd.to_datetime(df_filtered['MSNDATE'], format='%M').dt.month.astype(int)
df_filtered.loc[:, 'year'] = pd.to_datetime(df_filtered['MSNDATE'], format='%Y').dt.year.astype(int)

year_selection = alt.selection_point(fields=['year'], nearest=True, on='click')
month_selection = alt.selection_point(fields=['month'], nearest=True, on='click')

# 同年事件图表
same_year_incidents = alt.Chart(df_filtered, title='Incidents in the same year').mark_circle(opacity=op_var).encode(
    alt.X('WEAPONWEIGHT', axis=alt.Axis(title='Weapon weight')),
    alt.Y('BOMBLOAD', axis=alt.Axis(title='Bombload'), scale=alt.Scale(nice=10, zero=False, padding=1)),  
    color = attackercolor,
    size = alt.value(150),
    tooltip = ["COUNTRY", "TGTCOUNTRY", 'MSNDATE:T', 'WEAPONWEIGHT', 'BOMBLOAD']
).transform_filter(
    year_selection
).add_params(
    op_var, brush
).interactive().properties(height=200, width=650)

# 同月事件图表
same_month_incidents = alt.Chart(df_filtered, title='Incidents in the same month').mark_circle(opacity=op_var).encode(
    alt.X('WEAPONWEIGHT', axis=alt.Axis(title='Weapon weight')),
    alt.Y('BOMBLOAD', axis=alt.Axis(title='Bombload'), scale=alt.Scale(nice=10, zero=False, padding=1)),  
    color = attackercolor,
    size = alt.value(150),
    tooltip = ["COUNTRY", "TGTCOUNTRY", 'MSNDATE:T', 'WEAPONWEIGHT', 'BOMBLOAD']
).transform_filter(
    month_selection
).add_params(
    op_var, brush
).properties(height=200, width=650)

初始运行图表显示正常,但点击bombing_over_time图表中的事件(如MSNDATE为14/9/1918的条目)后,两个筛选图表无任何内容显示。


问题原因分析
  1. 日期转换格式错误
    代码中用format='%M'解析MSNDATE完全错误:%M代表分钟而非月份;format='%Y'仅解析年份部分,无法处理14/9/1918这类完整日期字符串,导致month和year列提取的值与实际日期不符,后续筛选自然匹配不到数据。

  2. 选择器未关联时间图表
    当前定义的year_selection和month_selection是独立选择器,未绑定到bombing_over_time图表的点击事件。点击时间图表时,这两个选择器无法获取对应年份/月份值,导致筛选条件为空,图表无数据显示。


修复方案

1. 修正日期转换代码

假设MSNDATE格式为日/月/年(如14/9/1918),用正确格式解析日期后提取月份和年份:

# 解析完整日期,格式需匹配你的实际日期格式
df_filtered['MSNDATE'] = pd.to_datetime(df_filtered['MSNDATE'], format='%d/%m/%Y')
# 提取月份和年份
df_filtered['month'] = df_filtered['MSNDATE'].dt.month.astype(int)
df_filtered['year'] = df_filtered['MSNDATE'].dt.year.astype(int)

若日期格式为月/日/年,需将format改为%m/%d/%Y。

2. 统一选择器并关联时间图表

在bombing_over_time图表中定义一个选择器,同时获取点击事件的year和month值,再在两个筛选图表中分别过滤:

# 定义选择器,绑定到时间图表的点击事件
date_selection = alt.selection_point(fields=['year', 'month'], nearest=True, on='click')

# 同年事件图表:仅匹配年份
same_year_incidents = alt.Chart(df_filtered, title='Incidents in the same year').mark_circle(opacity=op_var).encode(
    alt.X('WEAPONWEIGHT', axis=alt.Axis(title='Weapon weight')),
    alt.Y('BOMBLOAD', axis=alt.Axis(title='Bombload'), scale=alt.Scale(nice=10, zero=False, padding=1)),  
    color=attackercolor,
    size=alt.value(150),
    tooltip=["COUNTRY", "TGTCOUNTRY", 'MSNDATE:T', 'WEAPONWEIGHT', 'BOMBLOAD']
).transform_filter(
    alt.datum.year == date_selection.year
).add_params(
    op_var, brush
).interactive().properties(height=200, width=650)

# 同月事件图表:同时匹配年份和月份(避免不同年份同月混淆)
same_month_incidents = alt.Chart(df_filtered, title='Incidents in the same month').mark_circle(opacity=op_var).encode(
    alt.X('WEAPONWEIGHT', axis=alt.Axis(title='Weapon weight')),
    alt.Y('BOMBLOAD', axis=alt.Axis(title='Bombload'), scale=alt.Scale(nice=10, zero=False, padding=1)),  
    color=attackercolor,
    size=alt.value(150),
    tooltip=["COUNTRY", "TGTCOUNTRY", 'MSNDATE:T', 'WEAPONWEIGHT', 'BOMBLOAD']
).transform_filter(
    (alt.datum.year == date_selection.year) & (alt.datum.month == date_selection.month)
).add_params(
    op_var, brush
).properties(height=200, width=650)

# 在时间图表中绑定选择器
bombing_over_time = alt.Chart(df_filtered, title='Bombing Over Time').mark_point().encode(
    x='MSNDATE:T',
    # 其他编码字段
).add_params(date_selection)

3. 验证数据正确性

运行代码前先检查month和year列是否正确:

print(df_filtered[['MSNDATE', 'month', 'year']].head())

确保提取的月份和年份与原始MSNDATE一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:07:48