简体   繁体   English

如何为 Seaborn displot 指定日期 bin 范围

[英]How to specify date bin ranges for Seaborn displot

Problem statement问题陈述

I am creating a distribution plot of flood events per N year periods starting in 1870. I am using Pandas and Seaborn.我正在创建从 1870 年开始的每N年期间洪水事件的分布 plot。我正在使用 Pandas 和 Seaborn。 I need help with...我需要帮助...

  1. specifying the date range of each bin when usingsns.displot , and使用sns.displot时指定每个 bin 的日期范围,以及
  2. clearly representing my bin size specifications along the x axis.清楚地代表我沿x轴的 bin 大小规格。

To clarify this problem, here is the data that I am working with, what I have tried, and a description of the desired output.为了澄清这个问题,这里是我正在使用的数据、我尝试过的数据以及对所需 output 的描述。

The Data数据

The data I am using is available from the US Weather service.我使用的数据可从美国气象服务获得。

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)

What works什么有效

I am able to plot the data with Seaborn's displot , and I can manipulate the number of bins with the bins command.我可以使用 Seaborn 的displot对数据进行 plot 处理,并且可以使用bins命令来操作 bin 的数量。

The second image is closer to my desired output.第二张图片更接近我想要的 output。 However, I do not think that it's clear where the bins start and end.但是,我认为垃圾箱的开始和结束位置并不明确。 For example, the first two bins (reading left to right) clearly start before and end after 1880, but the precise years are not clear.例如,前两个分档(从左到右阅读)清楚地开始于 1880 年之前和结束于 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)

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

What fails什么失败了

I tried specifying date ranges using the bins input.我尝试使用bins输入指定日期范围。 The approach is loosely based on a previous SO thread .该方法松散地基于先前的 SO 线程

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

This attempt, however, produced a TypeError但是,这种尝试产生了 TypeError

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

This is a long question, so I imagine that some clarification might be necessary.这是一个很长的问题,所以我想可能有必要进行一些澄清。 Please do not hesitate to ask questions in the comments.请不要犹豫,在评论中提问。

Thanks in advance.提前致谢。

Seaborn internally converts its input data to numbers so that it can do math on them, and it uses matplotlib's "unit conversion" machinery to do that. Seaborn 在内部将其输入数据转换为数字,以便对其进行数学运算,并使用 matplotlib 的“单位转换”机制来做到这一点。 So the easiest way to pass bins that will work is to use matplotlib's date converter:因此,传递有效的 bin 的最简单方法是使用 matplotlib 的日期转换器:

sns.displot(data=tcdf, x="Date", bins=mpl.dates.date2num(my_bins))

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM