如何按脊线最大高度/面积降序排序Altair山脊线图?
如何按脊线大小降序排列Altair山脊线图
当然可行,你不需要在Y轴上做排序操作——问题出在你选错了排序的位置。正确的做法是对分面的行(也就是月份)基于每个脊线的最大高度或总面积进行排序,这样既不会扭曲图形,又能实现从上到下由大到小的排列。
修改后的代码示例
import altair as alt from vega_datasets import data source = data.seattle_weather.url step = 20 overlap = 1 alt.Chart(source, height=step).transform_timeunit( Month='month(date)' ).transform_joinaggregate( mean_temp='mean(temp_max)', groupby=['Month'] ).transform_bin( ['bin_max', 'bin_min'], 'temp_max' ).transform_aggregate( value='count()', groupby=['Month', 'mean_temp', 'bin_min', 'bin_max'] ).transform_impute( impute='value', groupby=['Month', 'mean_temp'], key='bin_min', value=0 # 新增:计算每个月份的最大脊线高度 ).transform_aggregate( max_value='max(value)', groupby=['Month', 'mean_temp'] # 将统计值关联回原数据 ).transform_lookup( lookup='Month', from_=alt.LookupData(data='_wrapped', key='Month', fields=['max_value']) ).mark_area( interpolate='monotone', fillOpacity=0.8, stroke='lightgray', strokeWidth=0.5 ).encode( alt.X('bin_min:Q') .bin('binned') .title('每日最高气温(℃)'), alt.Y('value:Q') .axis(None) .scale(range=[step, -step * overlap]), alt.Fill('mean_temp:Q') .legend(None) .scale(domain=[30, 5], scheme='redyellowblue') ).facet( row=alt.Row('Month:T') .title(None) .header(labelAngle=0, labelAlign='left', format='%B') # 基于max_value降序排序分面行 .sort(alt.EncodingSortField(field='max_value', order='descending')) ).properties( title='西雅图天气', bounds='flush' ).configure_facet( spacing=0 ).configure_view( stroke=None ).configure_title( anchor='end' )
关键修改点说明
- 新增
transform_aggregate计算每个月份的max_value(即脊线的最大高度),如果想用总面积排序,把max(value)改成sum(value)即可。 - 通过
transform_lookup把每个月份的统计值关联到所有对应的数据行,确保分面排序时能获取到该字段。 - 在
alt.Row的sort参数中,基于max_value(或sum_value)降序排列,让最大的脊线显示在顶部。
这样修改后,每个脊线的形状完全保留,同时实现了你需要的排序效果。
内容的提问来源于stack exchange,提问作者Stephanie
相关产品推荐
相关产品推荐

