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

Altair图表:如何为指定年份子集生成精简图例?

气候温度折线图复刻与图例优化方案

核心需求

  • 将1940-2022年的温度折线设为灰色低透明度,2023年设为红色,2024年设为黑色
  • 图例仅显示三个分组:1940-2022、2023、2024(或可选择仅保留2023和2024)
  • 优化代码结构与运行效率

图例实现核心思路

通过创建分组标签列替代原有的手动颜色/透明度列,让Altair自动基于分组生成精简图例:

  1. 新增LegendGroup列,将年份按需求分为三个类别
  2. 直接在Altair编码中绑定该分组列,指定颜色、透明度、线宽的映射规则
  3. 保留图例显示,自动展示分组标签

代码优化建议

  • 用pandas向量化操作替代apply循环,提升数据处理效率
  • 简化日期标签生成逻辑,避免手动构建字典
  • 修复依赖缺失(补充requests导入)
  • 移除冗余的手动生成列(如Color、Opacity),直接通过Altair编码实现样式映射

完整修改后代码

import pandas as pd
import altair as alt
import requests  # 补充缺失的依赖导入

# 数据获取与预处理
def fetch_and_prep_data():
    url = "https://climatereanalyzer.org/clim/t2_daily/json/era5_world_t2_day.json"
    data = requests.get(url).json()
    
    all_dfs = []
    for year_data in data:
        year = year_data['name']
        # 过滤非4位数字年份
        if len(year) != 4:
            continue
        temperatures = [temp if temp is not None else float('nan') for temp in year_data['data']]
        days = list(range(1, len(temperatures)+1))
        
        df = pd.DataFrame({
            'Year': [int(year)]*len(temperatures),  # 直接转换为整数
            'Day': days,
            'Temperature': temperatures
        })
        all_dfs.append(df)
    
    df_at = pd.concat(all_dfs)
    # 新增分组列,用于图例与样式映射
    df_at['LegendGroup'] = pd.cut(
        df_at['Year'],
        bins=[0, 2022, 2023, 2024],
        labels=['1940-2022', '2023', '2024'],
        include_lowest=True
    )
    # 过滤无效天数
    df_at = df_at[df_at['Day'] <= 365]
    return df_at

# 生成x轴月份标签(每月最后一天的日序与缩写)
def get_month_labels():
    dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
    last_days = dates[dates.is_month_end]
    return last_days.day_of_year.tolist(), last_days.strftime('%b').tolist()

# 主绘图逻辑
df = fetch_and_prep_data()
tick_values, tick_labels = get_month_labels()

line_chart = alt.Chart(df).mark_line().encode(
    x=alt.X(
        'Day:Q',
        title='Month',
        scale=alt.Scale(domain=(0, 365), clamp=True),
        axis=alt.Axis(
            tickCount=12,
            values=tick_values,
            labels=True,
            # 动态匹配标签与刻度值
            labelExpr="indexof(values, datum.value) > -1 ? labels[indexof(values, datum.value)] : ''",
            labelOffset=-30
        )
    ),
    y=alt.Y(
        'Temperature:Q',
        title='Temperature (°C)',
        scale=alt.Scale(domain=(11, 18), clamp=True)
    ),
    # 基于分组列映射颜色,自动生成图例
    color=alt.Color(
        'LegendGroup:N',
        scale=alt.Scale(
            domain=['1940-2022', '2023', '2024'],
            range=['gray', 'red', 'black']
        ),
        title='Year Group'
    ),
    # 分组映射透明度
    opacity=alt.Opacity(
        'LegendGroup:N',
        scale=alt.Scale(
            domain=['1940-2022', '2023', '2024'],
            range=[0.01, 1.0, 1.0]
        ),
        legend=None
    ),
    # 分组映射线宽
    strokeWidth=alt.StrokeWidth(
        'LegendGroup:N',
        scale=alt.Scale(
            domain=['1940-2022', '2023', '2024'],
            range=[1, 4, 4]
        ),
        legend=None
    ),
    # 按年份拆分折线,避免合并
    detail='Year:N'
).properties(
    width=800,
    height=600
)

line_chart

可选:仅保留2023和2024的图例

若需要隐藏1940-2022的图例项,可在颜色编码中添加legend=alt.Legend(values=['2023', '2024']):

color=alt.Color(
    'LegendGroup:N',
    scale=alt.Scale(
        domain=['1940-2022', '2023', '2024'],
        range=['gray', 'red', 'black']
    ),
    title='Year',
    legend=alt.Legend(values=['2023', '2024'])  # 仅显示指定图例项
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:55:53