Matplotlib Contour/ Contourf在北极/ Dateline的Cartopy奇点中

发布于 2025-01-24 22:43:46 字数 2862 浏览 2 评论 0 原文

我正在尝试产生热图,显示与北极上方的卫星链接的大气衰减值,但是我对matplotlib轮廓/轮廓函数进行的插值有问题。

轮廓函数完成的线性插值在n.pole周围无法很好地工作,因为我怀疑它不知道在从(-180度到+180 ver)的值之间插值。 IE越过数据线,或越过杆子。

关于一种生成热图的不同方法的任何建议,以避免在中心这个可怕的孔吗?

下面的代码生成图。

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()

Attenation_DF是熊猫数据框架,其中包含大约3500个样品点的衰减值,在全球范围内均等。这是样品点的位置:

”示例点位置“

这是Attenation_df的标题:

LON LAT 衰减
0 -30.8538 48.8813 0.860307
1 -29.0448 49.5026 0.783662
2 -27.2358 50.1317 0.720165
3 -32.6628 = href
< a https://pastebin.com/

在这里: nya1jfgt“ rel =“ nofollow noreferrer”> https://pastebin.com/nyaa1jfgt

I am trying to produce heatmaps showing atmospheric attenuation values for a RF link to a satellite above the North Pole, but I have issues with the interpolation done by the Matplotlib contour/contourf functions.

Heatmap at N Pole

The linear interpolation done by the contourf function does not work well around the N.Pole, as I suspect it does not know to interpolate between values which go from (-180 deg to +180 deg) - i.e. cross the dateline, or cross the pole.

Any suggestions on a different approach to generate the heatmap, to avoid this horrible hole at the centre?!

Code below to generate plot.

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 is a Pandas Dataframe which contains an attenuation value at approximately 3500 sample points, which are equally spaced around the globe. Here is the location of the sample points:

Sample point locations

Here is the header of attenuation_df:

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

The link to the csv of attenuation_df is here: https://pastebin.com/NYA1jFgt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等待我真够勒 2025-01-31 22:43:46

一种解决方案是将数据重新投射到其他坐标系,我的建议是使用a 。但是,以北极为中心的大“孔”不是来自使用的坐标系,而是来自数据集中的一些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")

这是输出图:

A solution is to reproject your data to a different coordinate system, my suggestion is to use a Polar Stereographic system. However, the large "hole" centered at the North Pole is not coming from the coordinate system in use but to the presence of some nans in your dataset, so you first have to remove those values.

Here a working solution:

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")

And this is the output figure:
enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文