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

如何为Seaborn displot指定日期分箱范围并清晰展示分箱

解决Seaborn displot日期分箱及轴标签问题

需求

  • 使用sns.displot指定每N年的日期分箱范围
  • 在x轴清晰展示分箱的年份规格

数据处理代码

import pandas as pd
import bs4
import urllib.request
link = "https://water.weather.gov/ahps2/crests.php?wfo=jan&gage=jacm6&crest_type=historic"

webpage=str(urllib.request.urlopen(link).read())
soup = bs4.BeautifulSoup(webpage)

tbl = soup.find('div', class_='water_information')
vals = tbl.get_text().split(r'\n')

tcdf = pd.Series(vals).str.extractall(r'\((?P<Rank>\d+)\)\s(?P<Stage>\d+.\d+)\sft\son\s(?P<Date>\d{2}\/\d{2}\/\d{4})')\
    .reset_index(drop=True)

tcdf['Stage'] = tcdf.Stage.astype(float)
total_crests_events = len(tcdf)
tcdf['Rank'] = tcdf.Rank.astype(int)
tcdf['Date'] = pd.to_datetime(tcdf.Date)

问题分析

直接传入pd.date_range生成的日期数组作为bins参数会触发TypeError,原因是Seaborn底层会将日期转换为浮点型时间戳,而datetime64类型的数组无法直接安全转换为float64。

解决方法

1. 转换分箱为数值格式

将日期分箱转换为对应的时间戳数值,再传入bins参数:

import seaborn as sns

# 生成5年间隔的分箱(起始年份1870,结束2025)
my_bins = pd.date_range(start='1870', end='2025', freq='5YS')
# 将日期转换为Seaborn可识别的数值型时间戳
numeric_bins = my_bins.view('int64')  # 转换为纳秒级时间戳数值

# 绘制分布图
g = sns.displot(data=tcdf, x="Date", bins=numeric_bins)

2. 优化x轴分箱显示

通过设置刻度和标签,清晰展示分箱的年份:

# 设置x轴刻度为分箱的起始日期对应的数值
g.set_xticks(numeric_bins)
# 将刻度标签格式化为年份,旋转45度避免重叠
g.set_xticklabels(my_bins.strftime('%Y'), rotation=45)
# 可选:添加x轴标题
g.set_xlabels('年份区间')

完整代码示例

import seaborn as sns
import pandas as pd

# 生成分箱并转换为数值
my_bins = pd.date_range(start='1870', end='2025', freq='5YS')
numeric_bins = my_bins.view('int64')

# 绘图并设置轴标签
g = sns.displot(data=tcdf, x="Date", bins=numeric_bins, kde=False)
g.set_xticks(numeric_bins)
g.set_xticklabels(my_bins.strftime('%Y'), rotation=45)
g.set_xlabels('年份')
g.set_ylabels('洪水事件数量')
g.fig.suptitle('每5年洪水事件分布', y=1.02)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:01:20