357 lines
14 KiB
Python
357 lines
14 KiB
Python
# 探空气球只有重力波
|
|
|
|
from io import BytesIO
|
|
import numpy as np
|
|
import pandas as pd
|
|
import seaborn as sns
|
|
from windrose import WindroseAxes
|
|
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.gridspec as gridspec
|
|
|
|
|
|
def plot_w_f(filtered_df, ax):
|
|
min_val = 1
|
|
max_val = 10
|
|
bin_width = 0.5
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["w_f"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("w/f值统计结果", fontsize=24)
|
|
ax.set_xlabel("w/f")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_zhou_qi(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["zhou_qi"].min())
|
|
max_val = np.ceil(filtered_df["zhou_qi"].max())
|
|
bin_width = 1
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["zhou_qi"], bins=bins,
|
|
kde=False, edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("周期统计结果", fontsize=24)
|
|
ax.set_xlabel("h")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_ver_wave_len(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["ver_wave_len"].min())
|
|
max_val = np.ceil(filtered_df["ver_wave_len"].max())
|
|
bin_width = 0.5
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["ver_wave_len"], bins=bins,
|
|
kde=False, edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("垂直波长分布", fontsize=24)
|
|
ax.set_xlabel("Vertical wavelength(km)")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_hori_wave_len(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["hori_wave_len"].min())
|
|
max_val = np.ceil(filtered_df["hori_wave_len"].max())
|
|
bin_width = 100
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["hori_wave_len"], bins=bins,
|
|
kde=False, edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("水平波长分布", fontsize=24)
|
|
ax.set_xlabel("Horizontal wavelength(km)")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_c_x(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["c_x"].min())
|
|
max_val = np.ceil(filtered_df["c_x"].max())
|
|
bin_width = 10
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["c_x"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("纬向本征相速度", fontsize=24)
|
|
ax.set_xlabel("Zonal phase speed (m/s)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_c_y(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["c_y"].min())
|
|
max_val = np.ceil(filtered_df["c_y"].max())
|
|
bin_width = 10
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["c_y"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("经向本征相速度", fontsize=24)
|
|
ax.set_xlabel("Meridional phase speed (m/s)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_c_z(filtered_df, ax):
|
|
min_val = filtered_df["c_z"].min()
|
|
max_val = filtered_df["c_z"].max()
|
|
bin_width = 0.1
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["c_z"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("垂直本征相速度", fontsize=24)
|
|
ax.set_xlabel("Vertical phase speed (m/s)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_u1(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["u1"].min())
|
|
max_val = np.ceil(filtered_df["u1"].max())
|
|
bin_width = 0.5
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["u1"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title(" ", fontsize=24)
|
|
ax.set_xlabel("Zonal wind amplitude (m/s)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_v1(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["v1"].min())
|
|
max_val = np.ceil(filtered_df["v1"].max())
|
|
bin_width = 0.5
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["v1"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("扰动振幅统计结果", fontsize=24)
|
|
ax.set_xlabel("Meridional wind amplitude (m/s)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_T1(filtered_df, ax):
|
|
min_val = np.floor(filtered_df["T1"].min())
|
|
max_val = np.ceil(filtered_df["T1"].max())
|
|
bin_width = 0.5
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df["T1"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title(" ", fontsize=24)
|
|
ax.set_xlabel("Temperature amplitude (K)")
|
|
ax.set_ylabel("Occurrence (%)")
|
|
|
|
|
|
def plot_MFu(filtered_df1, ax):
|
|
min_val = np.floor(filtered_df1["MFu"].min())
|
|
max_val = np.ceil(filtered_df1["MFu"].max())
|
|
bin_width = 0.1
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df1["MFu"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("纬向动量通量统计结果", fontsize=24)
|
|
ax.set_xlabel("Zonal momentum flux(mPa)")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_MFv(filtered_df1, ax):
|
|
min_val = np.floor(filtered_df1["MFv"].min())
|
|
max_val = np.ceil(filtered_df1["MFv"].max())
|
|
bin_width = 0.1
|
|
bins = np.arange(min_val, max_val + bin_width, bin_width)
|
|
sns.histplot(filtered_df1["MFv"], bins=bins, kde=False,
|
|
edgecolor="black", stat="percent", ax=ax)
|
|
ax.set_xlim(min_val, max_val)
|
|
ax.set_title("经向动量通量统计结果", fontsize=24)
|
|
ax.set_xlabel("Meridional momentum flux(mPa)")
|
|
ax.set_ylabel("Occurrence(%)")
|
|
|
|
|
|
def plot_horizontal_propagation(filtered_df: pd.DataFrame, season):
|
|
def get_season(date):
|
|
month = date.month
|
|
if month in [12, 1, 2]:
|
|
return "Winter"
|
|
elif month in [3, 4, 5]:
|
|
return "Spring"
|
|
elif month in [6, 7, 8]:
|
|
return "Summer"
|
|
else:
|
|
return "Fall"
|
|
fig = plt.figure(figsize=(36, 20))
|
|
gs = gridspec.GridSpec(2, 2)
|
|
ax10 = []
|
|
for i in range(4):
|
|
ax10.append(fig.add_subplot(gs[i//2, i % 2], projection="windrose"))
|
|
|
|
data = filtered_df.copy()
|
|
|
|
data.loc[:, "date"] = data["file_name"].str[-28:-16]
|
|
filtered_df = data[[
|
|
"date"] + [col for col in data.columns if col != "file_name" and col != "date"]]
|
|
filtered_df.reset_index(drop=True, inplace=True)
|
|
|
|
filtered_df = filtered_df.drop_duplicates(
|
|
subset="date", keep="last") # 使用 drop_duplicates 函数,保留每组重复中的最后一个记录
|
|
|
|
filtered_df["date1"] = filtered_df["date"].str.split(
|
|
"T").str[0] # 再加一列,只保留日期部分
|
|
filtered_df["date1"] = pd.to_datetime(
|
|
filtered_df["date1"], format="%Y%m%d") # 确保 'date1' 列是日期格式
|
|
filtered_df["season"] = filtered_df["date1"].apply(get_season) # 添加季节列
|
|
seasons = ["Winter", "Spring", "Summer", "Fall"]
|
|
for ax, season in zip(ax10, seasons):
|
|
season_data = filtered_df[filtered_df["season"] == season]
|
|
windrose = WindroseAxes.from_ax(ax)
|
|
ax.set_title(season, fontsize=18)
|
|
windrose.bar(season_data["b"], np.ones_like(
|
|
season_data["b"]), normed=False) # normed=True表示占每个季节的占比
|
|
# season_data = filtered_df[filtered_df["season"] == season]
|
|
# windrose = WindroseAxes.from_ax(ax)
|
|
# ax.set_title(season, fontsize=18)
|
|
# windrose.bar(season_data["b"], np.ones_like(
|
|
# season_data["b"]), normed=False)
|
|
|
|
|
|
def plot_vertical_propagation(filtered_df, ax):
|
|
data = filtered_df.copy()
|
|
|
|
data.loc[:, "date"] = data["file_name"].str[-28:-16]
|
|
filtered_df = data[[
|
|
"date"] + [col for col in data.columns if col != "file_name" and col != "date"]]
|
|
filtered_df.reset_index(drop=True, inplace=True)
|
|
|
|
filtered_df = filtered_df.drop_duplicates(
|
|
subset="date", keep="last") # 使用 drop_duplicates 函数,保留每组重复中的最后一个记录
|
|
|
|
filtered_df["date1"] = filtered_df["date"].str.split(
|
|
"T").str[0] # 再加一列,只保留日期部分
|
|
filtered_df["date1"] = pd.to_datetime(
|
|
filtered_df["date1"], format="%Y%m%d") # 确保 'date1' 列是日期格式
|
|
|
|
filtered_df.set_index("date1", inplace=True)
|
|
monthly_stats_df = (
|
|
filtered_df.groupby([filtered_df.index.month, filtered_df.index.year])
|
|
.apply(lambda x: pd.Series({"Upload (%)": (x["a"] == 1).mean() * 100, "Downward (%)": (x["a"] == -1).mean() * 100}))
|
|
.reset_index(level=1, drop=True)
|
|
)
|
|
monthly_avg_stats_df = monthly_stats_df.groupby(level=0).mean()
|
|
dates = monthly_avg_stats_df.index.to_numpy()
|
|
ax.plot(dates, monthly_avg_stats_df["Upload (%)"].to_numpy(
|
|
), marker="o", label="Up (%)")
|
|
ax.plot(dates, monthly_avg_stats_df["Downward (%)"].to_numpy(
|
|
), marker="o", label="Down (%)")
|
|
ax.set_xticks(
|
|
ticks=np.arange(1, 13), labels=["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], rotation=0
|
|
)
|
|
ax.legend()
|
|
ax.set_title("每月上传/下传重力波占比", fontsize=24)
|
|
ax.set_xlabel("Month")
|
|
ax.set_ylabel("Percentage (%)")
|
|
|
|
|
|
def plot_energy_distribution(filtered_df, ax):
|
|
data = filtered_df.copy()
|
|
|
|
data.loc[:, "date"] = data["file_name"].str[-28:-16]
|
|
filtered_df = data[[
|
|
"date"] + [col for col in data.columns if col != "file_name" and col != "date"]]
|
|
filtered_df.reset_index(drop=True, inplace=True)
|
|
|
|
filtered_df = filtered_df.drop_duplicates(
|
|
subset="date", keep="last") # 使用 drop_duplicates 函数,保留每组重复中的最后一个记录
|
|
|
|
filtered_df["date1"] = filtered_df["date"].str.split(
|
|
"T").str[0] # 再加一列,只保留日期部分
|
|
filtered_df["date1"] = pd.to_datetime(
|
|
filtered_df["date1"], format="%Y%m%d") # 确保 'date1' 列是日期格式
|
|
|
|
filtered_df.reset_index(inplace=True)
|
|
filtered_df["year_month"] = filtered_df["date1"].dt.to_period("M")
|
|
monthly_avg = filtered_df.groupby("year_month")[["Ek", "E_p"]].mean()
|
|
full_range = pd.period_range(
|
|
start=monthly_avg.index.min(), end=monthly_avg.index.max(), freq="M")
|
|
full_monthly_avg = pd.DataFrame(index=full_range).join(monthly_avg)
|
|
full_monthly_avg["Ek"] = pd.to_numeric(
|
|
full_monthly_avg["Ek"], errors="coerce")
|
|
full_monthly_avg["E_p"] = pd.to_numeric(
|
|
full_monthly_avg["E_p"], errors="coerce")
|
|
ax.plot(full_monthly_avg.index.values.astype(
|
|
str), full_monthly_avg["Ek"].values, marker="o", linestyle="-", color="r", label="动能月平均值")
|
|
ax.plot(full_monthly_avg.index.values.astype(
|
|
str), full_monthly_avg["E_p"].values, marker="o", linestyle="-", color="b", label="势能月平均值")
|
|
ax.set_title("动能和势能分布情况", fontsize=24)
|
|
ax.set_xlabel("Month", fontsize=14)
|
|
ax.set_ylabel("Wave energy (J/kg)", fontsize=14)
|
|
months = full_monthly_avg.index.values.astype(str)
|
|
june_indices = [i for i, date in enumerate(months) if date.endswith("-06")]
|
|
december_indices = [i for i, date in enumerate(
|
|
months) if date.endswith("-12")]
|
|
selected_indices = june_indices + december_indices
|
|
ax.set_xticks(ticks=selected_indices, labels=[
|
|
months[i] for i in selected_indices], rotation=45)
|
|
ax.legend()
|
|
|
|
|
|
# def render_based_on_mode(df, mode, seaon = None):
|
|
def render_based_on_mode(df, mode, season=None):
|
|
buf = BytesIO()
|
|
fig, ax = plt.subplots(figsize=(10, 6))
|
|
if mode == "w/f值统计结果":
|
|
plot_w_f(df, ax)
|
|
elif mode == "周期统计结果":
|
|
plot_zhou_qi(df, ax)
|
|
elif mode == "垂直波长分布":
|
|
plot_ver_wave_len(df, ax)
|
|
elif mode == "水平波长分布":
|
|
plot_hori_wave_len(df, ax)
|
|
elif mode == "纬向本征相速度":
|
|
plot_c_x(df, ax)
|
|
elif mode == "经向本征相速度":
|
|
plot_c_y(df, ax)
|
|
elif mode == "垂直本征相速度":
|
|
plot_c_z(df, ax)
|
|
elif mode == "Zonal wind amplitude (m/s)":
|
|
plot_u1(df, ax)
|
|
elif mode == "扰动振幅统计结果":
|
|
plot_v1(df, ax)
|
|
elif mode == "Temperature amplitude (K)":
|
|
plot_T1(df, ax)
|
|
elif mode == "纬向动量通量统计结果":
|
|
plot_MFu(df, ax)
|
|
elif mode == "经向动量通量统计结果":
|
|
plot_MFv(df, ax)
|
|
elif mode == "horizontal propagation":
|
|
plot_horizontal_propagation(df, season="Fall")
|
|
elif mode == "每月上传/下传重力波占比":
|
|
plot_vertical_propagation(df, ax)
|
|
elif mode == "动能和势能分布情况":
|
|
plot_energy_distribution(df, ax)
|
|
else:
|
|
raise ValueError("Invalid mode")
|
|
plt.rcParams["font.sans-serif"] = ["SimHei"] # 显示中文
|
|
plt.savefig(buf)
|
|
buf.seek(0)
|
|
plt.close()
|
|
return buf
|
|
# if mode == ""
|
|
|
|
|
|
def get_all_modes():
|
|
return [
|
|
"w/f值统计结果",
|
|
"周期统计结果",
|
|
"垂直波长分布",
|
|
"水平波长分布",
|
|
"纬向本征相速度",
|
|
"经向本征相速度",
|
|
"垂直本征相速度",
|
|
"Zonal wind amplitude (m/s)",
|
|
"扰动振幅统计结果",
|
|
"Temperature amplitude (K)",
|
|
"纬向动量通量统计结果",
|
|
"经向动量通量统计结果",
|
|
"horizontal propagation",
|
|
"每月上传/下传重力波占比",
|
|
"动能和势能分布情况",
|
|
]
|