shancx 1.9.33.109__py3-none-any.whl → 1.9.33.218__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.
- shancx/{Dsalgor → Algo}/__init__.py +37 -1
- shancx/Calmetrics/__init__.py +78 -9
- shancx/Calmetrics/calmetrics.py +14 -0
- shancx/Calmetrics/rmseR2score.py +14 -3
- shancx/{Command.py → Cmd.py} +20 -15
- shancx/Config_.py +26 -0
- shancx/Df/__init__.py +11 -0
- shancx/Df/tool.py +0 -1
- shancx/NN/__init__.py +200 -11
- shancx/{path.py → Path1.py} +2 -3
- shancx/Plot/__init__.py +129 -403
- shancx/Plot/draw_day_CR_PNG.py +4 -21
- shancx/Plot/exam.py +116 -0
- shancx/Plot/plotGlobal.py +325 -0
- shancx/Plot/radarNmc.py +1 -48
- shancx/Plot/single_china_map.py +1 -1
- shancx/Point.py +46 -0
- shancx/QC.py +223 -0
- shancx/Read.py +17 -10
- shancx/Resize.py +79 -0
- shancx/SN/__init__.py +8 -1
- shancx/Time/timeCycle.py +97 -23
- shancx/Train/makelist.py +161 -155
- shancx/__init__.py +79 -232
- shancx/bak.py +78 -53
- shancx/geosProj.py +2 -2
- shancx/wait.py +35 -1
- {shancx-1.9.33.109.dist-info → shancx-1.9.33.218.dist-info}/METADATA +12 -4
- shancx-1.9.33.218.dist-info/RECORD +91 -0
- {shancx-1.9.33.109.dist-info → shancx-1.9.33.218.dist-info}/WHEEL +1 -1
- shancx/Plot/Mip.py +0 -42
- shancx/Plot/border.py +0 -44
- shancx/Plot/draw_day_CR_PNGUS.py +0 -206
- shancx/Plot/draw_day_CR_SVG.py +0 -275
- shancx/Plot/draw_day_pre_PNGUS.py +0 -205
- shancx/Plot/radar_nmc_china_map_compare1.py +0 -50
- shancx/makenetCDFN.py +0 -42
- shancx-1.9.33.109.dist-info/RECORD +0 -91
- /shancx/{3DJU → 3D}/__init__.py +0 -0
- /shancx/{Dsalgor → Algo}/Class.py +0 -0
- /shancx/{Dsalgor → Algo}/CudaPrefetcher1.py +0 -0
- /shancx/{Dsalgor → Algo}/Fake_image.py +0 -0
- /shancx/{Dsalgor → Algo}/Hsml.py +0 -0
- /shancx/{Dsalgor → Algo}/L2Loss.py +0 -0
- /shancx/{Dsalgor → Algo}/MetricTracker.py +0 -0
- /shancx/{Dsalgor → Algo}/Normalize.py +0 -0
- /shancx/{Dsalgor → Algo}/OptimizerWScheduler.py +0 -0
- /shancx/{Dsalgor → Algo}/Rmageresize.py +0 -0
- /shancx/{Dsalgor → Algo}/Savemodel.py +0 -0
- /shancx/{Dsalgor → Algo}/SmoothL1_losses.py +0 -0
- /shancx/{Dsalgor → Algo}/Tqdm.py +0 -0
- /shancx/{Dsalgor → Algo}/checknan.py +0 -0
- /shancx/{Dsalgor → Algo}/dsalgor.py +0 -0
- /shancx/{Dsalgor → Algo}/iouJU.py +0 -0
- /shancx/{Dsalgor → Algo}/mask.py +0 -0
- /shancx/{Dsalgor → Algo}/psnr.py +0 -0
- /shancx/{Dsalgor → Algo}/ssim.py +0 -0
- /shancx/{Dsalgor → Algo}/structural_similarity.py +0 -0
- /shancx/{Dsalgor → Algo}/tool.py +0 -0
- /shancx/Calmetrics/{matrixLib.py → calmetricsmatrixLib.py} +0 -0
- /shancx/{Diffmodel → Diffm}/Psamples.py +0 -0
- /shancx/{Diffmodel → Diffm}/__init__.py +0 -0
- /shancx/{Diffmodel → Diffm}/test.py +0 -0
- /shancx/{Board → tensBoard}/__init__.py +0 -0
- {shancx-1.9.33.109.dist-info → shancx-1.9.33.218.dist-info}/top_level.txt +0 -0
shancx/Plot/draw_day_CR_PNG.py
CHANGED
|
@@ -29,7 +29,6 @@ import cartopy.io.shapereader as shpreader
|
|
|
29
29
|
from shancx import crDir
|
|
30
30
|
|
|
31
31
|
def add_china_map(ax):
|
|
32
|
-
# 在地图上添加地形特征
|
|
33
32
|
ax.add_feature(cfeature.COASTLINE, edgecolor='gray')
|
|
34
33
|
ax.add_feature(cfeature.BORDERS, linestyle=':', edgecolor='gray')
|
|
35
34
|
ax.add_feature(cfeature.LAKES, alpha=0.8)
|
|
@@ -38,28 +37,14 @@ def add_china_map(ax):
|
|
|
38
37
|
provinces_features = shpreader.Reader(provinces).geometries()
|
|
39
38
|
ax.add_geometries(provinces_features, ccrs.PlateCarree(), facecolor='none', edgecolor='gray', linestyle=':', linewidth=0.5, alpha=0.8)
|
|
40
39
|
|
|
41
|
-
|
|
42
40
|
def draw_subplot(args):
|
|
43
41
|
index, tp, vmax, vmin, cmap,time_index, name = args
|
|
44
|
-
# print(time_index)
|
|
45
|
-
# logger.info(f"Processing index: {index}")
|
|
46
|
-
# logger.info(time_index)
|
|
47
42
|
fig, ax = plt.subplots(figsize=(10, 10))
|
|
48
|
-
|
|
49
|
-
# 创建绘图和设置坐标系
|
|
50
|
-
# fig = plt.figure(figsize=(10, 8))
|
|
51
43
|
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
|
|
52
|
-
|
|
53
|
-
# 设置图像显示的范围
|
|
54
|
-
ax.set_extent([73, 135, 18, 54], ccrs.PlateCarree()) # 根据需要调整
|
|
55
|
-
|
|
56
|
-
# 添加中国地图的边界和特征,包括省份轮廓
|
|
44
|
+
ax.set_extent([73, 135, 18, 54], ccrs.PlateCarree())
|
|
57
45
|
add_china_map(ax)
|
|
46
|
+
ax.imshow(tp, vmin=0, vmax=100, cmap=cmp_hjnwtx["radar_nmc"], transform=ccrs.PlateCarree(), extent=[73, 134.99, 12.21, 54.2], alpha=1)
|
|
58
47
|
|
|
59
|
-
ax.imshow(tp, vmin=0, vmax=100, cmap=cmp_hjnwtx["radar_nmc"], transform=ccrs.PlateCarree(), extent=[73, 134.99, 12.21, 54.2], alpha=1)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# ax.imshow(tp, vmax=vmax, vmin=vmin, cmap=cmap)
|
|
63
48
|
ax.axis('off')
|
|
64
49
|
# ax.text(0.5, 0.5, str(index), transform=ax.transAxes, color='white', fontsize=20, ha='center', va='center')
|
|
65
50
|
ax.text(0.95, 0.95, f'{time_index}', transform=ax.transAxes, color='white', fontsize=20, ha='right', va='bottom')
|
|
@@ -70,9 +55,8 @@ def draw_subplot(args):
|
|
|
70
55
|
plt.savefig(buf, format='png')
|
|
71
56
|
buf.seek(0)
|
|
72
57
|
plt.close(fig)
|
|
73
|
-
return (index, buf)
|
|
58
|
+
return (index, buf)
|
|
74
59
|
|
|
75
|
-
# 修改读取部分
|
|
76
60
|
def drawpic(tp, Count,timeList, name="temp"):
|
|
77
61
|
vmax = 70
|
|
78
62
|
vmin = 0
|
|
@@ -193,8 +177,7 @@ if __name__ == '__main__':
|
|
|
193
177
|
drawpic(Data_con_120[int(len(Data_con_120)/2):], int(len(Data_con_120)/4),timeList[int(len(Data_con_120)/2):],name=f"temp120_240_{sCSTstr}_{loss_len}_")
|
|
194
178
|
print(datetime.datetime.now()-end1)
|
|
195
179
|
print("done 120-240")
|
|
196
|
-
logger.info("success")
|
|
197
|
-
|
|
180
|
+
logger.info("success")
|
|
198
181
|
|
|
199
182
|
# "/mnt/wtx_weather_forecast/WTX_DATA/RADA/MQPF/2024/20240704/MSP2_WTX_AIW_REF_L88_CHN_202407040324_00000-00300-00006.nc"
|
|
200
183
|
|
shancx/Plot/exam.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from matplotlib import pyplot as plt
|
|
2
|
+
import numpy as np
|
|
3
|
+
def drawHigh_new(TSV,F1V,ACCV,outpath):
|
|
4
|
+
TS_WTX = np.asarray(list(TSV.values()))
|
|
5
|
+
F1_WTX = np.asarray(list(F1V.values()))
|
|
6
|
+
ACC_WTX =np.asarray(list(ACCV.values()))
|
|
7
|
+
time = ['1h', '2h','3h']
|
|
8
|
+
TS_WTX = np.asarray(list(TSV.values()))
|
|
9
|
+
plt.figure(figsize=(6, 4))
|
|
10
|
+
inspect_flag = "TS"
|
|
11
|
+
plt.subplot(131)
|
|
12
|
+
bar_width = 0.3
|
|
13
|
+
plt.bar(time,[TS_WTX[0][0],TS_WTX[1][0],TS_WTX[2][0]], width=bar_width , label='WTX')
|
|
14
|
+
plt.xlabel('Time')
|
|
15
|
+
plt.ylabel(f'{inspect_flag}')
|
|
16
|
+
plt.title(f'{inspect_flag}')
|
|
17
|
+
plt.grid(axis="y")
|
|
18
|
+
inspect_flag = "F1"
|
|
19
|
+
TS_WTX = np.asarray(list(TSV.values()))
|
|
20
|
+
plt.subplot(132)
|
|
21
|
+
bar_width = 0.3
|
|
22
|
+
plt.bar(time,[F1_WTX[0][0],F1_WTX[1][0],F1_WTX[2][0]], width=bar_width , label='WTX')
|
|
23
|
+
plt.xlabel('Time')
|
|
24
|
+
plt.ylabel(f'{inspect_flag}')
|
|
25
|
+
plt.title(f'{inspect_flag}')
|
|
26
|
+
plt.grid(axis="y")
|
|
27
|
+
inspect_flag = "ACC"
|
|
28
|
+
TS_WTX = np.asarray(list(TSV.values()))
|
|
29
|
+
plt.subplot(133)
|
|
30
|
+
bar_width = 0.3
|
|
31
|
+
plt.bar(time,[ACC_WTX[0][0],ACC_WTX[1][0],F1_WTX[2][0]], width=bar_width , label='WTX')
|
|
32
|
+
plt.xlabel('Time')
|
|
33
|
+
plt.ylabel(f'{inspect_flag}')
|
|
34
|
+
plt.title(f'{inspect_flag}')
|
|
35
|
+
plt.grid(axis="y")
|
|
36
|
+
plt.tight_layout()
|
|
37
|
+
plt.savefig(outpath)
|
|
38
|
+
plt.close()
|
|
39
|
+
|
|
40
|
+
def drawLow_new(POV,FARV,outpath):
|
|
41
|
+
time = ['1h', '2h']
|
|
42
|
+
PO_WTX = np.asarray(list(POV.values()))
|
|
43
|
+
FAR_WTX = np.asarray(list(FARV.values()))
|
|
44
|
+
inspect_flag = "PO"
|
|
45
|
+
time = ['1h', '2h','3h']
|
|
46
|
+
plt.figure(figsize=(6, 4))
|
|
47
|
+
plt.subplot(121)
|
|
48
|
+
bar_width = 0.3
|
|
49
|
+
plt.bar(time,[PO_WTX[0][0],PO_WTX[1][0],PO_WTX[2][0]], width=bar_width , label='WTX')
|
|
50
|
+
plt.xlabel('Time')
|
|
51
|
+
plt.ylabel(f'{inspect_flag}')
|
|
52
|
+
plt.title(f'{inspect_flag}')
|
|
53
|
+
plt.grid(axis="y")
|
|
54
|
+
plt.tight_layout()
|
|
55
|
+
inspect_flag = "FAR"
|
|
56
|
+
plt.subplot(122)
|
|
57
|
+
bar_width = 0.3
|
|
58
|
+
plt.bar(time,[FAR_WTX[0][0],FAR_WTX[1][0],FAR_WTX[2][0]], width=bar_width , label='WTX')
|
|
59
|
+
plt.xlabel('Time')
|
|
60
|
+
plt.ylabel(f'{inspect_flag}')
|
|
61
|
+
plt.title(f'{inspect_flag}')
|
|
62
|
+
# plt.xticks(index + bar_width / 2, time)
|
|
63
|
+
plt.grid(axis="y")
|
|
64
|
+
plt.tight_layout()
|
|
65
|
+
plt.savefig(outpath)
|
|
66
|
+
plt.close()
|
|
67
|
+
"""
|
|
68
|
+
POV = {}
|
|
69
|
+
for i in range(1,4):
|
|
70
|
+
F1hm =PO(df[f"PRE{i}_r"], df[f"PRE{i}_w"])
|
|
71
|
+
POV[i] = [np.round(F1hm, 3)]
|
|
72
|
+
POV
|
|
73
|
+
{1: [0.45], 2: [0.67], 3: [0.778]}
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def drawLow(POV,FARV,outpath):
|
|
77
|
+
time = ['1h', '2h']
|
|
78
|
+
PO_CY = np.asarray(list(POV.values()))[:,0].astype(float)
|
|
79
|
+
PO_WTX = np.asarray(list(POV.values()))[:,1].astype(float)
|
|
80
|
+
FAR_CY = np.asarray(list(FARV.values()))[:,0].astype(float)
|
|
81
|
+
FAR_WTX = np.asarray(list(FARV.values()))[:,1].astype(float)
|
|
82
|
+
plt.figure(figsize=(8, 4))
|
|
83
|
+
bar_width = 0.35
|
|
84
|
+
index = np.arange(len(time))
|
|
85
|
+
x_pos = index + bar_width / 2 # 刻度标签位置
|
|
86
|
+
plt.subplot(121)
|
|
87
|
+
plt.bar(index, PO_CY, bar_width, label='CY')
|
|
88
|
+
plt.bar(index + bar_width, PO_WTX, bar_width, label='WTX')
|
|
89
|
+
plt.xlabel('Time')
|
|
90
|
+
plt.ylabel('PO')
|
|
91
|
+
plt.title('PO 对比')
|
|
92
|
+
plt.xticks(x_pos, time)
|
|
93
|
+
plt.legend()
|
|
94
|
+
plt.grid(axis="y")
|
|
95
|
+
plt.subplot(122)
|
|
96
|
+
plt.bar(index, FAR_CY, bar_width, label='CY')
|
|
97
|
+
plt.bar(index + bar_width, FAR_WTX, bar_width, label='WTX')
|
|
98
|
+
plt.xlabel('Time')
|
|
99
|
+
plt.ylabel('FAR')
|
|
100
|
+
plt.title('FAR 对比')
|
|
101
|
+
plt.xticks(x_pos, time)
|
|
102
|
+
plt.legend()
|
|
103
|
+
plt.grid(axis="y")
|
|
104
|
+
plt.tight_layout()
|
|
105
|
+
plt.savefig(outpath)
|
|
106
|
+
plt.close()
|
|
107
|
+
"""
|
|
108
|
+
POV = {}
|
|
109
|
+
for i in range(1,3):
|
|
110
|
+
F1h =PO(df[f"PRE{i}_r"], df[f"PRE{i}_c"],thresholdF=thresholdF)
|
|
111
|
+
F1hm =PO(df[f"PRE{i}_r"], df[f"PRE{i}_w"])
|
|
112
|
+
POV[i] = [np.round(F1h, 3), np.round(F1hm, 3),f"{np.round((F1hm-F1h)/F1h*100,2)*-1}%"]
|
|
113
|
+
print(f"{i}h {np.round(F1h,3)} {np.round(F1hm,3)} {np.round((F1hm-F1h)/F1h*100,2)*-1}%")
|
|
114
|
+
POV CY WTX
|
|
115
|
+
{1: [0.778, 0.556, '28.57%'], 2: [1.0, 0.875, '12.5%']}
|
|
116
|
+
"""
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import ssl
|
|
4
|
+
import urllib.request
|
|
5
|
+
ssl._create_default_https_context = ssl._create_unverified_context
|
|
6
|
+
import datetime
|
|
7
|
+
import numpy as np
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
import cartopy.crs as ccrs
|
|
10
|
+
import cartopy.feature as cfeature
|
|
11
|
+
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
|
|
12
|
+
from hjnwtx.colormap import cmp_hjnwtx
|
|
13
|
+
import os
|
|
14
|
+
def plotGlobal(b, latArr1, lonArr1, cmap='summer', title='Global QPF Data Visualization',saveDir = "./plotGlobal",ty=None ):
|
|
15
|
+
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
16
|
+
plt.figure(figsize=(20, 10), dpi=100)
|
|
17
|
+
ax = plt.axes(projection=ccrs.PlateCarree())
|
|
18
|
+
ax.add_feature(cfeature.LAND, facecolor='none') # 陆地无色
|
|
19
|
+
ax.add_feature(cfeature.OCEAN, facecolor='none') # 海洋无色
|
|
20
|
+
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, edgecolor='black') # 海岸线黑色
|
|
21
|
+
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=0.5, edgecolor='black') # 国界线黑色
|
|
22
|
+
ax.add_feature(cfeature.LAKES, alpha=0.3, facecolor='none', edgecolor='gray') # 湖泊无色,灰色边界
|
|
23
|
+
ax.add_feature(cfeature.RIVERS, edgecolor='gray', linewidth=0.5) # 河流灰色
|
|
24
|
+
lon_grid, lat_grid = np.meshgrid(lonArr1, latArr1)
|
|
25
|
+
stride = 10 # 每10个点取1个
|
|
26
|
+
cmap = {
|
|
27
|
+
"radar": cmp_hjnwtx["radar_nmc"],
|
|
28
|
+
"pre": cmp_hjnwtx["pre_tqw"],
|
|
29
|
+
None: 'summer'
|
|
30
|
+
}.get(ty)
|
|
31
|
+
img = ax.pcolormesh(lon_grid[::stride, ::stride],
|
|
32
|
+
lat_grid[::stride, ::stride],
|
|
33
|
+
b[::stride, ::stride],
|
|
34
|
+
cmap=cmap,
|
|
35
|
+
shading='auto',
|
|
36
|
+
transform=ccrs.PlateCarree())
|
|
37
|
+
cbar = plt.colorbar(img, ax=ax, orientation='vertical', pad=0.05, shrink=0.6)
|
|
38
|
+
cbar.set_label('Value Scale', fontsize=12)
|
|
39
|
+
ax.set_xticks(np.arange(-180, 181, 30), crs=ccrs.PlateCarree())
|
|
40
|
+
ax.set_yticks(np.arange(-90, 91, 15), crs=ccrs.PlateCarree())
|
|
41
|
+
ax.xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label=True))
|
|
42
|
+
ax.yaxis.set_major_formatter(LatitudeFormatter())
|
|
43
|
+
ax.gridlines(color='gray', linestyle=':', alpha=0.5)
|
|
44
|
+
ax.set_title(title, fontsize=16, pad=20)
|
|
45
|
+
ax.set_global()
|
|
46
|
+
plt.tight_layout()
|
|
47
|
+
os.makedirs(saveDir, exist_ok=True)
|
|
48
|
+
plt.savefig(f"./{saveDir}/plotScatter_glob{now_str}.png", dpi=300, bbox_inches="tight")
|
|
49
|
+
plt.close()
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
plotGlobal(b, latArr1, lonArr1,
|
|
53
|
+
title='Global Meteorological Data',ty="radar")
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
import datetime
|
|
58
|
+
import numpy as np
|
|
59
|
+
import matplotlib.pyplot as plt
|
|
60
|
+
import cartopy.crs as ccrs
|
|
61
|
+
import cartopy.feature as cfeature
|
|
62
|
+
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
|
|
63
|
+
from hjnwtx.colormap import cmp_hjnwtx
|
|
64
|
+
import os
|
|
65
|
+
|
|
66
|
+
def plotGlobalPlus(b, latArr1, lonArr1, cmap='summer', title='Global QPF Data Visualization',
|
|
67
|
+
saveDir="./plotGlobal", ty=None, cartopy_data_dir="./share/cartopy"):
|
|
68
|
+
os.environ['CARTOPY_USER_BACKGROUNDS'] = cartopy_data_dir
|
|
69
|
+
os.makedirs(cartopy_data_dir, exist_ok=True)
|
|
70
|
+
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
71
|
+
plt.figure(figsize=(20, 10), dpi=100)
|
|
72
|
+
ax = plt.axes(projection=ccrs.PlateCarree())
|
|
73
|
+
try:
|
|
74
|
+
ax.add_feature(cfeature.LAND.with_scale('110m'), facecolor='none')
|
|
75
|
+
ax.add_feature(cfeature.OCEAN.with_scale('110m'), facecolor='none')
|
|
76
|
+
ax.add_feature(cfeature.COASTLINE.with_scale('110m'), linewidth=0.8, edgecolor='black')
|
|
77
|
+
ax.add_feature(cfeature.BORDERS.with_scale('110m'), linestyle='-', linewidth=0.5, edgecolor='black')
|
|
78
|
+
ax.add_feature(cfeature.LAKES.with_scale('110m'), alpha=0.3, facecolor='none', edgecolor='gray')
|
|
79
|
+
ax.add_feature(cfeature.RIVERS.with_scale('110m'), edgecolor='gray', linewidth=0.5)
|
|
80
|
+
except:
|
|
81
|
+
ax.add_feature(cfeature.LAND, facecolor='none')
|
|
82
|
+
ax.add_feature(cfeature.OCEAN, facecolor='none')
|
|
83
|
+
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, edgecolor='black')
|
|
84
|
+
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=0.5, edgecolor='black')
|
|
85
|
+
ax.add_feature(cfeature.LAKES, alpha=0.3, facecolor='none', edgecolor='gray')
|
|
86
|
+
ax.add_feature(cfeature.RIVERS, edgecolor='gray', linewidth=0.5)
|
|
87
|
+
lon_grid, lat_grid = np.meshgrid(lonArr1, latArr1)
|
|
88
|
+
stride = 10 # 每10个点取1个
|
|
89
|
+
cmap = {
|
|
90
|
+
"radar": cmp_hjnwtx["radar_nmc"],
|
|
91
|
+
"pre": cmp_hjnwtx["pre_tqw"],
|
|
92
|
+
None: cmap
|
|
93
|
+
}.get(ty, cmap)
|
|
94
|
+
img = ax.pcolormesh(lon_grid[::stride, ::stride],
|
|
95
|
+
lat_grid[::stride, ::stride],
|
|
96
|
+
b[::stride, ::stride],
|
|
97
|
+
cmap=cmap,
|
|
98
|
+
shading='auto',
|
|
99
|
+
transform=ccrs.PlateCarree())
|
|
100
|
+
cbar = plt.colorbar(img, ax=ax, orientation='vertical', pad=0.05, shrink=0.6)
|
|
101
|
+
cbar.set_label('Value Scale', fontsize=12)
|
|
102
|
+
ax.set_xticks(np.arange(-180, 181, 30), crs=ccrs.PlateCarree())
|
|
103
|
+
ax.set_yticks(np.arange(-90, 91, 15), crs=ccrs.PlateCarree())
|
|
104
|
+
ax.xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label=True))
|
|
105
|
+
ax.yaxis.set_major_formatter(LatitudeFormatter())
|
|
106
|
+
ax.gridlines(color='gray', linestyle=':', alpha=0.5)
|
|
107
|
+
ax.set_title(title, fontsize=16, pad=20)
|
|
108
|
+
ax.set_global()
|
|
109
|
+
plt.tight_layout()
|
|
110
|
+
os.makedirs(saveDir, exist_ok=True)
|
|
111
|
+
save_path = os.path.join(saveDir, f"plotScatter_glob{now_str}.png")
|
|
112
|
+
plt.savefig(save_path, dpi=300, bbox_inches="tight")
|
|
113
|
+
plt.close()
|
|
114
|
+
print(f"图像已保存到: {save_path}")
|
|
115
|
+
return save_path
|
|
116
|
+
"""
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
plotGlobal(
|
|
119
|
+
b=CR,
|
|
120
|
+
latArr1=latArr,
|
|
121
|
+
lonArr1=lonArr,
|
|
122
|
+
title='Global Precipitation Forecast',
|
|
123
|
+
saveDir='./output',
|
|
124
|
+
ty='pre',
|
|
125
|
+
cartopy_data_dir='./share/cartopy'
|
|
126
|
+
)
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
import ssl
|
|
130
|
+
import urllib.request
|
|
131
|
+
ssl._create_default_https_context = ssl._create_unverified_context
|
|
132
|
+
import matplotlib.pyplot as plt
|
|
133
|
+
import cartopy.crs as ccrs
|
|
134
|
+
import cartopy.feature as cfeature
|
|
135
|
+
import os
|
|
136
|
+
import datetime
|
|
137
|
+
import numpy as np
|
|
138
|
+
def plotScatter(df1, title = "Total number ",saveDir="plotScatter", map_background=True,
|
|
139
|
+
projection=ccrs.PlateCarree(), figsize=(12, 8)):
|
|
140
|
+
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
141
|
+
if map_background:
|
|
142
|
+
fig = plt.figure(figsize=figsize)
|
|
143
|
+
ax = plt.axes(projection=projection)
|
|
144
|
+
ax.add_feature(cfeature.LAND, facecolor='none', alpha=0.3)
|
|
145
|
+
ax.add_feature(cfeature.OCEAN, facecolor='none', alpha=0.3)
|
|
146
|
+
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, edgecolor='black')
|
|
147
|
+
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=0.5, edgecolor='black')
|
|
148
|
+
ax.add_feature(cfeature.LAKES, alpha=0.3, facecolor='gray')
|
|
149
|
+
ax.add_feature(cfeature.RIVERS, edgecolor='gray', linewidth=0.5)
|
|
150
|
+
ax.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='--')
|
|
151
|
+
if len(df1) > 0:
|
|
152
|
+
buffer = 5 # 边距
|
|
153
|
+
min_lon, max_lon = df1["Lon"].min() - buffer, df1["Lon"].max() + buffer
|
|
154
|
+
min_lat, max_lat = df1["Lat"].min() - buffer, df1["Lat"].max() + buffer
|
|
155
|
+
# ax.set_extent([min_lon, max_lon, min_lat, max_lat], crs=ccrs.PlateCarree())
|
|
156
|
+
ax.set_global()
|
|
157
|
+
else:
|
|
158
|
+
ax.set_global() # 如果没有数据,显示全球
|
|
159
|
+
scatter = ax.scatter(
|
|
160
|
+
df1["Lon"],
|
|
161
|
+
df1["Lat"],
|
|
162
|
+
s=0.5,
|
|
163
|
+
alpha=0.7,
|
|
164
|
+
edgecolor="red",
|
|
165
|
+
linewidth=0.5,
|
|
166
|
+
color='red',
|
|
167
|
+
transform=ccrs.PlateCarree(), # 重要:指定坐标变换
|
|
168
|
+
zorder=10 # 确保散点在地图上方
|
|
169
|
+
)
|
|
170
|
+
plt.title(title, fontsize=14, pad=20)
|
|
171
|
+
|
|
172
|
+
plt.tight_layout()
|
|
173
|
+
os.makedirs(saveDir, exist_ok=True)
|
|
174
|
+
plt.savefig(f"./{saveDir}/plotScatter_{now_str}.png", dpi=300, bbox_inches="tight")
|
|
175
|
+
plt.close()
|
|
176
|
+
print(f"散点图已保存到: ./{saveDir}/plotScatter_{now_str}.png")
|
|
177
|
+
print(f"总共绘制了 {len(df1)} 个点")
|
|
178
|
+
|
|
179
|
+
"""
|
|
180
|
+
plotScatter(df2,title = f" Total number of stations ", saveDir="scatter_maps")
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
import ssl
|
|
184
|
+
import urllib.request
|
|
185
|
+
ssl._create_default_https_context = ssl._create_unverified_context
|
|
186
|
+
import datetime
|
|
187
|
+
import numpy as np
|
|
188
|
+
import matplotlib.pyplot as plt
|
|
189
|
+
import cartopy.crs as ccrs
|
|
190
|
+
import cartopy.feature as cfeature
|
|
191
|
+
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
|
|
192
|
+
from hjnwtx.colormap import cmp_hjnwtx
|
|
193
|
+
from shancx import crDir
|
|
194
|
+
def plotBorder(UTCstr, nclon, nclat, cr, fig_title,savepath="./plotBorder", datatype=None,font_path=None,shp_file="./"):
|
|
195
|
+
myfont = mpl.font_manager.FontProperties(fname = font_path, size = 12)
|
|
196
|
+
figpath = f"{savepath}/fig/{UTCstr[:4]}/{UTCstr[:8]}/{fig_title}.PNG"
|
|
197
|
+
crDir(figpath)
|
|
198
|
+
lonmin = np.min(nclon)
|
|
199
|
+
lonmax = np.max(nclon)
|
|
200
|
+
latmin = np.min(nclat)
|
|
201
|
+
latmax = np.max(nclat)
|
|
202
|
+
# 创建图形和坐标轴
|
|
203
|
+
fig = plt.figure(figsize=(6, 6))
|
|
204
|
+
ax = plt.axes(projection=ccrs.PlateCarree())
|
|
205
|
+
# 1. 首先添加Cartopy的基础地理要素(作为底层)
|
|
206
|
+
ax.add_feature(cfeature.OCEAN, facecolor='none') # 海洋无色
|
|
207
|
+
ax.add_feature(cfeature.LAND, facecolor='none') # 陆地无色
|
|
208
|
+
ax.add_feature(cfeature.COASTLINE, linewidth=0.8, edgecolor='gray') # 海岸线
|
|
209
|
+
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=0.5, edgecolor='gray') # 国界线
|
|
210
|
+
ax.add_feature(cfeature.LAKES, alpha=0.3, facecolor='none', edgecolor='gray') # 湖泊
|
|
211
|
+
ax.add_feature(cfeature.RIVERS, edgecolor='gray', linewidth=0.5) # 河流
|
|
212
|
+
ax.set_xticks(np.arange(lonmin, lonmax + 0.1, 15))
|
|
213
|
+
ax.set_yticks(np.arange(latmin, latmax + 0.1, 10))
|
|
214
|
+
ax.set_xlim([nclon[0], nclon[-1]])
|
|
215
|
+
ax.set_ylim([nclat[-1], nclat[0]])
|
|
216
|
+
ax.xaxis.set_major_formatter(LongitudeFormatter())
|
|
217
|
+
ax.yaxis.set_major_formatter(LatitudeFormatter())
|
|
218
|
+
ax.tick_params(axis='both', labelsize=10)
|
|
219
|
+
# 3. 叠加自定义的省界矢量(显示在基础地理要素之上)
|
|
220
|
+
if os.path.exists(shp_file) and shp_file[-4:]==".shp" :
|
|
221
|
+
try:
|
|
222
|
+
shp = gpd.read_file(shp_file).boundary
|
|
223
|
+
# 使用较细的线宽,避免与国界线混淆
|
|
224
|
+
shp.plot(ax=ax, edgecolor='grey', linewidth=0.5, linestyle='-')
|
|
225
|
+
except Exception as e:
|
|
226
|
+
print(f"警告:读取矢量文件 {shp_file} 失败: {e}")
|
|
227
|
+
else:
|
|
228
|
+
print(f"警告:矢量文件 {shp_file} 不存在,将只绘制Cartopy地理要素。")
|
|
229
|
+
ax.set_title(fig_title, fontsize=12, loc='center', fontproperties=myfont)
|
|
230
|
+
# 5. 绘制雷达或降雨数据(在最上层)
|
|
231
|
+
if datatype == 'radar':
|
|
232
|
+
clevels = [0, 10, 20, 30, 40, 50, 60, 70]
|
|
233
|
+
colors = ['#62e6eaff', '#00d72eff', '#fefe3fff', '#ff9a29ff', '#d70e15ff', '#ff1cecff', '#af91edff']
|
|
234
|
+
elif datatype == 'rain':
|
|
235
|
+
clevels = [0.1, 2.5, 8, 16, 200]
|
|
236
|
+
colors = ["#a6f28f", "#3dba3d", "#61b8ff", "#0000ff"]
|
|
237
|
+
cs = plt.contourf(nclon, nclat, cr, levels=clevels, colors=colors, extend='both')
|
|
238
|
+
cb = plt.colorbar(cs, fraction=0.022, pad=0.03)
|
|
239
|
+
cb.set_ticks(clevels[:-1])
|
|
240
|
+
cb.set_ticklabels([str(level) for level in clevels[:-1]], fontproperties=myfont)
|
|
241
|
+
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
|
242
|
+
label.set_fontproperties(myfont)
|
|
243
|
+
plt.savefig(figpath, dpi=300, bbox_inches='tight')
|
|
244
|
+
print(f"{fig_title.split('_')[0]}绘制完成: {figpath}")
|
|
245
|
+
plt.close()
|
|
246
|
+
|
|
247
|
+
"""
|
|
248
|
+
latArr = np.linspace(27, -13, 2000 )
|
|
249
|
+
lonArr = np.linspace(70, 150, 4000)
|
|
250
|
+
font_path = '/mnt/wtx_weather_forecast/scx/sever7/微软雅黑.ttf'
|
|
251
|
+
|
|
252
|
+
fig_title = f"实况雷达回波_{UTCstr}_test"
|
|
253
|
+
baseCR[:,900:3700] = CR
|
|
254
|
+
plotBorder(UTCstr,lonArr,latArr,baseCR,fig_title,datatype="radar",font_path=font_path)
|
|
255
|
+
fig_title = f"卫星反演雷达回波_{UTCstr}"
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
import matplotlib as mpl
|
|
259
|
+
import matplotlib.pyplot as plt
|
|
260
|
+
import cartopy.crs as ccrs
|
|
261
|
+
import geopandas as gpd
|
|
262
|
+
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
|
|
263
|
+
import numpy as np
|
|
264
|
+
from shancx import crDir
|
|
265
|
+
def plot_fig1(cr,nclat,nclon,fig_title,datatype=None,savepath=None,font_path=None,shp_file=None):
|
|
266
|
+
figpath = f"{savepath}/fig/{fig_title.split('_')[1][:4]}/{fig_title.split('_')[1][:8]}/{fig_title.split('_')[1][:12]}/{fig_title}.PNG"
|
|
267
|
+
# if not os.path.exists(figpath):
|
|
268
|
+
lonmin = np.min(nclon)
|
|
269
|
+
lonmax = np.max(nclon)
|
|
270
|
+
latmin = np.min(nclat)
|
|
271
|
+
latmax = np.max(nclat)
|
|
272
|
+
myfont = mpl.font_manager.FontProperties(fname = font_path, size = 12)
|
|
273
|
+
fig = plt.figure(figsize=(6,6))
|
|
274
|
+
ax = plt.axes(projection=ccrs.PlateCarree())
|
|
275
|
+
ax.set_xticks(np.arange(lonmin, lonmax + 0.1, 15))
|
|
276
|
+
ax.set_yticks(np.arange(latmin, latmax + 0.1, 10))
|
|
277
|
+
ax.set_xlim([lonmin, lonmax])
|
|
278
|
+
ax.set_ylim([latmin, latmax])
|
|
279
|
+
ax.xaxis.set_major_formatter(LongitudeFormatter()) #刻度格式转换为经纬度样式
|
|
280
|
+
ax.yaxis.set_major_formatter(LatitudeFormatter())
|
|
281
|
+
ax.tick_params(axis = 'both',labelsize = 10)
|
|
282
|
+
shp = gpd.read_file(shp_file).boundary
|
|
283
|
+
shp.plot(ax=ax, edgecolor='grey', linewidth=0.7)
|
|
284
|
+
ax.set_title(fig_title, fontsize = 12, loc='center',fontproperties = myfont)
|
|
285
|
+
if datatype == 'radar':
|
|
286
|
+
clevels = [0,10, 20, 30, 40, 50, 60, 70]
|
|
287
|
+
colors = ['#62e6eaff','#00d72eff','#fefe3fff','#ff9a29ff','#d70e15ff','#ff1cecff','#af91edff']
|
|
288
|
+
# colors = ["#449ded", "#62e6ea", "#68f952", "#0000ff"]
|
|
289
|
+
elif datatype == 'rain':
|
|
290
|
+
clevels = [0.1, 2.5, 8, 16,200]
|
|
291
|
+
colors = ["#a6f28f", "#3dba3d", "#61b8ff", "#0000ff"]
|
|
292
|
+
if datatype == 'sat':
|
|
293
|
+
clevels = [150,170, 190, 210, 230, 250, 270, 290,310]
|
|
294
|
+
colors = [
|
|
295
|
+
'#00008B', # 150K 深蓝
|
|
296
|
+
'#0066CC', # 170K 钴蓝
|
|
297
|
+
'#00BFFF', # 190K 深天蓝
|
|
298
|
+
'#40E0D0', # 210K 绿松石
|
|
299
|
+
'#00FF00', # 230K 亮绿
|
|
300
|
+
'#FFFF00', # 250K 黄色
|
|
301
|
+
'#FFA500', # 270K 橙色
|
|
302
|
+
'#FF4500', # 290K 橙红
|
|
303
|
+
'#FF0000' # 310K 红色
|
|
304
|
+
]
|
|
305
|
+
cs = plt.contourf(nclon, nclat, cr, levels=clevels, colors=colors)
|
|
306
|
+
cb = plt.colorbar(cs, fraction=0.022)
|
|
307
|
+
cb.set_ticks(clevels[:-1])
|
|
308
|
+
cb.set_ticklabels([str(level) for level in clevels[:-1]],fontproperties = myfont)
|
|
309
|
+
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
|
310
|
+
label.set_fontproperties(myfont)
|
|
311
|
+
crDir(figpath)
|
|
312
|
+
plt.savefig(figpath, dpi=300, bbox_inches='tight')
|
|
313
|
+
print(f"{fig_title.split('_')[0]}绘制完成: {figpath}")
|
|
314
|
+
plt.close()
|
|
315
|
+
"""
|
|
316
|
+
font_path = './shp/微软雅黑.ttf'
|
|
317
|
+
myfont = mpl.font_manager.FontProperties(fname = font_path, size = 12)
|
|
318
|
+
UTCstr="202508280000"
|
|
319
|
+
shp_file = "./shp/province_9south.shp"
|
|
320
|
+
savepath = f"./FY4BBIG"
|
|
321
|
+
fig_title = f"卫星反演雷达回波_{UTCstr}"
|
|
322
|
+
# base[20:1070,75:1625] = satCR
|
|
323
|
+
plot_fig(data,result['lats'],result['lons'],fig_title,datatype="radar")
|
|
324
|
+
"""
|
|
325
|
+
|
shancx/Plot/radarNmc.py
CHANGED
|
@@ -10,57 +10,10 @@ def MDir(path):
|
|
|
10
10
|
path_obj = Path(path)
|
|
11
11
|
directory = path_obj.parent if path_obj.suffix else path_obj
|
|
12
12
|
directory.mkdir(parents=True, exist_ok=True)
|
|
13
|
-
|
|
14
|
-
import datetime
|
|
15
|
-
import matplotlib.pyplot as plt
|
|
16
|
-
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
17
|
-
def plotRadar(array_dt, ty="CR", temp="temp"):
|
|
18
|
-
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
19
|
-
if len(array_dt.shape) == 2 and ty == "pre":
|
|
20
|
-
fig, ax = plt.subplots()
|
|
21
|
-
im = ax.imshow(array_dt, vmin=0, vmax=10, cmap=cmp_hjnwtx["pre_tqw"])
|
|
22
|
-
# 创建与图像高度一致的colorbar
|
|
23
|
-
divider = make_axes_locatable(ax)
|
|
24
|
-
cax = divider.append_axes("right", size="5%", pad=0.05)
|
|
25
|
-
plt.colorbar(im, cax=cax)
|
|
26
|
-
outpath = f"./radar_nmc/{temp}{now_str}.png"
|
|
27
|
-
MDir(outpath)
|
|
28
|
-
plt.savefig(outpath)
|
|
29
|
-
plt.close()
|
|
30
|
-
else:
|
|
31
|
-
fig, ax = plt.subplots()
|
|
32
|
-
im = ax.imshow(array_dt, vmin=0, vmax=72, cmap=cmp_hjnwtx["radar_nmc"])
|
|
33
|
-
# 创建与图像高度一致的colorbar
|
|
34
|
-
divider = make_axes_locatable(ax)
|
|
35
|
-
cax = divider.append_axes("right", size="5%", pad=0.05)
|
|
36
|
-
plt.colorbar(im, cax=cax)
|
|
37
|
-
outpath = f"./radar_nmc/{temp}_{now_str}.png"
|
|
38
|
-
MDir(outpath)
|
|
39
|
-
plt.savefig(outpath)
|
|
40
|
-
plt.close()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def plotRadar3(array_dt, ty="CR", temp="temp"):
|
|
45
|
-
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
46
|
-
if len(array_dt.shape) == 3:
|
|
47
|
-
for i, img_ch_nel in enumerate(array_dt):
|
|
48
|
-
fig, ax = plt.subplots()
|
|
49
|
-
im = ax.imshow(img_ch_nel, vmin=0, vmax=10, cmap=cmp_hjnwtx["radar_nmc"])
|
|
50
|
-
divider = make_axes_locatable(ax)
|
|
51
|
-
cax = divider.append_axes("right", size="5%", pad=0.05)
|
|
52
|
-
plt.colorbar(im, cax=cax)
|
|
53
|
-
outpath = f"./radar_nmc/{temp}{now_str}.png"
|
|
54
|
-
MDir(outpath)
|
|
55
|
-
plt.savefig(outpath)
|
|
56
|
-
plt.close()
|
|
57
|
-
|
|
58
|
-
|
|
59
13
|
|
|
60
14
|
def plotRadarcoor(array_dt, temp="temp"):
|
|
61
15
|
now_str = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
|
62
|
-
y_coords2, x_coords2 = np.where(array_dt > 0)
|
|
63
|
-
|
|
16
|
+
y_coords2, x_coords2 = np.where(array_dt > 0)
|
|
64
17
|
def plot_and_save(image, path):
|
|
65
18
|
plt.imshow(image, vmin=0, vmax=10, cmap=cmp_hjnwtx["radar_nmc"])
|
|
66
19
|
for (x, y) in zip(x_coords2, y_coords2):
|
shancx/Plot/single_china_map.py
CHANGED
|
@@ -4,7 +4,7 @@ import cartopy.feature as cfeature
|
|
|
4
4
|
import cartopy.io.shapereader as shpreader
|
|
5
5
|
import datetime
|
|
6
6
|
import os
|
|
7
|
-
|
|
7
|
+
from hjnwtx.colormap import cmp_hjnwtx
|
|
8
8
|
def add_china_map(ax):
|
|
9
9
|
ax.add_feature(cfeature.COASTLINE, edgecolor='gray')
|
|
10
10
|
ax.add_feature(cfeature.BORDERS, linestyle=':', edgecolor='gray')
|
shancx/Point.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.interpolate import griddata
|
|
3
|
+
def getPoint(field,lats=None,lons=None,obs_lats=None,obs_lons=None):
|
|
4
|
+
lon_mesh, lat_mesh = np.meshgrid(lons, lats)
|
|
5
|
+
grid_points = np.column_stack([lon_mesh.ravel(), lat_mesh.ravel()])
|
|
6
|
+
interp_values = griddata(grid_points, field.ravel(), (obs_lons, obs_lats), method='linear')
|
|
7
|
+
valid_mask = ~np.isnan(interp_values)
|
|
8
|
+
return interp_values[valid_mask]
|
|
9
|
+
"""
|
|
10
|
+
nlat, nlon = background.shape
|
|
11
|
+
lons = np.linspace(-180, 180, nlon, endpoint=False)
|
|
12
|
+
lats = np.linspace(90, -90, nlat)
|
|
13
|
+
obs_lats = df["lat"]
|
|
14
|
+
obs_lons = df["lon"]
|
|
15
|
+
"""
|
|
16
|
+
from scipy.spatial import cKDTree
|
|
17
|
+
def mask_KDTree(grid_lon, grid_lat, lon_points, lat_points, step_lonlat=0.2):
|
|
18
|
+
grid_shape = grid_lon.shape
|
|
19
|
+
grid_coords = np.column_stack((grid_lon.ravel(), grid_lat.ravel()))
|
|
20
|
+
thunder_points = np.column_stack((lon_points, lat_points))
|
|
21
|
+
tree = cKDTree(thunder_points)
|
|
22
|
+
indices = tree.query_ball_point(grid_coords, r = step_lonlat)
|
|
23
|
+
mask_flat = np.zeros(len(grid_coords), dtype=int)
|
|
24
|
+
for i, neighbors in enumerate(indices):
|
|
25
|
+
if len(neighbors) >= 1:
|
|
26
|
+
mask_flat[i] = 1
|
|
27
|
+
mask_flat = mask_flat.reshape(grid_shape)
|
|
28
|
+
return mask_flat
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
lon_points = df_sta['lon']
|
|
32
|
+
lat_points = df_sta['lat']
|
|
33
|
+
grid_lon = th.lon.data
|
|
34
|
+
grid_lat = th.lat.data
|
|
35
|
+
grid_lon,grid_lat = np.meshgrid(grid_lon, grid_lat)
|
|
36
|
+
grid_marked = mask_KDTree(grid_lon, grid_lat, lon_points, lat_points, step_lonlat=0.5) step_lonlat 度数 0.01代表1公里
|
|
37
|
+
"""
|
|
38
|
+
def repetitionlatlon(df):
|
|
39
|
+
threshold = 0.001
|
|
40
|
+
df['lat_group'] = np.round(df['lat'] / threshold) * threshold
|
|
41
|
+
df['lon_group'] = np.round(df['lon'] / threshold) * threshold
|
|
42
|
+
duplicate_counts = df.groupby(['lat_group', 'lon_group']).size().reset_index(name='repetition')
|
|
43
|
+
return duplicate_counts
|
|
44
|
+
'''
|
|
45
|
+
输入数据框,通过近似查询,计算重复的经纬度点
|
|
46
|
+
'''
|