oafuncs 0.0.97.14__py3-none-any.whl → 0.0.97.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oafuncs/_script/cprogressbar.py +42 -20
- oafuncs/_script/netcdf_merge.py +1 -1
- oafuncs/_script/netcdf_modify.py +106 -0
- oafuncs/_script/netcdf_write.py +125 -0
- oafuncs/oa_cmap.py +59 -112
- oafuncs/oa_date.py +30 -16
- oafuncs/oa_down/hycom_3hourly.py +5 -54
- oafuncs/oa_draw.py +11 -132
- oafuncs/oa_file.py +1 -23
- oafuncs/oa_nc.py +51 -270
- oafuncs/oa_python.py +77 -87
- oafuncs/oa_sign/meteorological.py +3 -3
- oafuncs/oa_tool.py +31 -34
- {oafuncs-0.0.97.14.dist-info → oafuncs-0.0.97.16.dist-info}/METADATA +1 -1
- {oafuncs-0.0.97.14.dist-info → oafuncs-0.0.97.16.dist-info}/RECORD +18 -16
- {oafuncs-0.0.97.14.dist-info → oafuncs-0.0.97.16.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.97.14.dist-info → oafuncs-0.0.97.16.dist-info}/licenses/LICENSE.txt +0 -0
- {oafuncs-0.0.97.14.dist-info → oafuncs-0.0.97.16.dist-info}/top_level.txt +0 -0
oafuncs/oa_date.py
CHANGED
@@ -13,40 +13,39 @@ SystemInfo: Windows 11
|
|
13
13
|
Python Version: 3.12
|
14
14
|
"""
|
15
15
|
|
16
|
-
|
17
|
-
|
18
16
|
import calendar
|
19
17
|
import datetime
|
18
|
+
from typing import List, Optional
|
20
19
|
|
21
|
-
__all__ = ["
|
20
|
+
__all__ = ["month_days", "hour_range", "adjust_time", "timeit"]
|
22
21
|
|
23
22
|
|
24
|
-
def
|
23
|
+
def month_days(year: int, month: int) -> int:
|
25
24
|
return calendar.monthrange(year, month)[1]
|
26
25
|
|
27
26
|
|
28
|
-
def
|
27
|
+
def hour_range(start: str, end: str, interval: int = 6) -> List[str]:
|
29
28
|
"""
|
30
29
|
Generate a list of datetime strings with a specified interval in hours.
|
31
30
|
|
32
31
|
Args:
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
start (str): Start date in the format "%Y%m%d%H".
|
33
|
+
end (str): End date in the format "%Y%m%d%H".
|
34
|
+
interval (int): Interval in hours between each datetime.
|
36
35
|
|
37
36
|
Returns:
|
38
37
|
list: List of datetime strings in the format "%Y%m%d%H".
|
39
38
|
"""
|
40
|
-
date_s = datetime.datetime.strptime(
|
41
|
-
date_e = datetime.datetime.strptime(
|
39
|
+
date_s = datetime.datetime.strptime(start, "%Y%m%d%H")
|
40
|
+
date_e = datetime.datetime.strptime(end, "%Y%m%d%H")
|
42
41
|
date_list = []
|
43
42
|
while date_s <= date_e:
|
44
43
|
date_list.append(date_s.strftime("%Y%m%d%H"))
|
45
|
-
date_s += datetime.timedelta(hours=
|
44
|
+
date_s += datetime.timedelta(hours=interval)
|
46
45
|
return date_list
|
47
46
|
|
48
47
|
|
49
|
-
def adjust_time(initial_time, amount, time_unit="hours", output_format=None):
|
48
|
+
def adjust_time(initial_time: str, amount: int, time_unit: str = "hours", output_format: Optional[str] = None) -> str:
|
50
49
|
"""
|
51
50
|
Adjust a given initial time by adding a specified amount of time.
|
52
51
|
|
@@ -91,22 +90,37 @@ def adjust_time(initial_time, amount, time_unit="hours", output_format=None):
|
|
91
90
|
default_format = "%Y%m%d"
|
92
91
|
return time_obj.strftime(default_format)
|
93
92
|
|
93
|
+
|
94
94
|
class timeit:
|
95
95
|
"""
|
96
96
|
A decorator to measure the execution time of a function.
|
97
97
|
|
98
98
|
Usage:
|
99
|
-
@timeit
|
99
|
+
@timeit(log=True, print_time=True)
|
100
100
|
def my_function():
|
101
101
|
# Function code here
|
102
|
+
|
103
|
+
Args:
|
104
|
+
log (bool): Whether to log the execution time to a file. Defaults to False.
|
105
|
+
print_time (bool): Whether to print the execution time to the console. Defaults to True.
|
102
106
|
"""
|
103
|
-
|
107
|
+
|
108
|
+
def __init__(self, func, log: bool = False, print_time: bool = True):
|
104
109
|
self.func = func
|
110
|
+
self.log = log
|
111
|
+
self.print_time = print_time
|
105
112
|
|
106
113
|
def __call__(self, *args, **kwargs):
|
107
114
|
start_time = datetime.datetime.now()
|
108
115
|
result = self.func(*args, **kwargs)
|
109
116
|
end_time = datetime.datetime.now()
|
110
117
|
elapsed_time = (end_time - start_time).total_seconds()
|
111
|
-
|
112
|
-
|
118
|
+
|
119
|
+
if self.print_time:
|
120
|
+
print(f"Function '{self.func.__name__}' executed in {elapsed_time:.2f} seconds.")
|
121
|
+
|
122
|
+
if self.log:
|
123
|
+
with open("execution_time.log", "a") as log_file:
|
124
|
+
log_file.write(f"{datetime.datetime.now()} - Function '{self.func.__name__}' executed in {elapsed_time:.2f} seconds.\n")
|
125
|
+
|
126
|
+
return result
|
oafuncs/oa_down/hycom_3hourly.py
CHANGED
@@ -40,7 +40,7 @@ from oafuncs.oa_nc import modify as modify_nc
|
|
40
40
|
|
41
41
|
warnings.filterwarnings("ignore", category=RuntimeWarning, message="Engine '.*' loading failed:.*")
|
42
42
|
|
43
|
-
__all__ = ["draw_time_range", "download"
|
43
|
+
__all__ = ["draw_time_range", "download"]
|
44
44
|
|
45
45
|
|
46
46
|
def _get_initial_data():
|
@@ -278,7 +278,7 @@ def draw_time_range(pic_save_folder=None):
|
|
278
278
|
plt.close()
|
279
279
|
|
280
280
|
|
281
|
-
def
|
281
|
+
def _get_time_list(time_s, time_e, delta, interval_type="hour"):
|
282
282
|
"""
|
283
283
|
Description: get a list of time strings from time_s to time_e with a specified interval
|
284
284
|
Args:
|
@@ -1029,7 +1029,7 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
|
|
1029
1029
|
_prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, ymdh_time_s, None, depth, level, store_path, dataset_name, version_name, check)
|
1030
1030
|
elif int(ymdh_time_s) < int(ymdh_time_e):
|
1031
1031
|
print("Downloading a series of files...")
|
1032
|
-
time_list =
|
1032
|
+
time_list = _get_time_list(ymdh_time_s, ymdh_time_e, interval_hour, "hour")
|
1033
1033
|
with Progress() as progress:
|
1034
1034
|
task = progress.add_task(f"[cyan]{bar_desc}", total=len(time_list))
|
1035
1035
|
if ftimes == 1:
|
@@ -1048,7 +1048,7 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
|
|
1048
1048
|
_done_callback(feature, progress, task, len(time_list), counter_lock)
|
1049
1049
|
else:
|
1050
1050
|
# new_time_list = get_time_list(ymdh_time_s, ymdh_time_e, 3 * ftimes, "hour")
|
1051
|
-
new_time_list =
|
1051
|
+
new_time_list = _get_time_list(ymdh_time_s, ymdh_time_e, interval_hour * ftimes, "hour")
|
1052
1052
|
total_num = len(new_time_list)
|
1053
1053
|
if num_workers is None or num_workers <= 1:
|
1054
1054
|
# 串行方式
|
@@ -1097,7 +1097,7 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
|
|
1097
1097
|
Returns:
|
1098
1098
|
None
|
1099
1099
|
"""
|
1100
|
-
from oafuncs.
|
1100
|
+
from oafuncs.oa_tool import pbar
|
1101
1101
|
from oafuncs.oa_cmap import get as get_cmap
|
1102
1102
|
|
1103
1103
|
_get_initial_data()
|
@@ -1248,55 +1248,6 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
|
|
1248
1248
|
print("[bold #ecdbfe]=" * mark_len)
|
1249
1249
|
|
1250
1250
|
|
1251
|
-
def how_to_use():
|
1252
|
-
print("""
|
1253
|
-
# 1. Choose the dataset and version according to the time:
|
1254
|
-
# 1.1 Use function to query
|
1255
|
-
You can use the function check_time_in_dataset_and_version(time_input=20241101) to find the dataset and version according to the time.
|
1256
|
-
Then, you can see the dataset and version in the output.
|
1257
|
-
# 1.2 Draw a picture to see
|
1258
|
-
You can draw a picture to see the time range of each dataset and version.
|
1259
|
-
Using the function draw_time_range(pic_save_folder=None) to draw the picture.
|
1260
|
-
|
1261
|
-
# 2. Get the base url according to the dataset, version, var and year:
|
1262
|
-
# 2.1 Dataset and version were found in step 1
|
1263
|
-
# 2.2 Var: u, v, temp, salt, ssh, u_b, v_b, temp_b, salt_b
|
1264
|
-
# 2.3 Year: 1994-2024(current year)
|
1265
|
-
|
1266
|
-
# 3. Get the query_dict according to the var, lon_min, lon_max, lat_min, lat_max, depth, level_num, time_str_ymdh:
|
1267
|
-
# 3.1 Var: u, v, temp, salt, ssh, u_b, v_b, temp_b, salt_b
|
1268
|
-
# 3.2 Lon_min, lon_max, lat_min, lat_max: float
|
1269
|
-
# 3.3 Depth: 0-5000m, if you wanna get single depth data, you can set the depth
|
1270
|
-
# 3.4 Level_num: 1-40, if you wanna get single level data, you can set the level_num
|
1271
|
-
# 3.5 Time_str_ymdh: '2024110112', the hour normally is 00, 03, 06, 09, 12, 15, 18, 21, besides 1 hourly data
|
1272
|
-
# 3.6 Use the function to get the query_dict
|
1273
|
-
# 3.7 Note: If you wanna get the full depth or full level data, you can needn't set the depth or level_num
|
1274
|
-
|
1275
|
-
# 4. Get the submit url according to the dataset, version, var, year, query_dict:
|
1276
|
-
# 4.1 Use the function to get the submit url
|
1277
|
-
# 4.2 You can use the submit url to download the data
|
1278
|
-
|
1279
|
-
# 5. Download the data according to the submit url:
|
1280
|
-
# 5.1 Use the function to download the data
|
1281
|
-
# 5.2 You can download the data of single time or a series of time
|
1282
|
-
# 5.3 Note: If you wanna download a series of data, you can set the ymdh_time_s and ymdh_time_e different
|
1283
|
-
# 5.4 Note: The time resolution is 3 hours
|
1284
|
-
|
1285
|
-
# 6. Direct download the data:
|
1286
|
-
# 6.1 Use the function to direct download the data
|
1287
|
-
# 6.2 You can set the dataset_name and version_name by yourself
|
1288
|
-
# 6.3 Note: If you do not set the dataset_name and version_name, the dataset and version will be chosen according to the download_time
|
1289
|
-
# 6.4 Note: If you set the dataset_name and version_name, please ensure the dataset_name and version_name are correct
|
1290
|
-
# 6.5 Note: If you just set one of the dataset_name and version_name, both the dataset and version will be chosen according to the download_time
|
1291
|
-
|
1292
|
-
# 7. Simple use:
|
1293
|
-
# 7.1 You can use the function: download(var, ymdh_time_s, ymdh_time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None)
|
1294
|
-
# 7.2 You can download the data of single time or a series of time
|
1295
|
-
# 7.3 The parameters you must set are var, ymdh_time_s, ymdh_time_e
|
1296
|
-
# 7.4 Example: download('u', '2024110112', '2024110212', lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level_num=None, store_path=None, dataset_name=None, version_name=None)
|
1297
|
-
""")
|
1298
|
-
|
1299
|
-
|
1300
1251
|
if __name__ == "__main__":
|
1301
1252
|
download_dict = {
|
1302
1253
|
"water_u": {"simple_name": "u", "download": 1},
|
oafuncs/oa_draw.py
CHANGED
@@ -13,7 +13,6 @@ SystemInfo: Windows 11
|
|
13
13
|
Python Version: 3.11
|
14
14
|
"""
|
15
15
|
|
16
|
-
|
17
16
|
import warnings
|
18
17
|
|
19
18
|
import cartopy.crs as ccrs
|
@@ -21,16 +20,15 @@ import cartopy.feature as cfeature
|
|
21
20
|
import matplotlib as mpl
|
22
21
|
import matplotlib.pyplot as plt
|
23
22
|
import numpy as np
|
24
|
-
import xarray as xr
|
25
23
|
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
|
26
24
|
from rich import print
|
27
25
|
|
28
|
-
__all__ = ["fig_minus", "gif", "add_cartopy", "add_gridlines", "MidpointNormalize", "add_lonlat_unit"
|
26
|
+
__all__ = ["fig_minus", "gif", "add_cartopy", "add_gridlines", "MidpointNormalize", "add_lonlat_unit"]
|
29
27
|
|
30
28
|
warnings.filterwarnings("ignore")
|
31
29
|
|
32
30
|
|
33
|
-
def fig_minus(ax_x=None, ax_y=None, cbar=None, decimal=None, add_space=False):
|
31
|
+
def fig_minus(ax_x: plt.Axes = None, ax_y: plt.Axes = None, cbar: mpl.colorbar.Colorbar = None, decimal: int = None, add_space: bool = False) -> plt.Axes | mpl.colorbar.Colorbar | None:
|
34
32
|
"""
|
35
33
|
Description: 将坐标轴刻度中的负号替换为减号
|
36
34
|
|
@@ -76,7 +74,7 @@ def fig_minus(ax_x=None, ax_y=None, cbar=None, decimal=None, add_space=False):
|
|
76
74
|
|
77
75
|
|
78
76
|
# ** 将生成图片/已有图片制作成动图
|
79
|
-
def gif(image_list: list, gif_name: str, duration=200, resize=None): # 制作动图,默认间隔0.2
|
77
|
+
def gif(image_list: list[str], gif_name: str, duration: float = 200, resize: tuple[int, int] = None) -> None: # 制作动图,默认间隔0.2
|
80
78
|
"""
|
81
79
|
Description
|
82
80
|
Make gif from images
|
@@ -125,7 +123,7 @@ def gif(image_list: list, gif_name: str, duration=200, resize=None): # 制作
|
|
125
123
|
|
126
124
|
|
127
125
|
# ** 转化经/纬度刻度
|
128
|
-
def add_lonlat_unit(lon=None, lat=None, decimal=2):
|
126
|
+
def add_lonlat_unit(lon: list[float] = None, lat: list[float] = None, decimal: int = 2) -> tuple[list[str], list[str]] | list[str]:
|
129
127
|
"""
|
130
128
|
param {*} lon : 经度列表
|
131
129
|
param {*} lat : 纬度列表
|
@@ -165,15 +163,16 @@ def add_lonlat_unit(lon=None, lat=None, decimal=2):
|
|
165
163
|
|
166
164
|
|
167
165
|
# ** 添加网格线
|
168
|
-
def add_gridlines(ax, xline=None, yline=None, projection=ccrs.PlateCarree(), color="k", alpha=0.5, linestyle="--", linewidth=0.5):
|
166
|
+
def add_gridlines(ax: plt.Axes, xline: list[float] = None, yline: list[float] = None, projection: ccrs.Projection = ccrs.PlateCarree(), color: str = "k", alpha: float = 0.5, linestyle: str = "--", linewidth: float = 0.5) -> tuple[plt.Axes, mpl.ticker.Locator]:
|
169
167
|
from matplotlib import ticker as mticker
|
168
|
+
|
170
169
|
# add gridlines
|
171
170
|
gl = ax.gridlines(crs=projection, draw_labels=True, linewidth=linewidth, color=color, alpha=alpha, linestyle=linestyle)
|
172
171
|
gl.right_labels = False
|
173
172
|
gl.top_labels = False
|
174
173
|
gl.xformatter = LongitudeFormatter(zero_direction_label=False)
|
175
174
|
gl.yformatter = LatitudeFormatter()
|
176
|
-
|
175
|
+
|
177
176
|
if xline is not None:
|
178
177
|
gl.xlocator = mticker.FixedLocator(np.array(xline))
|
179
178
|
if yline is not None:
|
@@ -183,7 +182,7 @@ def add_gridlines(ax, xline=None, yline=None, projection=ccrs.PlateCarree(), col
|
|
183
182
|
|
184
183
|
|
185
184
|
# ** 添加地图
|
186
|
-
def add_cartopy(ax, lon=None, lat=None, projection=ccrs.PlateCarree(), gridlines=True, landcolor="lightgrey", oceancolor="lightblue", cartopy_linewidth=0.5):
|
185
|
+
def add_cartopy(ax: plt.Axes, lon: np.ndarray = None, lat: np.ndarray = None, projection: ccrs.Projection = ccrs.PlateCarree(), gridlines: bool = True, landcolor: str = "lightgrey", oceancolor: str = "lightblue", cartopy_linewidth: float = 0.5) -> None:
|
187
186
|
# add coastlines
|
188
187
|
ax.add_feature(cfeature.LAND, facecolor=landcolor)
|
189
188
|
ax.add_feature(cfeature.OCEAN, facecolor=oceancolor)
|
@@ -219,139 +218,19 @@ class MidpointNormalize(mpl.colors.Normalize):
|
|
219
218
|
nrom = MidpointNormalize(vmin=-2, vmax=1, vcenter=0)
|
220
219
|
"""
|
221
220
|
|
222
|
-
def __init__(self, vmin=None, vmax=None, vcenter=None, clip=False):
|
221
|
+
def __init__(self, vmin: float = None, vmax: float = None, vcenter: float = None, clip: bool = False) -> None:
|
223
222
|
self.vcenter = vcenter
|
224
223
|
super().__init__(vmin, vmax, clip)
|
225
224
|
|
226
|
-
def __call__(self, value, clip=None):
|
225
|
+
def __call__(self, value: np.ndarray, clip: bool = None) -> np.ma.MaskedArray:
|
227
226
|
x, y = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1.0]
|
228
227
|
return np.ma.masked_array(np.interp(value, x, y, left=-np.inf, right=np.inf))
|
229
228
|
|
230
|
-
def inverse(self, value):
|
229
|
+
def inverse(self, value: np.ndarray) -> np.ndarray:
|
231
230
|
y, x = [self.vmin, self.vcenter, self.vmax], [0, 0.5, 1]
|
232
231
|
return np.interp(value, x, y, left=-np.inf, right=np.inf)
|
233
232
|
|
234
233
|
|
235
|
-
# -----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
236
|
-
|
237
|
-
# ** 绘制填色图
|
238
|
-
def contourf(data,x=None,y=None,cmap='coolwarm',show=True,store=None,cartopy=False):
|
239
|
-
"""
|
240
|
-
Description: 绘制填色图
|
241
|
-
|
242
|
-
param {*} data : 二维数据
|
243
|
-
param {*} x : x轴坐标
|
244
|
-
param {*} y : y轴坐标
|
245
|
-
param {*} cmap : 颜色映射
|
246
|
-
param {*} show : 是否显示
|
247
|
-
param {*} store : 是否保存
|
248
|
-
param {*} cartopy : 是否使用cartopy
|
249
|
-
|
250
|
-
return {*}
|
251
|
-
"""
|
252
|
-
data = np.array(data)
|
253
|
-
if x is None or y is None:
|
254
|
-
x = np.arange(data.shape[1])
|
255
|
-
y = np.arange(data.shape[0])
|
256
|
-
if cartopy:
|
257
|
-
fig, ax = plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()})
|
258
|
-
add_cartopy(ax, lon=x, lat=y)
|
259
|
-
ax.contourf(x, y, data, transform=ccrs.PlateCarree(), cmap=cmap)
|
260
|
-
else:
|
261
|
-
plt.contourf(x, y, data, cmap=cmap)
|
262
|
-
plt.colorbar()
|
263
|
-
plt.savefig(store, dpi=600, bbox_inches="tight") if store else plt.show()
|
264
|
-
plt.close()
|
265
|
-
|
266
|
-
|
267
|
-
# ** 绘制等值线图
|
268
|
-
def contour(data, x=None, y=None, cmap="coolwarm", show=True, store=None, cartopy=False):
|
269
|
-
"""
|
270
|
-
Description: 绘制等值线图
|
271
|
-
|
272
|
-
param {*} data : 二维数据
|
273
|
-
param {*} x : x轴坐标
|
274
|
-
param {*} y : y轴坐标
|
275
|
-
param {*} cmap : 颜色映射
|
276
|
-
param {*} show : 是否显示
|
277
|
-
param {*} store : 是否保存
|
278
|
-
param {*} cartopy : 是否使用cartopy
|
279
|
-
|
280
|
-
return {*}
|
281
|
-
"""
|
282
|
-
data = np.array(data)
|
283
|
-
if x is None or y is None:
|
284
|
-
x = np.arange(data.shape[1])
|
285
|
-
y = np.arange(data.shape[0])
|
286
|
-
if cartopy:
|
287
|
-
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.PlateCarree()})
|
288
|
-
add_cartopy(ax, lon=x, lat=y)
|
289
|
-
cr = ax.contour(x, y, data, transform=ccrs.PlateCarree(), cmap=cmap)
|
290
|
-
else:
|
291
|
-
cr = plt.contour(x, y, data, cmap=cmap)
|
292
|
-
plt.clabel(cr, inline=True, fontsize=10)
|
293
|
-
plt.savefig(store, dpi=600, bbox_inches="tight") if store else plt.show()
|
294
|
-
plt.close()
|
295
|
-
|
296
|
-
|
297
|
-
# ** 绘制矢量场
|
298
|
-
def quiver(u, v, lon, lat, picname=None, cmap="coolwarm", scale=0.25, width=0.002, x_space=5, y_space=5):
|
299
|
-
"""
|
300
|
-
param {*} u : 二维数据
|
301
|
-
param {*} v : 二维数据
|
302
|
-
param {*} lon : 经度, 1D or 2D
|
303
|
-
param {*} lat : 纬度, 1D or 2D
|
304
|
-
param {*} picname : 图片保存的文件名(含路径)
|
305
|
-
param {*} cmap : 颜色映射,默认coolwarm
|
306
|
-
param {*} scale : 箭头的大小 / 缩小程度
|
307
|
-
param {*} width : 箭头的宽度
|
308
|
-
param {*} x_space : x轴间隔
|
309
|
-
param {*} y_space : y轴间隔
|
310
|
-
return {*} 无返回值
|
311
|
-
"""
|
312
|
-
# 创建新的网格位置变量(lat_c, lon_c)
|
313
|
-
if len(lon.shape) == 1 and len(lat.shape) == 1:
|
314
|
-
lon_c, lat_c = np.meshgrid(lon, lat)
|
315
|
-
else:
|
316
|
-
lon_c, lat_c = lon, lat
|
317
|
-
|
318
|
-
# 设置箭头的比例、颜色、宽度等参数
|
319
|
-
# scale = 0.25 # 箭头的大小 / 缩小程度
|
320
|
-
# color = '#E5D1FA'
|
321
|
-
# width = 0.002 # 箭头的宽度
|
322
|
-
# x_space = 1
|
323
|
-
# y_space = 1
|
324
|
-
|
325
|
-
# 计算矢量的大小
|
326
|
-
S = xr.DataArray(np.hypot(np.array(u), np.array(v)))
|
327
|
-
|
328
|
-
mean_S = S.nanmean()
|
329
|
-
|
330
|
-
# 使用 plt.quiver 函数绘制矢量图
|
331
|
-
# 通过设置 quiver 函数的 pivot 参数来指定箭头的位置
|
332
|
-
quiver_plot = plt.quiver(
|
333
|
-
lon_c[::y_space, ::x_space],
|
334
|
-
lat_c[::y_space, ::x_space],
|
335
|
-
u[::y_space, ::x_space],
|
336
|
-
v[::y_space, ::x_space],
|
337
|
-
S[::y_space, ::x_space], # 矢量的大小,可以不要
|
338
|
-
pivot="middle",
|
339
|
-
scale=scale,
|
340
|
-
# color=color, # 矢量的颜色,单色
|
341
|
-
cmap=cmap, # 矢量的颜色,多色
|
342
|
-
width=width,
|
343
|
-
)
|
344
|
-
# plt.quiverkey(quiver_plot, X=0.90, Y=0.975, U=1, label='1 m/s', labelpos='E', fontproperties={'size': 10})
|
345
|
-
plt.quiverkey(quiver_plot, X=0.87, Y=0.975, U=mean_S, label=f"{mean_S:.2f} m/s", labelpos="E", fontproperties={"size": 10})
|
346
|
-
plt.colorbar(quiver_plot)
|
347
|
-
plt.xlabel("X")
|
348
|
-
plt.ylabel("Y")
|
349
|
-
|
350
|
-
plt.savefig(picname, bbox_inches="tight") if picname is not None else plt.show()
|
351
|
-
plt.clf()
|
352
|
-
plt.close()
|
353
|
-
|
354
|
-
|
355
234
|
|
356
235
|
if __name__ == "__main__":
|
357
236
|
pass
|
oafuncs/oa_file.py
CHANGED
@@ -21,7 +21,7 @@ import shutil
|
|
21
21
|
|
22
22
|
from rich import print
|
23
23
|
|
24
|
-
__all__ = ["find_file", "link_file", "copy_file", "rename_file", "
|
24
|
+
__all__ = ["find_file", "link_file", "copy_file", "rename_file", "move_file", "clear_folder", "remove_empty_folder", "remove", "file_size", "mean_size", "make_dir", "replace_content"]
|
25
25
|
|
26
26
|
|
27
27
|
# ** 查找文件,支持通配符
|
@@ -157,7 +157,6 @@ def copy_file(src_pattern, dst):
|
|
157
157
|
print(f"Copy and rename file or directory: {src_file} -> {dst_file}")
|
158
158
|
|
159
159
|
|
160
|
-
|
161
160
|
# ** 移动文件或目录,支持通配符
|
162
161
|
def move_file(src_pattern, dst):
|
163
162
|
"""
|
@@ -205,7 +204,6 @@ def move_file(src_pattern, dst):
|
|
205
204
|
print(f"Move and rename file or directory: {src_file} -> {dst_file}")
|
206
205
|
|
207
206
|
|
208
|
-
|
209
207
|
# ** 重命名文件,支持通配符
|
210
208
|
def rename_file(directory, old_str, new_str):
|
211
209
|
"""
|
@@ -243,26 +241,6 @@ def rename_file(directory, old_str, new_str):
|
|
243
241
|
print(f"Rename file: {old_path} -> {new_path}")
|
244
242
|
|
245
243
|
|
246
|
-
# ** 创建子文件夹(可选清空)
|
247
|
-
def make_folder(rootpath=None, folder_name=None, clear=False) -> str:
|
248
|
-
"""
|
249
|
-
# 描述:创建子文件夹(可选清空)
|
250
|
-
# 使用示例
|
251
|
-
rootpath = r'E:\\Data\\2024\\09\\17'
|
252
|
-
folder_name = 'var1'
|
253
|
-
newpath = make_folder(rootpath, folder_name, clear=1)
|
254
|
-
param {*} rootpath # 根目录
|
255
|
-
param {*} folder_name # 文件夹名称
|
256
|
-
"""
|
257
|
-
if rootpath is None:
|
258
|
-
rootpath = os.getcwd()
|
259
|
-
folder_path = os.path.join(str(rootpath), str(folder_name))
|
260
|
-
if clear:
|
261
|
-
shutil.rmtree(folder_path, ignore_errors=True)
|
262
|
-
os.makedirs(folder_path, exist_ok=True)
|
263
|
-
return folder_path
|
264
|
-
|
265
|
-
|
266
244
|
# ** 创建路径
|
267
245
|
def make_dir(directory):
|
268
246
|
"""
|