#!/usr/bin/env python # coding: utf-8 # # [海洋要素计算 编程作业5](#toc0_) # # # - 1. 画出波面高度时间序列,利用上跨零点或者下跨零点的方法读取数据资料中的波高、周期等波浪要素,并画图展示。 # - 2. 画出波高的概率密度分布,并计算给出有效波高和有效波周期 # # 数据: # - data.txt # - 一维海浪时间序列,共2048个数据,总时间长度为512s,时间间隔0.25s,数据单位为米(m) # # **Developed By [Hanxue Yu](https://github.com/Yuhan-xue) 02\06\2023** # **Student ID: 20010006082** # **Table of contents** # - [海洋要素计算 编程作业5](#toc1_) # # # # In[24]: import numpy as np import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt from scipy.stats import gaussian_kde from statsmodels.tsa.stattools import adfuller from mpl_toolkits.axes_grid1 import make_axes_locatable import seaborn as sns mpl.rcParams['font.sans-serif'] = ['LXGW Bright'] # 字体下载 https://github.com/lxgw/LxgwBright mpl.rcParams['axes.unicode_minus'] = False import sys print(sys.version) get_ipython().system('pip list | grep numpy') get_ipython().system('pip list | grep pandas') get_ipython().system('pip list | grep matplotlib') get_ipython().system('pip list | grep scipy') get_ipython().system('pip list | grep statsmodels') get_ipython().system('pip list | grep seaborn') # In[25]: def readt(t): return float(t.split('\n')[0]) with open('data.txt','r') as f: data=np.array(list(map(readt,f.readlines()))) f.close();del f time=np.arange(0,data.shape[0]/4,0.25) plt.figure(figsize=(15,3),dpi=300) plt.title('Origin Data') plt.plot(time,data) plt.xlim(time[0],time[-1]) plt.xlabel('Time (s)');plt.ylabel('height (m)') plt.axhline(y=0, color='r', linestyle='--') plt.grid() plt.show() # In[26]: # 对数据进行差分并进行平稳性检验 diff_data = np.diff(data) adftest = adfuller(diff_data) print('ADF检验的p值为:', adftest[1])#如果p值小于0.05,则拒绝原假设,即序列平稳 # 拟合一次线性趋势,得到趋势项 X = time Y = data coefficients = np.polyfit(X, Y, 1) trend = X * coefficients[0] + coefficients[1] detrend=data-trend # 对数据进行差分并进行平稳性检验 diff_data_without_trend = diff_data - X[:-1] * coefficients[0] adftest = adfuller(diff_data_without_trend) print('去掉趋势项后的ADF检验的p值为:', adftest[1])#如果p值小于0.05,则拒绝原假设,即序列平稳 # 合并为Pandas DataFrame并计算均线 df=pd.DataFrame(index=time,columns=['or'],data=data) df['detrend']=detrend df['ma'] = df['detrend'].rolling(window=5).mean() # 可视化 plt.figure(figsize=(15,10),dpi=300) plt.subplot(5,1,(1,2)) plt.plot(time,df['or'], label='original data',c='#b7282e') plt.plot(time,df['detrend'], label='detrend data',c='#918754') plt.legend() plt.axhline(y=0, color='r', linestyle='--') plt.xlim(time[0],time[-1]) plt.xticks(np.arange(0,501,100),[]) plt.ylabel('height (m)') plt.grid() plt.subplot(5,1,3) plt.plot(time,trend, label='trend',c='#c9171e') plt.legend() plt.xlim(time[0],time[-1]);plt.xticks(np.arange(0,501,100),[]) plt.ylabel('height (m)') plt.grid() plt.subplot(5,1,(4,5)) plt.plot(time,df['detrend'], label='detrend data',c='#b7282e') plt.plot(time,df['ma'], label='moving average',c='#918754') plt.legend() plt.xlim(time[0],time[-1]) plt.xlabel('Time (s)');plt.ylabel('height (m)') plt.axhline(y=0, color='k', linestyle='--') plt.grid() plt.show() del X,Y,diff_data,diff_data_without_trend,coefficients,adftest,trend # In[27]: up_zero_crossings = np.where(np.diff(np.sign(df['ma'])) > 0)[0]+1 dow_zero_crossings = np.where(np.diff(np.sign(df['ma'])) < 0)[0]+1 plt.figure(figsize=(17,3),dpi=300) plt.plot(time,df['ma'], label='moving average',c='#895b8a',linewidth=0.7) plt.scatter(time[up_zero_crossings],df['ma'][time[up_zero_crossings]],c='#b7282e',label='up_zero crossings',s=10) plt.scatter(time[dow_zero_crossings],df['ma'][time[dow_zero_crossings]],c='#918754',label='down_zero crossings',s=10) plt.legend() plt.xlim(time[0],time[-1]) plt.xlabel('Time (s)');plt.ylabel('height (m)') plt.axhline(y=0, color='r', linestyle='--') plt.grid() plt.show() # In[36]: def cal_H(arr, indices): dists = [arr[indices[i]:indices[i+1]] for i in range(len(indices)-1)] return np.array([np.max(dist) - np.min(dist) for dist in dists]) def cal_T(arr, indices): dists = [arr[indices[i+1]]-arr[indices[i]] for i in range(len(indices)-1)] return np.array(dists) def sort(A, B): sorted_indices = np.argsort(A)[::-1] sorted_A = A[sorted_indices] sorted_B = B[sorted_indices] return sorted_A, sorted_B def average_of_top_percent(arr, percent): if not 0 < percent < 1: raise ValueError("Input percent must be between 0 and 1 exclusive.") arr = sorted(arr) top_num = int(percent * len(arr)) top_arr = arr[-top_num:] return sum(top_arr) / top_num if top_num > 0 else 0 H=cal_H(np.array(df['ma']),up_zero_crossings) T=cal_T(time,up_zero_crossings) H_sort,T_sort = sort(H,T) print(f'上跨零点法 1/10大波平均波高(显著波高):{average_of_top_percent(H_sort,0.1):.3f}m',end='') print(f' 对应周期为:{average_of_top_percent(T_sort,0.1):.3f}s') print(f'上跨零点法 1/3 大波平均波高(有效波高):{average_of_top_percent(H_sort,1/3):.3f}m',end='') print(f' 对应周期为:{average_of_top_percent(T_sort,1/3):.3f}s') x, y = sort(H,T) bi,hi,tmp=plt.hist(T_sort,bins=20,orientation='horizontal') bi2,hi2,tmp=plt.hist(H_sort,bins=40,orientation='horizontal') plt.close() # 创建散点图 plt.figure(figsize=[10,10],dpi=300) plt.suptitle('Kernel Density Estimation (KDE)&Probability Density Distribution [Up Zero Crossings]') ax=plt.gca() # 创建&绘制 KDE 曲线 kde = gaussian_kde(np.vstack([H_sort,T_sort])) Hi, Ti = np.mgrid[H_sort.min():H_sort.max():100j, T_sort.min():T_sort.max():100j] zi = kde(np.vstack([Hi.flatten(), Ti.flatten()])) c=ax.contourf(Hi, Ti, zi.reshape(Hi.shape)*100,40,cmap='rocket') plt.ylabel('Cycle Time [s]') plt.xlabel('Wave Height [m]') ax.scatter(x, y, s=5, color='white', alpha=0.8) tik_x=ax.get_xticks() xlim=ax.get_xlim() divider = make_axes_locatable(ax) ax2 = divider.append_axes("top", size="20%", pad=0, sharex=ax) ax2.bar(hi2[:-1],bi2,width=0.1,color="#03051A") ax2.plot(hi2[:-1],bi2,c='#9e3d3f') ax2.scatter(hi2[:-1],bi2,c='#9e3d3f') ax2.grid(True) ax3 = divider.append_axes("right", size="15%", pad=0, sharex=ax) ax3.barh(hi[:-1],bi/6,color="#03051A") ax3.plot(bi/6,hi[:-1],c='#9e3d3f') ax3.scatter(bi/6,hi[:-1],c='#9e3d3f') ax3.grid(True) #ax3.set_xlim(0,20) ax.set_xlim(xlim) ax2.tick_params(top=True,bottom=True,labeltop=True,labelbottom=False,labelleft=False) ax3.tick_params(right=True,left=True,labelright=True,labelleft=False,labelbottom=False) ax.tick_params(right=True,left=True,top=True,bottom=True) plt.colorbar(c,orientation='horizontal',label='Percent (%)') plt.savefig('result.png') # In[35]: H=cal_H(np.array(df['ma']),dow_zero_crossings) T=cal_T(time,dow_zero_crossings) H_sort,T_sort = sort(H,T) print(f'下跨零点法 1/10大波平均波高(显著波高):{average_of_top_percent(H_sort,0.1):.3f}m',end='') print(f' 对应周期为:{average_of_top_percent(T_sort,0.1):.3f}s') print(f'下跨零点法 1/3 大波平均波高(有效波高):{average_of_top_percent(H_sort,1/3):.3f}m',end='') print(f' 对应周期为:{average_of_top_percent(T_sort,1/3):.3f}s') x, y = sort(H,T) bi,hi,tmp=plt.hist(T_sort,bins=20,orientation='horizontal') bi2,hi2,tmp=plt.hist(H_sort,bins=40,orientation='horizontal') plt.close() # 创建散点图 plt.figure(figsize=[10,10],dpi=300) plt.suptitle('Kernel Density Estimation (KDE)&Probability Density Distribution [Dow Zero Crossings]') ax=plt.gca() # 创建&绘制 KDE 曲线 kde = gaussian_kde(np.vstack([H_sort,T_sort])) Hi, Ti = np.mgrid[H_sort.min():H_sort.max():100j, T_sort.min():T_sort.max():100j] zi = kde(np.vstack([Hi.flatten(), Ti.flatten()])) c=ax.contourf(Hi, Ti, zi.reshape(Hi.shape)*100,40,cmap='rocket') plt.ylabel('Cycle Time [s]') plt.xlabel('Wave Height [m]') ax.scatter(x, y, s=5, color='white', alpha=0.8) tik_x=ax.get_xticks() xlim=ax.get_xlim() divider = make_axes_locatable(ax) ax2 = divider.append_axes("top", size="20%", pad=0, sharex=ax) ax2.bar(hi2[:-1],bi2,width=0.1,color="#03051A") ax2.plot(hi2[:-1],bi2,c='#9e3d3f') ax2.scatter(hi2[:-1],bi2,c='#9e3d3f') ax2.grid(True) ax3 = divider.append_axes("right", size="15%", pad=0, sharex=ax) ax3.barh(hi[:-1],bi/6,color="#03051A") ax3.plot(bi/6,hi[:-1],c='#9e3d3f') ax3.scatter(bi/6,hi[:-1],c='#9e3d3f') ax3.grid(True) #ax3.set_xlim(0,20) ax.set_xlim(xlim) ax2.tick_params(top=True,bottom=True,labeltop=True,labelbottom=False,labelleft=False) ax3.tick_params(right=True,left=True,labelright=True,labelleft=False,labelbottom=False) ax.tick_params(right=True,left=True,top=True,bottom=True) plt.colorbar(c,orientation='horizontal',label='Percent (%)') plt.show() # In[ ]: 3.10.10 | packaged by Anaconda, Inc. | (main, Mar 21 2023, 18:39:17) [MSC v.1916 64 bit (AMD64)] numpy 1.24.3 pandas 1.5.3 matplotlib 3.7.1 matplotlib-inline 0.1.6 scipy 1.10.1 statsmodels 0.13.5 seaborn 0.12.2