Matplotlib Contour/Contourf 在北极/日期变更线的 Cartopy 奇点
Matplotlib Contour/Contourf in Cartopy singularity at North Pole/ dateline
我正在尝试生成显示 RF link 到北极上方卫星的大气衰减值的热图,但我对 Matplotlib contour/contourf 函数完成的插值有疑问。
contourf 函数完成的线性插值在 N.Pole 周围效果不佳,因为我怀疑它不知道在从(-180 度到 +180 度)的值之间进行插值 - 即越过日期变更线,或越过极点。
有什么关于生成热图的不同方法的建议,以避免中心出现这个可怕的洞?!
下面的代码生成绘图。
import cartopy.crs as ccrs
import cartopy.feature
plt.figure(figsize=(10,10))
# Initialise Cartopy Axes.
proj=ccrs.LambertAzimuthalEqualArea(central_longitude=0, central_latitude=90)
ax = plt.axes(projection = proj)
ax.set_extent([-180,180,45,90], ccrs.PlateCarree())
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.gridlines(ls=":",color="grey",lw=0.5)
x0,x1 = attenuation_df.lon.min(), attenuation_df.lon.max()
y0,y1 = attenuation_df.lat.min(), attenuation_df.lat.max()
x,y = np.linspace(x0,x1,1000), np.linspace(y0,y1,1000)
X,Y = np.meshgrid(x,y)
Z = scipy.interpolate.griddata(
attenuation_df[["lon","lat"]],
attenuation_df["attenuation"],
(X,Y),
method="linear",
)
plt.contourf(X,Y,Z,transform=ccrs.PlateCarree(),alpha=0.5)
plt.colorbar(shrink=0.5)
plt.title("Attenuation")
plt.show()
Attenuation_df 是一个 Pandas 数据框,其中包含大约 3500 个采样点的衰减值,这些采样点在全球范围内等距分布。这是样本点的位置:
这里是 attenuation_df 的 header:
lon
lat
attenuation
0
-30.8538
48.8813
0.860307
1
-29.0448
49.5026
0.783662
2
-27.2358
50.1317
0.720165
3
-32.6628
48.2676
0.947662
4
37.4226
46.0322
0.27495
attenuation_df 的 csv link 在这里:https://pastebin.com/NYA1jFgt
一个解决方案是将您的数据重新投影到不同的坐标系,我的建议是使用 Polar Stereographic system。但是,以北极为中心的大“洞”不是来自正在使用的坐标系,而是数据集中存在一些 nan,因此您首先必须删除这些值。
这是一个可行的解决方案:
from pyproj import Proj
# Define a pyproj function to reproject data
def coordinate_conv(x, y, inverse = True):
p = Proj('+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs')
return p(x, y, inverse = inverse)
# Drop null values
attenuation_df.dropna(how = 'any', inplace = True)
# Reproject data
rpjx, rpjy = coordinate_conv(attenuation_df.lon, attenuation_df.lat, False)
rpj_cord = pd.DataFrame({'x': rpjx, 'y': rpjy})
# Interpoolate data
x,y = np.linspace(rpjx.min(),rpjx.max(),1000), np.linspace(rpjy.min(),rpjy.max(),1000)
X,Y = np.meshgrid(x,y)
Z = interpolate.griddata(
rpj_cord,
attenuation_df["attenuation"],
(X,Y),
method="linear",
)
# Figure
plt.figure(figsize=(10,10))
# Initialise Cartopy Axes.
proj=ccrs.LambertAzimuthalEqualArea(central_longitude=0, central_latitude=90)
ax = plt.axes(projection = proj)
ax.set_extent([-180,180,45,90], ccrs.PlateCarree())
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.gridlines(ls=":",color="grey",lw=0.5)
kw = dict(central_latitude=90, central_longitude=-45, true_scale_latitude=70)
plt.contourf(X,Y,Z, transform=ccrs.Stereographic(**kw),alpha=0.5)
plt.colorbar(shrink=0.5)
plt.title("Attenuation")
这是输出图:
我正在尝试生成显示 RF link 到北极上方卫星的大气衰减值的热图,但我对 Matplotlib contour/contourf 函数完成的插值有疑问。
contourf 函数完成的线性插值在 N.Pole 周围效果不佳,因为我怀疑它不知道在从(-180 度到 +180 度)的值之间进行插值 - 即越过日期变更线,或越过极点。
有什么关于生成热图的不同方法的建议,以避免中心出现这个可怕的洞?!
下面的代码生成绘图。
import cartopy.crs as ccrs
import cartopy.feature
plt.figure(figsize=(10,10))
# Initialise Cartopy Axes.
proj=ccrs.LambertAzimuthalEqualArea(central_longitude=0, central_latitude=90)
ax = plt.axes(projection = proj)
ax.set_extent([-180,180,45,90], ccrs.PlateCarree())
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.gridlines(ls=":",color="grey",lw=0.5)
x0,x1 = attenuation_df.lon.min(), attenuation_df.lon.max()
y0,y1 = attenuation_df.lat.min(), attenuation_df.lat.max()
x,y = np.linspace(x0,x1,1000), np.linspace(y0,y1,1000)
X,Y = np.meshgrid(x,y)
Z = scipy.interpolate.griddata(
attenuation_df[["lon","lat"]],
attenuation_df["attenuation"],
(X,Y),
method="linear",
)
plt.contourf(X,Y,Z,transform=ccrs.PlateCarree(),alpha=0.5)
plt.colorbar(shrink=0.5)
plt.title("Attenuation")
plt.show()
Attenuation_df 是一个 Pandas 数据框,其中包含大约 3500 个采样点的衰减值,这些采样点在全球范围内等距分布。这是样本点的位置:
这里是 attenuation_df 的 header:
lon | lat | attenuation | |
---|---|---|---|
0 | -30.8538 | 48.8813 | 0.860307 |
1 | -29.0448 | 49.5026 | 0.783662 |
2 | -27.2358 | 50.1317 | 0.720165 |
3 | -32.6628 | 48.2676 | 0.947662 |
4 | 37.4226 | 46.0322 | 0.27495 |
attenuation_df 的 csv link 在这里:https://pastebin.com/NYA1jFgt
一个解决方案是将您的数据重新投影到不同的坐标系,我的建议是使用 Polar Stereographic system。但是,以北极为中心的大“洞”不是来自正在使用的坐标系,而是数据集中存在一些 nan,因此您首先必须删除这些值。
这是一个可行的解决方案:
from pyproj import Proj
# Define a pyproj function to reproject data
def coordinate_conv(x, y, inverse = True):
p = Proj('+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs')
return p(x, y, inverse = inverse)
# Drop null values
attenuation_df.dropna(how = 'any', inplace = True)
# Reproject data
rpjx, rpjy = coordinate_conv(attenuation_df.lon, attenuation_df.lat, False)
rpj_cord = pd.DataFrame({'x': rpjx, 'y': rpjy})
# Interpoolate data
x,y = np.linspace(rpjx.min(),rpjx.max(),1000), np.linspace(rpjy.min(),rpjy.max(),1000)
X,Y = np.meshgrid(x,y)
Z = interpolate.griddata(
rpj_cord,
attenuation_df["attenuation"],
(X,Y),
method="linear",
)
# Figure
plt.figure(figsize=(10,10))
# Initialise Cartopy Axes.
proj=ccrs.LambertAzimuthalEqualArea(central_longitude=0, central_latitude=90)
ax = plt.axes(projection = proj)
ax.set_extent([-180,180,45,90], ccrs.PlateCarree())
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.COASTLINE)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':')
ax.gridlines(ls=":",color="grey",lw=0.5)
kw = dict(central_latitude=90, central_longitude=-45, true_scale_latitude=70)
plt.contourf(X,Y,Z, transform=ccrs.Stereographic(**kw),alpha=0.5)
plt.colorbar(shrink=0.5)
plt.title("Attenuation")
这是输出图: