oafuncs 0.0.59__py2.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/__init__.py ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ '''
4
+ Author: Liu Kun && 16031215@qq.com
5
+ Date: 2024-09-17 16:09:20
6
+ LastEditors: Liu Kun && 16031215@qq.com
7
+ LastEditTime: 2024-10-14 17:08:57
8
+ FilePath: \\Python\\My_Funcs\\OAFuncs\\OAFuncs\\__init__.py
9
+ Description:
10
+ EditPlatform: vscode
11
+ ComputerInfo: XPS 15 9510
12
+ SystemInfo: Windows 11
13
+ Python Version: 3.11
14
+ '''
15
+
16
+ # 会导致OAFuncs直接导入所有函数,不符合模块化设计
17
+ from .oa_cmap import *
18
+ from .oa_data import *
19
+ from .oa_down import *
20
+ from .oa_draw import *
21
+ from .oa_file import *
22
+ from .oa_help import *
23
+ from .oa_nc import *
24
+ from .oa_python import *
25
+ from .oa_sign import *
26
+ from .oa_tool import *
oafuncs/oa_cmap.py ADDED
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ '''
4
+ Author: Liu Kun && 16031215@qq.com
5
+ Date: 2024-09-17 16:55:11
6
+ LastEditors: Liu Kun && 16031215@qq.com
7
+ LastEditTime: 2024-10-06 19:34:57
8
+ FilePath: \\Python\\My_Funcs\\OAFuncs\\OAFuncs\\oa_cmap.py
9
+ Description:
10
+ EditPlatform: vscode
11
+ ComputerInfo: XPS 15 9510
12
+ SystemInfo: Windows 11
13
+ Python Version: 3.11
14
+ '''
15
+
16
+
17
+ import matplotlib as mpl
18
+ import matplotlib.pyplot as plt
19
+ import numpy as np
20
+
21
+ __all__ = ['show', 'extract_colors', 'create_custom',
22
+ 'create_diverging', 'create_5rgb_txt']
23
+
24
+ # ** 将cmap用填色图可视化(官网摘抄函数)
25
+
26
+
27
+ def show(colormaps: list):
28
+ """
29
+ Helper function to plot data with associated colormap.
30
+ example:
31
+ cmap = ListedColormap(["darkorange", "gold", "lawngreen", "lightseagreen"])
32
+ show([cmap])
33
+ """
34
+ np.random.seed(19680801)
35
+ data = np.random.randn(30, 30)
36
+ n = len(colormaps)
37
+ fig, axs = plt.subplots(1, n, figsize=(n * 2 + 2, 3),
38
+ constrained_layout=True, squeeze=False)
39
+ for [ax, cmap] in zip(axs.flat, colormaps):
40
+ psm = ax.pcolormesh(data, cmap=cmap, rasterized=True, vmin=-4, vmax=4)
41
+ fig.colorbar(psm, ax=ax)
42
+ plt.show()
43
+
44
+
45
+ # ** 将cmap转为list,即多个颜色的列表
46
+ def extract_colors(cmap, n=256):
47
+ '''
48
+ cmap : cmap名称
49
+ n : 提取颜色数量
50
+ return : 提取的颜色列表
51
+ example : out_cmap = extract_colors('viridis', 256)
52
+ '''
53
+ c_map = mpl.colormaps.get_cmap(cmap)
54
+ out_cmap = [c_map(i) for i in np.linspace(0, 1, n)]
55
+ return out_cmap
56
+
57
+
58
+ # ** 自制cmap,多色,可带位置
59
+ def create_custom(colors: list, nodes=None): # 利用颜色快速配色
60
+ '''
61
+ func : 自制cmap,自动确定颜色位置(等比例)
62
+ description : colors可以是颜色名称,也可以是十六进制颜色代码
63
+ param {*} colors 颜色
64
+ param {*} nodes 颜色位置,默认不提供,等间距
65
+ return {*} c_map
66
+ example : c_map = mk_cmap(['#C2B7F3','#B3BBF2','#B0CBF1','#ACDCF0','#A8EEED'])
67
+ c_map = mk_cmap(['aliceblue','skyblue','deepskyblue'],[0.0,0.5,1.0])
68
+ '''
69
+ if nodes is None: # 采取自动分配比例
70
+ cmap_color = mpl.colors.LinearSegmentedColormap.from_list(
71
+ 'mycmap', colors)
72
+ else: # 按照提供比例分配
73
+ cmap_color = mpl.colors.LinearSegmentedColormap.from_list(
74
+ "mycmap", list(zip(nodes, colors)))
75
+ return cmap_color
76
+
77
+ # ** 自制diverging型cmap,默认中间为白色
78
+
79
+
80
+ def create_diverging(colors: list):
81
+ '''
82
+ func : 自制cmap,双色,中间默认为白色;如果输入偶数个颜色,则中间为白,如果奇数个颜色,则中间色为中间色
83
+ description : colors可以是颜色名称,也可以是十六进制颜色代码
84
+ param {*} colors
85
+ return {*}
86
+ example : diverging_cmap = mk_cmap_diverging(["#00c0ff", "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247"])
87
+ '''
88
+ # 自定义颜色位置
89
+ n = len(colors)
90
+ nodes = np.linspace(0.0, 1.0, n + 1 if n % 2 == 0 else n)
91
+ newcolors = colors
92
+ if n % 2 == 0:
93
+ newcolors.insert(int(n / 2), '#ffffff') # 偶数个颜色,中间为白色
94
+ cmap_color = mpl.colors.LinearSegmentedColormap.from_list(
95
+ "mycmap", list(zip(nodes, newcolors)))
96
+ return cmap_color
97
+
98
+ # ** 根据RGB的txt文档制作色卡(利用Grads调色盘)
99
+
100
+
101
+ def create_5rgb_txt(rgb_txt_filepath: str): # 根据RGB的txt文档制作色卡/根据rgb值制作
102
+ '''
103
+ func : 根据RGB的txt文档制作色卡
104
+ description : rgb_txt_filepath='E:/python/colorbar/test.txt'
105
+ param {*} rgb_txt_filepath txt文件路径
106
+ return {*} camp
107
+ example : cmap_color=dcmap(path)
108
+ '''
109
+ with open(rgb_txt_filepath) as fid:
110
+ data = fid.readlines()
111
+ n = len(data)
112
+ rgb = np.zeros((n, 3))
113
+ for i in np.arange(n):
114
+ rgb[i][0] = data[i].split(',')[0]
115
+ rgb[i][1] = data[i].split(',')[1]
116
+ rgb[i][2] = data[i].split(',')[2]
117
+ max_rgb = np.max(rgb)
118
+ if max_rgb > 2: # 如果rgb值大于2,则认为是0-255的值,需要归一化
119
+ rgb = rgb / 255.0
120
+ icmap = mpl.colors.ListedColormap(rgb, name='my_color')
121
+ return icmap
122
+
123
+
124
+ if __name__ == '__main__':
125
+ # ** 测试自制cmap
126
+ colors = ['#C2B7F3', '#B3BBF2', '#B0CBF1', '#ACDCF0', '#A8EEED']
127
+ nodes = [0.0, 0.2, 0.4, 0.6, 1.0]
128
+ c_map = create_custom(colors, nodes)
129
+ show([c_map])
130
+
131
+ # ** 测试自制diverging型cmap
132
+ diverging_cmap = create_diverging(["#4e00b3", "#0000FF", "#00c0ff",
133
+ "#a1d3ff", "#DCDCDC", "#FFD39B", "#FF8247", "#FF0000", "#FF5F9E"])
134
+ show([diverging_cmap])
135
+
136
+ # ** 测试根据RGB的txt文档制作色卡
137
+ file_path = 'E:/python/colorbar/test.txt'
138
+ cmap_color = create_5rgb_txt(file_path)
139
+
140
+ # ** 测试将cmap转为list
141
+ out_cmap = extract_colors('viridis', 256)
oafuncs/oa_data.py ADDED
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ '''
4
+ Author: Liu Kun && 16031215@qq.com
5
+ Date: 2024-09-17 17:12:47
6
+ LastEditors: Liu Kun && 16031215@qq.com
7
+ LastEditTime: 2024-10-06 19:05:38
8
+ FilePath: \\Python\\My_Funcs\\OAFuncs\\OAFuncs\\oa_data.py
9
+ Description:
10
+ EditPlatform: vscode
11
+ ComputerInfo: XPS 15 9510
12
+ SystemInfo: Windows 11
13
+ Python Version: 3.11
14
+ '''
15
+
16
+
17
+
18
+ import multiprocessing as mp
19
+ from concurrent.futures import ThreadPoolExecutor
20
+
21
+ import numpy as np
22
+ from scipy.interpolate import griddata
23
+
24
+ __all__ = ['interp_2d', 'interp_2d_parallel']
25
+
26
+ # ** 高维插值函数,插值最后两个维度
27
+ def interp_2d(target_x, target_y, origin_x, origin_y, data, method='linear'):
28
+ """
29
+ 高维插值函数,默认插值最后两个维度,传输数据前请确保数据的维度正确
30
+ 参数:
31
+ target_y (array-like): 目标经度网格 1D 或 2D
32
+ target_x (array-like): 目标纬度网格 1D 或 2D
33
+ origin_y (array-like): 初始经度网格 1D 或 2D
34
+ origin_x (array-like): 初始纬度网格 1D 或 2D
35
+ data (array-like): 数据 (*, lat, lon) 2D, 3D, 4D
36
+ method (str, optional): 插值方法,可选 'linear', 'nearest', 'cubic' 等,默认为 'linear'
37
+ 返回:
38
+ array-like: 插值结果
39
+ """
40
+
41
+ # 确保目标网格和初始网格都是二维的
42
+ if len(target_y.shape) == 1:
43
+ target_x, target_y = np.meshgrid(target_x, target_y)
44
+ if len(origin_y.shape) == 1:
45
+ origin_x, origin_y = np.meshgrid(origin_x, origin_y)
46
+
47
+ dims = data.shape
48
+ len_dims = len(dims)
49
+ # print(dims[-2:])
50
+ # 根据经纬度网格判断输入数据的形状是否匹配
51
+
52
+ if origin_x.shape != dims[-2:] or origin_y.shape != dims[-2:]:
53
+ print(origin_x.shape, dims[-2:])
54
+ raise ValueError(
55
+ 'Shape of data does not match shape of origin_x or origin_y.')
56
+
57
+ # 将目标网格展平成一维数组
58
+ target_points = np.column_stack((np.ravel(target_y), np.ravel(target_x)))
59
+
60
+ # 将初始网格展平成一维数组
61
+ origin_points = np.column_stack((np.ravel(origin_y), np.ravel(origin_x)))
62
+
63
+ # 进行插值
64
+ if len_dims == 2:
65
+ interpolated_data = griddata(origin_points, np.ravel(
66
+ data), target_points, method=method)
67
+ interpolated_data = np.reshape(interpolated_data, target_y.shape)
68
+ elif len_dims == 3:
69
+ interpolated_data = []
70
+ for i in range(dims[0]):
71
+ dt = griddata(origin_points, np.ravel(
72
+ data[i, :, :]), target_points, method=method)
73
+ interpolated_data.append(np.reshape(dt, target_y.shape))
74
+ print(f'Interpolating {i+1}/{dims[0]}...')
75
+ interpolated_data = np.array(interpolated_data)
76
+ elif len_dims == 4:
77
+ interpolated_data = []
78
+ for i in range(dims[0]):
79
+ interpolated_data.append([])
80
+ for j in range(dims[1]):
81
+ dt = griddata(origin_points, np.ravel(
82
+ data[i, j, :, :]), target_points, method=method)
83
+ interpolated_data[i].append(np.reshape(dt, target_y.shape))
84
+ print(
85
+ f'\rInterpolating {i*dims[1]+j+1}/{dims[0]*dims[1]}...', end='')
86
+ print('\n')
87
+ interpolated_data = np.array(interpolated_data)
88
+
89
+ return interpolated_data
90
+
91
+
92
+ # ** 高维插值函数,插值最后两个维度,使用多线程进行插值
93
+ # 在本地电脑上可以提速三倍左右,超算上暂时无法加速
94
+ def interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='linear'):
95
+ '''
96
+ param {*} target_x 目标经度网格 1D 或 2D
97
+ param {*} target_y 目标纬度网格 1D 或 2D
98
+ param {*} origin_x 初始经度网格 1D 或 2D
99
+ param {*} origin_y 初始纬度网格 1D 或 2D
100
+ param {*} data 数据 (*, lat, lon) 2D, 3D, 4D
101
+ param {*} method 插值方法,可选 'linear', 'nearest', 'cubic' 等,默认为 'linear'
102
+ return {*} 插值结果
103
+ description : 高维插值函数,默认插值最后两个维度,传输数据前请确保数据的维度正确
104
+ example : interpolated_data = interp_2d_parallel(target_x, target_y, origin_x, origin_y, data, method='linear')
105
+ '''
106
+ def interp_single2d(target_y, target_x, origin_y, origin_x, data, method='linear'):
107
+ target_points = np.column_stack(
108
+ (np.ravel(target_y), np.ravel(target_x)))
109
+ origin_points = np.column_stack(
110
+ (np.ravel(origin_y), np.ravel(origin_x)))
111
+
112
+ dt = griddata(origin_points, np.ravel(
113
+ data[:, :]), target_points, method=method)
114
+ return np.reshape(dt, target_y.shape)
115
+
116
+ def interp_single3d(i, target_y, target_x, origin_y, origin_x, data, method='linear'):
117
+ target_points = np.column_stack(
118
+ (np.ravel(target_y), np.ravel(target_x)))
119
+ origin_points = np.column_stack(
120
+ (np.ravel(origin_y), np.ravel(origin_x)))
121
+
122
+ dt = griddata(origin_points, np.ravel(
123
+ data[i, :, :]), target_points, method=method)
124
+ return np.reshape(dt, target_y.shape)
125
+
126
+ def interp_single4d(i, j, target_y, target_x, origin_y, origin_x, data, method='linear'):
127
+ target_points = np.column_stack(
128
+ (np.ravel(target_y), np.ravel(target_x)))
129
+ origin_points = np.column_stack(
130
+ (np.ravel(origin_y), np.ravel(origin_x)))
131
+
132
+ dt = griddata(origin_points, np.ravel(
133
+ data[i, j, :, :]), target_points, method=method)
134
+ return np.reshape(dt, target_y.shape)
135
+
136
+ if len(target_y.shape) == 1:
137
+ target_x, target_y = np.meshgrid(target_x, target_y)
138
+ if len(origin_y.shape) == 1:
139
+ origin_x, origin_y = np.meshgrid(origin_x, origin_y)
140
+
141
+ dims = data.shape
142
+ len_dims = len(dims)
143
+
144
+ if origin_x.shape != dims[-2:] or origin_y.shape != dims[-2:]:
145
+ raise ValueError('数据形状与 origin_x 或 origin_y 的形状不匹配.')
146
+
147
+ interpolated_data = []
148
+
149
+ # 使用多线程进行插值
150
+ with ThreadPoolExecutor(max_workers=mp.cpu_count()-2) as executor:
151
+ print(f'Using {mp.cpu_count()-2} threads...')
152
+ if len_dims == 2:
153
+ interpolated_data = list(executor.map(interp_single2d, [target_y], [
154
+ target_x], [origin_y], [origin_x], [data], [method]))
155
+ elif len_dims == 3:
156
+ interpolated_data = list(executor.map(interp_single3d, [i for i in range(dims[0])], [
157
+ target_y]*dims[0], [target_x]*dims[0], [origin_y]*dims[0], [origin_x]*dims[0], [data]*dims[0], [method]*dims[0]))
158
+ elif len_dims == 4:
159
+ interpolated_data = list(executor.map(interp_single4d, [i for i in range(dims[0]) for j in range(dims[1])], [j for i in range(dims[0]) for j in range(dims[1])], [
160
+ target_y]*dims[0]*dims[1], [target_x]*dims[0]*dims[1], [origin_y]*dims[0]*dims[1], [origin_x]*dims[0]*dims[1], [data]*dims[0]*dims[1], [method]*dims[0]*dims[1]))
161
+ interpolated_data = np.array(interpolated_data).reshape(
162
+ dims[0], dims[1], target_y.shape[0], target_x.shape[1])
163
+
164
+ interpolated_data = np.array(interpolated_data)
165
+
166
+ return interpolated_data
167
+
168
+
169
+ if __name__ == '__main__':
170
+ import time
171
+
172
+ import matplotlib.pyplot as plt
173
+
174
+ # 测试数据
175
+ origin_x = np.linspace(0, 10, 11)
176
+ origin_y = np.linspace(0, 10, 11)
177
+ target_x = np.linspace(0, 10, 101)
178
+ target_y = np.linspace(0, 10, 101)
179
+ data = np.random.rand(11, 11)
180
+
181
+ # 高维插值
182
+ origin_x = np.linspace(0, 10, 11)
183
+ origin_y = np.linspace(0, 10, 11)
184
+ target_x = np.linspace(0, 10, 101)
185
+ target_y = np.linspace(0, 10, 101)
186
+ data = np.random.rand(10, 10, 11, 11)
187
+
188
+ start = time.time()
189
+ interpolated_data = interp_2d(target_x, target_y, origin_x, origin_y, data)
190
+ print(f'Interpolation time: {time.time()-start:.2f}s')
191
+
192
+ print(interpolated_data.shape)
193
+
194
+ # 高维插值多线程
195
+ start = time.time()
196
+ interpolated_data = interp_2d_parallel(
197
+ target_x, target_y, origin_x, origin_y, data)
198
+ print(f'Interpolation time: {time.time()-start:.2f}s')
199
+
200
+ print(interpolated_data.shape)
201
+ print(interpolated_data[0, 0, :, :].shape)
202
+ plt.figure()
203
+ plt.contourf(target_x, target_y, interpolated_data[0, 0, :, :])
204
+ plt.colorbar()
205
+ plt.show()
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ '''
4
+ Author: Liu Kun && 16031215@qq.com
5
+ Date: 2024-09-17 16:09:20
6
+ LastEditors: Liu Kun && 16031215@qq.com
7
+ LastEditTime: 2024-10-14 18:12:12
8
+ FilePath: \\Python\\My_Funcs\\OAFuncs\\OAFuncs\\oa_down\\__init__.py
9
+ Description:
10
+ EditPlatform: vscode
11
+ ComputerInfo: XPS 15 9510
12
+ SystemInfo: Windows 11
13
+ Python Version: 3.11
14
+ '''
15
+
16
+ # from .love_ocean import sign as love_ocean
17
+ # from .meteorological_home import sign as meteorological_home
18
+
19
+ from .hycom_3hourly import *
20
+ from .refs_pdf import *