我正在尝试在Python中产生一个数字,该人物将使用卫星数据(POLDER)将Cartopy的地图海岸线排列为固定在正弦电网上的RGB投影。
我曾尝试过Matplotlib的基部和摄影作品,并且在Cartopy方面也有更好的运气,但是即使遵循其他人的代码,海岸线也无法匹配。
到目前为止,我的
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
proj = ccrs.Sinusoidal(central_longitude=0)
fig = plt.figure(figsize=(12, 12))
# set image extents using the min and max of lon at lat
# image_extent ~= [-73.25, -10, 59.5, 84]
min_lon = np.nanmin(subset_lon)
max_lon = np.nanmax(subset_lon)
min_lat = np.nanmin(subset_lat)
max_lat = np.nanmax(subset_lat)
extents = proj.transform_points(ccrs.Geodetic(), np.array([min_lon, max_lon]),
np.array([min_lat, max_lat]))
img_extents = [extents[0][0], extents[1][0], extents[0][1], extents[1][1]]
ax = plt.axes(projection=proj)
# # image RGB
ax.imshow(RGB, origin='upper', extent=img_extents, transform=proj))
ax.set_xmargin(0.05)
ax.set_ymargin(0.10)
ax.coastlines(color='white')
plt.show()
生产:
这个数字,海岸线不匹配
> ://i.sstatic.net/bhgk6.png“ rel =“ nofollow noreferrer”> central_lon as -20
仅使用iMshow
我知道投影必须是正弦的,因此这不应该是问题。
关于它可能是什么的任何想法,或有关如何修复它的提示?
这是数据集:
和代码以提取数据并制作我想要与Cartopy Coastlines叠加的图像:
data = SD(path_to_file, SDC.READ)
subset_lat = data.select('subset_lat')[:]
subset_lon = data.select('subset_lon')[:]
R = data.select('mband07')[:]
G = data.select('mband02')[:]
B = data.select('mband01')[:]
RGB = np.dstack((R, G, B))
plt.imshow(RGB)
**编辑以添加两个注释和代码,以制作IMShow RGB图像。
谢谢!!
I'm trying to produce a figure in Python that will line up the map coastlines from Cartopy with a RGB projection using satellite data (POLDER) that is fixed to Sinusoidal grid.
I have tried both Matplotlib's Basemap and Cartopy, and have had better luck with Cartopy, however even after following other people's code, the coastlines do not match up.
What I have so far:
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
proj = ccrs.Sinusoidal(central_longitude=0)
fig = plt.figure(figsize=(12, 12))
# set image extents using the min and max of lon at lat
# image_extent ~= [-73.25, -10, 59.5, 84]
min_lon = np.nanmin(subset_lon)
max_lon = np.nanmax(subset_lon)
min_lat = np.nanmin(subset_lat)
max_lat = np.nanmax(subset_lat)
extents = proj.transform_points(ccrs.Geodetic(), np.array([min_lon, max_lon]),
np.array([min_lat, max_lat]))
img_extents = [extents[0][0], extents[1][0], extents[0][1], extents[1][1]]
ax = plt.axes(projection=proj)
# # image RGB
ax.imshow(RGB, origin='upper', extent=img_extents, transform=proj))
ax.set_xmargin(0.05)
ax.set_ymargin(0.10)
ax.coastlines(color='white')
plt.show()
Produces:
this figure where the coastlines do NOT match up

