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

在Colab中使用Altair绘制日均温图时的截断异常问题

解决Altair绘制全球温度图时365天处的截断异常

我尝试用Altair复刻Climate Reanalyzer网站的全球温度图,数据加载流程如下:

import pandas as pd
import altair as alt
import json
import requests  # 补充原代码缺失的导入

url = "https://climatereanalyzer.org/clim/t2_daily/json/era5_world_t2_day.json"
data = requests.get(url).json()

years = []
all_temperatures = []
for year_data in data:
    year = year_data['name']
    temperatures = year_data['data']
    temperatures = [temp if temp is not None else float('nan') for temp in temperatures]
    days = list(range(1, len(temperatures) + 1))
    
    df = pd.DataFrame({
        'Year': [year] * len(temperatures),
        'Day': days,
        'Temperature': temperatures
    })
    
    years.append(year)
    all_temperatures.append(df)

df_all = pd.concat(all_temperatures)

绘图时遇到365天处的截断异常:多条曲线在年末突然向x轴365位置聚拢,形成明显的异常痕迹。当前绘图代码如下:

alt.data_transformers.enable('default', max_rows=None)
chart = alt.Chart(df_all).mark_line().encode(
    x=alt.X(
        'Day:Q', 
        title='Day of the Year', 
        scale=alt.Scale(domain=(0, 365), clamp=True)),
    y=alt.Y(
        'Temperature:Q', 
        title='Temperature (°C)', 
        scale=alt.Scale(domain=(11, 18), clamp=True)),
).properties(
    title='Daily World Temperatures',
    width=600,
    height=600
).encode(
    color=alt.Color(
        'Year:N', 
        legend=alt.Legend(
            orient='bottom', 
            columns=10, 
            symbolLimit=100
        )
    ),
)

chart

问题原因

异常源于闰年数据的处理冲突:部分年份是闰年,包含366天的数据,但x轴被设置为domain=(0,365)且开启了clamp=True,这会将所有超过365的天数强制映射到365的位置,导致闰年第366天的温度点全部叠加在x=365处,形成线条聚拢的异常。

解决方案

方案1:扩展x轴范围容纳闰年数据

调整x轴的domain为(0,366),让闰年的366天数据正常显示,避免截断:

alt.data_transformers.enable('default', max_rows=None)
chart = alt.Chart(df_all).mark_line().encode(
    x=alt.X(
        'Day:Q', 
        title='Day of the Year', 
        scale=alt.Scale(domain=(0, 366), clamp=True),  # 修改domain范围
        axis=alt.Axis(values=list(range(0, 367, 30)))  # 可选:设置刻度间隔,避免过密
    ),
    y=alt.Y(
        'Temperature:Q', 
        title='Temperature (°C)', 
        scale=alt.Scale(domain=(11, 18), clamp=True)),
    color=alt.Color(
        'Year:N', 
        legend=alt.Legend(
            orient='bottom', 
            columns=10, 
            symbolLimit=100
        )
    ),
).properties(
    title='Daily World Temperatures',
    width=600,
    height=600
)

chart

方案2:预处理数据移除闰年第366天

如果不需要保留闰年最后一天的数据,可以在数据加载阶段过滤掉:

# 在生成days和temperatures后添加过滤逻辑
# 只保留前365天的数据
temperatures = temperatures[:365]
days = days[:365]

修改后再执行后续的DataFrame创建,这样所有年份都统一为365天,x轴设置(0,365)就不会有截断问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:43:16