fix
This commit is contained in:
parent
27a24ba6a8
commit
ceeed5de92
@ -4,6 +4,32 @@ from scipy.optimize import curve_fit
|
|||||||
from scipy.signal import lombscargle, hilbert
|
from scipy.signal import lombscargle, hilbert
|
||||||
from sklearn.decomposition import PCA
|
from sklearn.decomposition import PCA
|
||||||
import sympy as sp
|
import sympy as sp
|
||||||
|
from scipy.interpolate import interp1d
|
||||||
|
from scipy.signal import lombscargle
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
from scipy.optimize import curve_fit
|
||||||
|
import math
|
||||||
|
from sklearn.decomposition import PCA
|
||||||
|
import sympy as sp
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import seaborn as sns
|
||||||
|
from matplotlib.patches import Patch
|
||||||
|
from matplotlib.lines import Line2D
|
||||||
|
from windrose import WindroseAxes
|
||||||
|
from scipy.signal import lombscargle, find_peaks
|
||||||
|
from itertools import permutations
|
||||||
|
from itertools import product
|
||||||
|
|
||||||
|
|
||||||
|
def get_top_peaks(pgram, ff, num_peaks=3):
|
||||||
|
peaks, _ = find_peaks(pgram)
|
||||||
|
peak_values = pgram[peaks]
|
||||||
|
peak_frequencies = ff[peaks]
|
||||||
|
sorted_indices = np.argsort(peak_values)[-num_peaks:][::-1] # 按照峰值从大到小排序
|
||||||
|
top_peaks_frequencies = peak_frequencies[sorted_indices]
|
||||||
|
top_peaks_values = peak_values[sorted_indices]
|
||||||
|
return top_peaks_frequencies, top_peaks_values
|
||||||
|
|
||||||
|
|
||||||
def calculate_n(Av, Au, Bu, Bv):
|
def calculate_n(Av, Au, Bu, Bv):
|
||||||
@ -118,7 +144,10 @@ def calculate_wave(data: pd.DataFrame, lat: float, g: float):
|
|||||||
pgram_ucmp = lombscargle(height, residual_ucmp, ff)
|
pgram_ucmp = lombscargle(height, residual_ucmp, ff)
|
||||||
pgram_vcmp = lombscargle(height, residual_vcmp, ff)
|
pgram_vcmp = lombscargle(height, residual_vcmp, ff)
|
||||||
|
|
||||||
# todo:我的频率等于垂直波数(单位10-3rad/m)?
|
# BEGIN CHANGE
|
||||||
|
|
||||||
|
# BACK
|
||||||
|
# todo: 我的频率等于垂直波数(单位10-3rad/m)?
|
||||||
main_frequency_temp = round(ff[np.argmax(pgram_temp)], 2)
|
main_frequency_temp = round(ff[np.argmax(pgram_temp)], 2)
|
||||||
main_frequency_ucmp = round(ff[np.argmax(pgram_ucmp)], 2)
|
main_frequency_ucmp = round(ff[np.argmax(pgram_ucmp)], 2)
|
||||||
main_frequency_vcmp = round(ff[np.argmax(pgram_vcmp)], 2)
|
main_frequency_vcmp = round(ff[np.argmax(pgram_vcmp)], 2)
|
||||||
@ -132,6 +161,11 @@ def calculate_wave(data: pd.DataFrame, lat: float, g: float):
|
|||||||
rsd_temp = abs(round(((λ1 - mean) / λ1) * 100, 2))
|
rsd_temp = abs(round(((λ1 - mean) / λ1) * 100, 2))
|
||||||
rsd_ucmp = abs(round(((λ2 - mean) / λ2) * 100, 2))
|
rsd_ucmp = abs(round(((λ2 - mean) / λ2) * 100, 2))
|
||||||
rsd_vcmp = abs(round(((λ3 - mean) / λ3) * 100, 2))
|
rsd_vcmp = abs(round(((λ3 - mean) / λ3) * 100, 2))
|
||||||
|
# BACK
|
||||||
|
|
||||||
|
# new
|
||||||
|
|
||||||
|
# END CHANGE
|
||||||
|
|
||||||
if not (rsd_temp < 20 and rsd_ucmp < 20 and rsd_vcmp < 20):
|
if not (rsd_temp < 20 and rsd_ucmp < 20 and rsd_vcmp < 20):
|
||||||
return []
|
return []
|
||||||
|
|||||||
@ -2,9 +2,25 @@ import xarray as xr
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.interpolate import interp1d
|
from scipy.interpolate import interp1d
|
||||||
|
from scipy.signal import lombscargle
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
from scipy.optimize import curve_fit
|
||||||
|
import math
|
||||||
|
from sklearn.decomposition import PCA
|
||||||
|
import sympy as sp
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import seaborn as sns
|
||||||
|
from matplotlib.patches import Patch
|
||||||
|
from matplotlib.lines import Line2D
|
||||||
|
from windrose import WindroseAxes
|
||||||
|
from scipy.signal import lombscargle, find_peaks
|
||||||
|
from itertools import permutations
|
||||||
|
from itertools import product
|
||||||
|
|
||||||
# 定义四舍五入函数
|
# 定义四舍五入函数
|
||||||
|
|
||||||
|
|
||||||
def round_to_nearest_multiple(value, multiple):
|
def round_to_nearest_multiple(value, multiple):
|
||||||
return round(value / multiple) * multiple
|
return round(value / multiple) * multiple
|
||||||
|
|
||||||
@ -24,10 +40,12 @@ def read_data(path):
|
|||||||
|
|
||||||
# 移除重复的高度值
|
# 移除重复的高度值
|
||||||
extracted_df = extracted_df.drop_duplicates(subset=["alt"])
|
extracted_df = extracted_df.drop_duplicates(subset=["alt"])
|
||||||
new_height = np.arange(extracted_df["alt"].min(), extracted_df["alt"].max() + 0.05, 0.05)
|
new_height = np.arange(extracted_df["alt"].min(
|
||||||
|
), extracted_df["alt"].max() + 0.05, 0.05)
|
||||||
|
|
||||||
# 将每个高度值转换为最接近0.05的整数倍,并转化为数组
|
# 将每个高度值转换为最接近0.05的整数倍,并转化为数组
|
||||||
rounded_heights = [round_to_nearest_multiple(height, 0.05) for height in new_height]
|
rounded_heights = [round_to_nearest_multiple(
|
||||||
|
height, 0.05) for height in new_height]
|
||||||
rounded_heights_np = np.array(rounded_heights)
|
rounded_heights_np = np.array(rounded_heights)
|
||||||
|
|
||||||
# 初始化一个新的 DataFrame 用于存储插值结果
|
# 初始化一个新的 DataFrame 用于存储插值结果
|
||||||
@ -35,7 +53,8 @@ def read_data(path):
|
|||||||
|
|
||||||
# 对每个因变量进行线性插值
|
# 对每个因变量进行线性插值
|
||||||
for col in ["press", "temp", "rh", "u", "v", "wspeed"]:
|
for col in ["press", "temp", "rh", "u", "v", "wspeed"]:
|
||||||
interp_func = interp1d(extracted_df["alt"], extracted_df[col], kind="linear", fill_value="extrapolate")
|
interp_func = interp1d(
|
||||||
|
extracted_df["alt"], extracted_df[col], kind="linear", fill_value="extrapolate")
|
||||||
interpolated_data[col] = interp_func(rounded_heights_np)
|
interpolated_data[col] = interp_func(rounded_heights_np)
|
||||||
|
|
||||||
return interpolated_data
|
return interpolated_data
|
||||||
|
|||||||
@ -35,8 +35,11 @@ async def single_render():
|
|||||||
year = request.args.get("year", 2008)
|
year = request.args.get("year", 2008)
|
||||||
day = request.args.get("day", 1)
|
day = request.args.get("day", 1)
|
||||||
mode = request.args.get("mode", "mean_ktemp_Nz")
|
mode = request.args.get("mode", "mean_ktemp_Nz")
|
||||||
|
lat_range = request.args.get("lat_range", "30.0 ~ 40.0")
|
||||||
|
lat_range = tuple(map(float, lat_range.split("~")))
|
||||||
|
|
||||||
p: CosmicGravitywPlot = await run_sync(CosmicGravitywPlot)(year=int(year), day=int(day))
|
p: CosmicGravitywPlot = await run_sync(CosmicGravitywPlot)(
|
||||||
|
year=int(year), day=int(day), lat_range=lat_range)
|
||||||
if mode == "mean_ktemp_Nz":
|
if mode == "mean_ktemp_Nz":
|
||||||
await run_sync(p.plot_results_mean_ktemp_Nz)()
|
await run_sync(p.plot_results_mean_ktemp_Nz)()
|
||||||
elif mode == "mean_ktemp_Ptz":
|
elif mode == "mean_ktemp_Ptz":
|
||||||
@ -57,10 +60,15 @@ async def multiday_render():
|
|||||||
start_day = request.args.get("start_day", 1)
|
start_day = request.args.get("start_day", 1)
|
||||||
end_day = request.args.get("end_day", 204)
|
end_day = request.args.get("end_day", 204)
|
||||||
mode = request.args.get("mode", "位温分布")
|
mode = request.args.get("mode", "位温分布")
|
||||||
|
lat_range = request.args.get("lat_range", "30.0 ~ 40.0")
|
||||||
|
lat_range = tuple(map(float, lat_range.split("~")))
|
||||||
|
|
||||||
p: GravityMultidayPlot = await run_sync(GravityMultidayPlot)(year=int(year),
|
p: GravityMultidayPlot = await run_sync(GravityMultidayPlot)(
|
||||||
day_range=(start_day, end_day))
|
year=int(year),
|
||||||
if mode == "布伦特-维萨拉频率分布":
|
day_range=(start_day, end_day),
|
||||||
|
lat_range=lat_range
|
||||||
|
)
|
||||||
|
if mode == "浮力频率均值":
|
||||||
await run_sync(p.plot_heatmap_tempNz)()
|
await run_sync(p.plot_heatmap_tempNz)()
|
||||||
elif mode == "不同高度下的逐日统计分析":
|
elif mode == "不同高度下的逐日统计分析":
|
||||||
await run_sync(p.plot_heatmap_tempPtz)()
|
await run_sync(p.plot_heatmap_tempPtz)()
|
||||||
@ -68,6 +76,8 @@ async def multiday_render():
|
|||||||
await run_sync(p.plot_floatage_trend)()
|
await run_sync(p.plot_floatage_trend)()
|
||||||
elif mode == "每月平均重力势能的折线图":
|
elif mode == "每月平均重力势能的折线图":
|
||||||
await run_sync(p.plot_monthly_energy)()
|
await run_sync(p.plot_monthly_energy)()
|
||||||
|
elif mode == "每月平均N^2的折线图":
|
||||||
|
await run_sync(p.plot_monthly_tempNz)()
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid mode")
|
raise ValueError("Invalid mode")
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ plt.rcParams['font.sans-serif'] = ['Simhei'] # 设置字体为微软雅黑
|
|||||||
# 主循环,处理1到365个文件
|
# 主循环,处理1到365个文件
|
||||||
|
|
||||||
|
|
||||||
def get_multiday_data(year=2008, day_range=DAY_RANGE):
|
def get_multiday_data(year=2008, day_range=DAY_RANGE, lat_range=(30, 40)):
|
||||||
base_folder_path = f"{DATA_BASEPATH.cosmic}/{year}"
|
base_folder_path = f"{DATA_BASEPATH.cosmic}/{year}"
|
||||||
all_mean_ktemp_Nz = []
|
all_mean_ktemp_Nz = []
|
||||||
all_mean_ktemp_Ptz = []
|
all_mean_ktemp_Ptz = []
|
||||||
@ -29,7 +29,7 @@ def get_multiday_data(year=2008, day_range=DAY_RANGE):
|
|||||||
for file_index in range(day_begin, day_end):
|
for file_index in range(day_begin, day_end):
|
||||||
try:
|
try:
|
||||||
mean_ktemp_Nz, mean_ktemp_Ptz = process_single_file(
|
mean_ktemp_Nz, mean_ktemp_Ptz = process_single_file(
|
||||||
base_folder_path, file_index)
|
base_folder_path, file_index, lat_range)
|
||||||
if mean_ktemp_Nz is not None and mean_ktemp_Ptz is not None:
|
if mean_ktemp_Nz is not None and mean_ktemp_Ptz is not None:
|
||||||
all_mean_ktemp_Nz.append(mean_ktemp_Nz)
|
all_mean_ktemp_Nz.append(mean_ktemp_Nz)
|
||||||
all_mean_ktemp_Ptz.append(mean_ktemp_Ptz)
|
all_mean_ktemp_Ptz.append(mean_ktemp_Ptz)
|
||||||
@ -83,11 +83,11 @@ def plot_heatmap(data, heights, title):
|
|||||||
|
|
||||||
|
|
||||||
class GravityMultidayPlot:
|
class GravityMultidayPlot:
|
||||||
def __init__(self, year, day_range):
|
def __init__(self, year, day_range, lat_range=None):
|
||||||
|
|
||||||
self.year = year
|
self.year = year
|
||||||
df_final_mean_ktemp_Nz, df_final_mean_ktemp_Ptz, data, heights = get_multiday_data(
|
df_final_mean_ktemp_Nz, df_final_mean_ktemp_Ptz, data, heights = get_multiday_data(
|
||||||
year, day_range)
|
year, day_range, lat_range)
|
||||||
self.df_final_mean_ktemp_Nz = df_final_mean_ktemp_Nz
|
self.df_final_mean_ktemp_Nz = df_final_mean_ktemp_Nz
|
||||||
self.df_final_mean_ktemp_Ptz = df_final_mean_ktemp_Ptz
|
self.df_final_mean_ktemp_Ptz = df_final_mean_ktemp_Ptz
|
||||||
self.data = data
|
self.data = data
|
||||||
@ -148,7 +148,6 @@ class GravityMultidayPlot:
|
|||||||
plt.grid(True)
|
plt.grid(True)
|
||||||
plt.xticks(rotation=45) # 让x轴标签(月份)倾斜,以便更清晰显示
|
plt.xticks(rotation=45) # 让x轴标签(月份)倾斜,以便更清晰显示
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plot_monthly_energy(self):
|
def plot_monthly_energy(self):
|
||||||
data1 = self.data1
|
data1 = self.data1
|
||||||
@ -192,7 +191,6 @@ class GravityMultidayPlot:
|
|||||||
plt.grid(True)
|
plt.grid(True)
|
||||||
plt.xticks(rotation=45) # 让x轴标签(月份)倾斜,以便更清晰显示
|
plt.xticks(rotation=45) # 让x轴标签(月份)倾斜,以便更清晰显示
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plot_floatage_trend(self):
|
def plot_floatage_trend(self):
|
||||||
data = self.data
|
data = self.data
|
||||||
@ -246,7 +244,6 @@ class GravityMultidayPlot:
|
|||||||
# 显示网格线,增强图表可读性
|
# 显示网格线,增强图表可读性
|
||||||
ax.grid(True)
|
ax.grid(True)
|
||||||
# 显示图形
|
# 显示图形
|
||||||
plt.show()
|
|
||||||
|
|
||||||
def plot_floatage_trend(self):
|
def plot_floatage_trend(self):
|
||||||
data1 = self.data1
|
data1 = self.data1
|
||||||
@ -300,4 +297,3 @@ class GravityMultidayPlot:
|
|||||||
# 显示网格线,增强图表可读性
|
# 显示网格线,增强图表可读性
|
||||||
ax.grid(True)
|
ax.grid(True)
|
||||||
# 显示图形
|
# 显示图形
|
||||||
plt.show()
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import seaborn as sns
|
|||||||
import matplotlib.font_manager as fm
|
import matplotlib.font_manager as fm
|
||||||
|
|
||||||
|
|
||||||
def process_single_file(base_folder_path, i):
|
def process_single_file(base_folder_path, i, lat_range=(30, 40)):
|
||||||
# 构建当前文件夹的路径
|
# 构建当前文件夹的路径
|
||||||
if i < 10:
|
if i < 10:
|
||||||
folder_name = f"atmPrf_repro2021_2008_00{i}" # 一位数,前面加两个0
|
folder_name = f"atmPrf_repro2021_2008_00{i}" # 一位数,前面加两个0
|
||||||
@ -93,9 +93,11 @@ def process_single_file(base_folder_path, i):
|
|||||||
# 摄氏度换算开尔文
|
# 摄氏度换算开尔文
|
||||||
final_df['Temperature'] = final_df['Temperature'] + 273.15
|
final_df['Temperature'] = final_df['Temperature'] + 273.15
|
||||||
|
|
||||||
|
lat_begin, lat_end = lat_range
|
||||||
|
|
||||||
# 筛选出纬度在30到40度之间的数据
|
# 筛选出纬度在30到40度之间的数据
|
||||||
latitude_filtered_df = final_df[(
|
latitude_filtered_df = final_df[(
|
||||||
final_df['Latitude'] >= 30) & (final_df['Latitude'] <= 40)]
|
final_df['Latitude'] >= lat_begin) & (final_df['Latitude'] <= lat_end)]
|
||||||
|
|
||||||
# 划分经度网格,20°的网格
|
# 划分经度网格,20°的网格
|
||||||
lon_min, lon_max = latitude_filtered_df['Longitude'].min(
|
lon_min, lon_max = latitude_filtered_df['Longitude'].min(
|
||||||
|
|||||||
@ -100,7 +100,7 @@ def read_and_preprocess_data(base_folder_path, day_num):
|
|||||||
|
|
||||||
|
|
||||||
# 模块2: 数据筛选与网格划分
|
# 模块2: 数据筛选与网格划分
|
||||||
def filter_and_grid_data(final_df):
|
def filter_and_grid_data(final_df, lat_range=(30, 40)):
|
||||||
"""
|
"""
|
||||||
对输入的数据框进行纬度筛选以及经度网格划分等操作
|
对输入的数据框进行纬度筛选以及经度网格划分等操作
|
||||||
|
|
||||||
@ -112,8 +112,9 @@ def filter_and_grid_data(final_df):
|
|||||||
altitude_temperature_mean (pd.DataFrame): 按高度分组求平均温度后的数据框
|
altitude_temperature_mean (pd.DataFrame): 按高度分组求平均温度后的数据框
|
||||||
"""
|
"""
|
||||||
# 筛选出纬度在30到40度之间的数据
|
# 筛选出纬度在30到40度之间的数据
|
||||||
|
lat_begin, lat_end = lat_range
|
||||||
latitude_filtered_df = final_df[(
|
latitude_filtered_df = final_df[(
|
||||||
final_df['Latitude'] >= 30) & (final_df['Latitude'] <= 40)]
|
final_df['Latitude'] >= lat_begin) & (final_df['Latitude'] <= lat_end)]
|
||||||
# 划分经度网格,20°的网格
|
# 划分经度网格,20°的网格
|
||||||
lon_min, lon_max = latitude_filtered_df['Longitude'].min(
|
lon_min, lon_max = latitude_filtered_df['Longitude'].min(
|
||||||
), latitude_filtered_df['Longitude'].max()
|
), latitude_filtered_df['Longitude'].max()
|
||||||
@ -381,7 +382,7 @@ def plot_results_mean_ktemp_Ptz(mean_ktemp_Ptz, heights):
|
|||||||
|
|
||||||
class CosmicGravitywPlot:
|
class CosmicGravitywPlot:
|
||||||
|
|
||||||
def __init__(self, year, day):
|
def __init__(self, year, day, lat_range):
|
||||||
BASE_PATH_COSMIC = DATA_BASEPATH.cosmic
|
BASE_PATH_COSMIC = DATA_BASEPATH.cosmic
|
||||||
|
|
||||||
base_folder_path = f"./{BASE_PATH_COSMIC}/{year}"
|
base_folder_path = f"./{BASE_PATH_COSMIC}/{year}"
|
||||||
@ -390,7 +391,7 @@ class CosmicGravitywPlot:
|
|||||||
final_df = read_and_preprocess_data(base_folder_path, day_num)
|
final_df = read_and_preprocess_data(base_folder_path, day_num)
|
||||||
# 模块2调用
|
# 模块2调用
|
||||||
latitude_filtered_df, altitude_temperature_mean = filter_and_grid_data(
|
latitude_filtered_df, altitude_temperature_mean = filter_and_grid_data(
|
||||||
final_df)
|
final_df, lat_range)
|
||||||
# 模块3调用
|
# 模块3调用
|
||||||
merged_df = calculate_wn0_and_perturbation(
|
merged_df = calculate_wn0_and_perturbation(
|
||||||
latitude_filtered_df, altitude_temperature_mean)
|
latitude_filtered_df, altitude_temperature_mean)
|
||||||
|
|||||||
@ -24,10 +24,14 @@ renderer = SaberGravitywRenderer()
|
|||||||
|
|
||||||
def get_gravityw_processer():
|
def get_gravityw_processer():
|
||||||
lat_str = request.args.get("lat_range")
|
lat_str = request.args.get("lat_range")
|
||||||
|
# if found ~ in str, replace it with ,
|
||||||
|
if "~" in lat_str:
|
||||||
|
lat_str = lat_str.replace("~", ",")
|
||||||
if lat_str is None:
|
if lat_str is None:
|
||||||
lat_str = "30.0,40.0"
|
lat_str = "30.0,40.0"
|
||||||
|
print(lat_str)
|
||||||
lat_range = tuple(map(float, lat_str.split(",")))
|
lat_range = tuple(map(float, lat_str.split(",")))
|
||||||
|
print(lat_range)
|
||||||
alt_str = request.args.get("alt_range")
|
alt_str = request.args.get("alt_range")
|
||||||
if alt_str is None:
|
if alt_str is None:
|
||||||
alt_str = "20.0,105.0"
|
alt_str = "20.0,105.0"
|
||||||
|
|||||||
@ -104,9 +104,9 @@ def saber_planetw_plot(
|
|||||||
# 对每一列生成独立的子图
|
# 对每一列生成独立的子图
|
||||||
col = k_to_a[f'k={k}']
|
col = k_to_a[f'k={k}']
|
||||||
plt.plot(x_values, fit_df[col].values)
|
plt.plot(x_values, fit_df[col].values)
|
||||||
plt.set_title(f'k = {k} 振幅图')
|
plt.suptitle(f'k = {k} 振幅图')
|
||||||
plt.set_xlabel('Day')
|
plt.xlabel('Day')
|
||||||
plt.set_ylabel('振幅')
|
plt.ylabel('振幅')
|
||||||
|
|
||||||
# 设置横坐标的动态调整
|
# 设置横坐标的动态调整
|
||||||
adjusted_x_values = x_values + (3 * T + 1) / 2
|
adjusted_x_values = x_values + (3 * T + 1) / 2
|
||||||
@ -118,8 +118,7 @@ def saber_planetw_plot(
|
|||||||
tick_positions = adjusted_x_values
|
tick_positions = adjusted_x_values
|
||||||
tick_labels = [f'{int(val)}' for val in tick_positions]
|
tick_labels = [f'{int(val)}' for val in tick_positions]
|
||||||
|
|
||||||
plt.set_xticks(tick_positions)
|
plt.xticks(tick_positions, tick_labels)
|
||||||
plt.set_xticklabels(tick_labels)
|
|
||||||
|
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
# plt.show()
|
# plt.show()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user