PYTHON脚本练习(二)

  以下是python脚本练习2,功能为读取选定时间段内的hdf5文件,文件名形如20130512_cross_spec.hdf5。该文件总共有24段,每一段是一个小时某台阵平均互相关谱。然后画出这个互相关谱,保存为png格式图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import os
import h5py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime, timedelta
from matplotlib.dates import DateFormatter


def parse_filename_to_start_time(filename):
"""从文件名推断数据起始时间"""
date_str = filename.split('_')[0] # 提取"20130512"
return datetime.strptime(date_str, "%Y%m%d") # 转为 datetime


def load_cross_spec_from_files(hdf5_dir, start_date, end_date):
"""读取目录下所有落在给定时间范围的互相关谱"""
files = sorted([f for f in os.listdir(hdf5_dir) if f.endswith("_cross_spec.hdf5")])
#files = sorted([f for f in os.listdir(hdf5_dir) if f.endswith("_power_spec.hdf5")])
time_list = []
spec_list = []
for file in files:
try:
base_time = parse_filename_to_start_time(file)
except Exception as e:
print(f"跳过无法解析时间的文件:{file}")
continue

if not (start_date <= base_time <= end_date):
continue

file_path = os.path.join(hdf5_dir, file)
with h5py.File(file_path, 'r') as f:
for i in range(1,24):
ds_name = f'window_{i}'
if ds_name in f:
data = f[ds_name][:]
current_time = base_time + timedelta(hours=i)
time_list.append(current_time)
spec_list.append(data)
return time_list, spec_list


def plot_spectrogram(time_list, spec_list, freqs=None, title="Cross Spectrogram", save_path=None):
"""绘制时间-频率图像"""
if not time_list or not spec_list:
print("没有数据可供绘图。")
return

spec_array = np.array(spec_list).T # shape: freq x time
#spec_array = spec_array - np.mean(spec_array, axis=1, keepdims=True)
n_freq = spec_array.shape[0]

if freqs is None:
freqs = np.linspace(0.005, 0.1, n_freq)

fig, ax = plt.subplots(figsize=(14, 6))
time_nums = mdates.date2num(time_list)

cax = ax.pcolormesh(time_nums, freqs, spec_array, shading='auto', cmap='inferno')
#cax = ax.pcolormesh(time_nums, freqs, spec_array, shading='auto' )
fig.colorbar(cax, label='Cross Spectral Amplitude')
ax.set_title(title)
ax.set_yscale('log') # 设置纵轴为对数刻度
ax.set_xlabel("Time (UTC)")
ax.set_ylabel("Frequency (Hz)")
ax.xaxis.set_major_formatter(DateFormatter("%Y-%m-%d\n%H:%M"))
plt.xticks(rotation=30)
plt.tight_layout()

if save_path:
plt.savefig(save_path, dpi=300)
print(f"图像已保存到:{save_path}")

plt.show()

# 设置参数
hdf5_dir = "output_1_0" # HDF5 文件夹路径
start_date = datetime(2006, 5, 1)
end_date = datetime(2006, 5,31)
# 加载数据
time_list, spec_list = load_cross_spec_from_files(hdf5_dir, start_date, end_date)
# 绘图并保存为 PNG(可选)
plot_spectrogram(time_list, spec_list,
title=f"Cross Spectral Density ({start_date.date()} ~ {end_date.date()})",
save_path="cross_spectrogram_2006_1_0.png")