如何用Altair绘制1:8属性的交互式mark_point()图?
解决方案
要在单张Altair散点图中展示8个属性的购买计数,并添加Region和Channel的交互筛选,核心是把宽格式DataFrame转换为长格式(tidy data),这是Altair处理多类别数据的标准方式。以下是完整实现步骤:
1. 数据准备与重塑
首先加载数据集,然后用pandas.melt()将多个数值列(Fresh、Frozen等)合并为一个类别列和对应的值列,这样就能把所有属性映射到同一个X轴:
import pandas as pd import altair as alt # 加载数据集 df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/00292/Wholesale%20customers%20data.csv') # 重塑数据:将8个属性转为类别+值的长格式 # id_vars保留用于筛选的列,var_name是类别列名,value_name是购买金额列名 melted_df = df.melt( id_vars=['Channel', 'Region'], var_name='Product_Category', value_name='Purchase_Amount' )
2. 创建交互筛选组件
添加基于Region和Channel的下拉选择器,用于动态过滤数据:
# Region筛选器 region_select = alt.selection_point( fields=['Region'], bind=alt.binding_select( options=df['Region'].unique(), name='Region Filter: ' ) ) # Channel筛选器 channel_select = alt.selection_point( fields=['Channel'], bind=alt.binding_select( options=df['Channel'].unique(), name='Channel Filter: ' ) )
3. 绘制交互式散点图
将重塑后的数据传入Altair,映射X轴为产品类别,Y轴为计数,同时绑定筛选器:
chart = alt.Chart(melted_df).mark_point(size=100).encode( x=alt.X('Product_Category:N', title='Product Category'), y=alt.Y('count():Q', title='Number of Customers'), color=alt.Color('Product_Category:N', legend=alt.Legend(title='Categories')), tooltip=[ alt.Tooltip('Product_Category:N', title='Category'), alt.Tooltip('count():Q', title='Customer Count'), alt.Tooltip('mean(Purchase_Amount):Q', title='Avg Purchase', format='$.2f'), alt.Tooltip('max(Purchase_Amount):Q', title='Max Purchase', format='$.2f') ] ).add_params( region_select, channel_select ).transform_filter( # 同时应用两个筛选器 region_select & channel_select ).properties( title='Customer Purchase Distribution by Product Category', width=700, height=450 ).configure_title( fontSize=16, anchor='middle' ) # 显示图表 chart
关键说明
- 之前用字典转换失败的原因:Altair依赖Vega-Lite的语法,更适合处理长格式数据——宽格式的多列无法直接映射到同一个X轴的不同类别,
melt()是解决这类问题的标准方法。 - 交互逻辑:两个筛选器是“与”关系,只有同时满足Region和Channel条件的数据才会被展示。
- 增强体验:添加了tooltip显示额外统计信息(平均/最大购买金额),让图表信息更丰富。
内容的提问来源于stack exchange,提问作者Tanmay Mittal
相关产品推荐
相关产品推荐

