如何在Altair图表中使用Pandas处理并展示航班时长数据?
如何在Altair图表中处理跨日时长数据
你需要制作按人员分组、Y轴展示累计航班时长(hh:mm:ss格式)的柱状图,但直接使用Pandas.Timedelta类型时出现Error: Unrecognized type: "Duration" (18)错误——这是因为Altair不原生支持Timedelta数据类型,需要先转换数据格式再配置图表。
修正后的完整代码
import pandas as pd import altair as alt import streamlit as st # 原始数据 data = pd.DataFrame({ 'Name': ['MARCOS', 'JOE', 'MICHAEL', 'MARCOS', 'MICHAEL', 'MARCOS', 'MARCOS'], 'Flight hours': [ pd.Timedelta(50, 'hours'), pd.Timedelta(30, 'hours'), pd.Timedelta(20, 'hours'), pd.Timedelta(10, 'hours'), pd.Timedelta(70, 'hours'), pd.Timedelta(20, 'hours'), pd.Timedelta(10, 'hours') ] }) # 分组求和并重置索引(将Name从索引转为普通列) data_grouped = data.groupby('Name')[['Flight hours']].sum().reset_index() # 将Timedelta转换为总秒数(Altair支持数值类型) data_grouped['total_seconds'] = data_grouped['Flight hours'].dt.total_seconds() # 创建Altair图表 chart = alt.Chart(data_grouped).mark_bar().encode( x=alt.X('Name:N', title='人员姓名'), y=alt.Y( 'total_seconds:Q', title='累计航班时长', # 自定义Y轴标签,将秒数格式化为hh:mm:ss axis=alt.Axis( labelExpr=""" let hours = floor(datum.value / 3600), minutes = floor((datum.value % 3600) / 60), seconds = datum.value % 60; hours + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds) """ ) ), # 添加tooltip显示格式化后的时长 tooltip=[ alt.Tooltip('Name:N', title='人员'), alt.Tooltip( 'Flight hours', title='累计时长', format='%H:%M:%S' ) ] ).properties( width=600, height=400 ) # 在Streamlit中渲染图表 st.altair_chart(chart)
关键处理步骤
- 修正分组代码的拼写错误,同时重置索引将分组字段转为普通列,确保Altair能识别分组维度
- 将Pandas.Timedelta类型转换为总秒数(数值类型),适配Altair的数据解析要求
- 通过Vega表达式自定义Y轴标签逻辑,将总秒数计算为
hh:mm:ss格式 - 配置Tooltip显示格式化后的时长,提升交互时的信息可读性
内容的提问来源于stack exchange,提问作者Marcos Vinicius
相关产品推荐
相关产品推荐

