如何为Seaborn displot指定日期分组范围

4

问题陈述

我正在创建从1870年开始的每N年洪水事件分布图。我正在使用Pandas和Seaborn。我需要帮助来解决以下问题:

  1. 当使用sns.displot时,指定每个bin的日期范围。
  2. 清晰地在x轴上表示我的bin大小规格。

为了澄清这个问题,这里是我正在使用的数据、我尝试过的方法以及所需输出的描述。

数据

我正在使用的数据可从美国气象服务处获取。

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)

有效方法

我可以使用Seaborn的displot绘制数据,并且可以使用bins命令来调整直方图中的柱子数量。

第二张图片更接近我想要的结果,但是我认为柱子的起始和结束位置不够清晰。例如,从左到右阅读的前两个柱明显在1880年之前开始并在之后结束,但具体的年份不清楚。

import seaborn as sns
# fig. 1: data distribution using default bin parameters
sns.displot(data=tcdf,x="Date")
# fig. 2: data distribution using 40 bins
sns.displot(data=tcdf,x="Date",bins=40)

出现的问题

我尝试使用 bins 参数指定日期范围,但是失败了。这种方法与之前的一个stackoverflow帖子有些相似。

使用默认bin参数的数据分布 在此输入图片描述

my_bins = pd.date_range(start='1870',end='2025',freq='5YS')
sns.displot(data=tcdf,x="Date",bins=my_bins)

然而,这次尝试却产生了一个 TypeError 错误。

TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

这是一个比较长的问题,可能需要一些澄清。请在评论中随时提问,谢谢。

1
使用pandas.cut创建区间,然后将其绘制在x轴上。请参阅Pandas如何使用pd.cut() - Trenton McKinney
@TrentonMcKinney,我会尝试并回报结果。 - Juancheeto
1个回答

5
Seaborn内部将其输入数据转换为数字,以便可以对它们进行数学计算,并使用matplotlib的"单位转换"机制来完成此操作。因此,传递可正常工作的bins的最简单方法是使用matplotlib的日期转换器:
sns.displot(data=tcdf, x="Date", bins=mpl.dates.date2num(my_bins))

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接