Figure with central_lon as -20
Figure using only imshow
I know the projection has to be sinusoidal, so that shouldn't be the issue.
Any ideas on what else it could be or tips on how to fix it?
Here is the dataset:
https://drive.google.com/file/d/1vRLKmeAXzCk5cLCJ1syOt7EJnaTmIwOa/view
And code to extract the data and make the image that I would like overlayed with the cartopy coastlines:
data = SD(path_to_file, SDC.READ)
subset_lat = data.select('subset_lat')[:]
subset_lon = data.select('subset_lon')[:]
R = data.select('mband07')[:]
G = data.select('mband02')[:]
B = data.select('mband01')[:]
RGB = np.dstack((R, G, B))
plt.imshow(RGB)
** Edited to add on two comments and code to make imshow RGB image.
Thanks!!
发布评论
评论(2)
所以我查看了数据,我认为问题实际上来自于您的数据不是在等距栅格中提供的事实!
因此,使用 imshow 是有问题的,因为它会引入扭曲...(请注意,imshow 只会根据数据点的数量将您的范围划分为相同大小的像素,而不考虑实际坐标!)
为了澄清我的意思...我'我非常确定您所拥有的数据已在此处描述的网格中提供(第 13 页):
https://www.theia- land.fr/wp-content/uploads/2018/12/parasol_te_level-3_format-i2.00.pdf
我个人从未遇到过这种情况网格定义,但似乎调整了每个纬度的像素数以考虑扭曲......引用上面的文档:
因此,为了快速可视化数据,我建议使用散点图+实际坐标而不是 imshow!
或者,我正在开发一个基于
matplotlib
+cartopy
的绘图库(EOmaps),旨在简化不规则或不均匀网格数据集(例如您的数据集)的可视化...在重新投影到正弦投影后,人们可以看到像素中心之间的距离至少几乎相等...
因此,我们可以使用此信息将数据可视化为正弦投影中大小为 6200x6200 的矩形...产生预期的图像:
...并且放大肯定会显示这些像素具有大致相同的大小,但它们绝对不是均匀分布的!

...这是使用 EOmaps 创建上述绘图的代码:
...通过这种方法,海岸线也位于它们应该在的位置!

so I had a look at the data and I think the problem actually comes from the fact that your data is NOT provided in an equidistant raster!
Therefore using imshow is problematic since it will introduce distortions... (note that imshow will just divide your extent into equally sized pixels based on the number of datapoints, irrespective of the actual coordinates!)
To clarify what I mean... I'm pretty sure the data you have is provided in the grid described here (page 13):
https://www.theia-land.fr/wp-content/uploads/2018/12/parasol_te_level-3_format-i2.00.pdf
I have personally never encountered this kind of grid-definition, but it seems that the number of pixels per latitude is adjusted to account for distortions... to quote from the document above:
To quickly visualize the data I'd therefore suggest to use a scatterplot + the actual coordinates instead of imshow!
Alternatively, I'm developing a
matplotlib
+cartopy
based plotting library (EOmaps) that is intended to simplify visualizations from irregular or non-uniformly gridded datasets such as yours...After reprojection to Sinusoidal projection, one can see that the distance between the pixel-centers is at least nearly equal...
So we can use this information to visualize the data as rectangles in Sinusoidal projection with a size of 6200x6200... yielding the expected image:
... and zooming in certainly shows that those pixels have approximately the same size but they are definitely not equally distributed!

... here's the code to create the above plot with EOmaps:
... and with this approach also the coastlines are located where they are supposed to be!

该问题由两部分组成:
要通过
basemap
解决这个问题,您需要一些技巧,因为目前Basemap
不支持正弦投影的范围(即它始终设置为整个地球) )。但是您可以在Basemap
对象和基础Axes
对象中手动更新范围,然后它应该可以工作:它显示了以下 RGB:

和土地覆盖:

南部的海岸线比北部的匹配得更好,但我不确定这是否只是仪器本身的限制(加上正确参考经度的不确定性)。
The issue consists of two parts:
To solve this by means of
basemap
, you need a bit of hacking because at the momentBasemap
does not support extents for sinusoidal projection (i.e. it is always set to the whole globe). But you can update the extent by hand both in theBasemap
object and the underlyingAxes
object and then it should work:which shows this RGB:

and this land cover:

The coastlines match better in the South than in the North, but I am not sure if this is just a limitation of the instrument itself (plus the uncertainty in the correct reference longitude).