在Basemap中绘制一个环绕路径

3

我正在尝试绘制卫星地面轨迹。我有一组以度为单位的纬度和经度列表。经度值均在-180至+180度之间。我的第一个问题是使用latlon关键字(顺便说一句,我是通过PyCall.jl包在Julia中使用的,所以请原谅奇怪的语法):

map = Basemap.Basemap(projection="mill",lon_0=0)
map[:drawcoastlines]()
map[:drawparallels](-90:30:90,labels=[1,0,0,0])
map[:drawmeridians](map[:lonmin]:60:map[:lonmax]+30,labels=[0,0,0,1])
map[:plot](lon,lat,color="red",latlon=true)

怪异的图形

这...不应该是这个样子的。我不确定问题出在哪里。不过,如果我首先将其转换为地图坐标:

xx,yy = map(lon,lat) 
map[:plot](xx,yy,color="red")

更好的图表

这个图表看起来很不错,但是当经度从+180变为-180时会出现问题。有没有什么建议可以让它看起来更好呢?

生成这些图表所使用的纬度和经度对(以度为单位)可以在这里找到。


有没有可能只是重新排列经纬度列表,使其从地图的边缘开始和结束就可以解决问题?换句话说,根据经度从-180到180进行重新排序。 - dagrha
我尝试重新排序,但由于太平洋上的重叠,路径在上部和下部之间来回反弹。 - Chris
这样的解决方案可能会有所帮助:https://dev59.com/AYXca4cB1Zd3GeqPJYQW#27139390 - dagrha
我曾经以为basemap旨在内部处理这类问题,因此我希望避免自己编写解决方案。 - Chris
你可以把你的经纬度数据发布到某个地方,这样大家就可以随便试验并尝试找出解决方案了。 - dagrha
@dagrha,请看我刚刚做的修改。 - Chris
1个回答

8

一开始我认为这可能与Basemap旧问题有关。然而,我认为你的问题并不是由于Basemap引起的,实际上它正确处理了经度包裹,如果你只使用标记来绘制卫星地面轨迹,你就可以看到。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

f = plt.figure(figsize(10,7.5))
m = Basemap(projection="mill", lon_0=0)

m.drawcoastlines()
m.drawparallels(np.arange(-90,91,30),labels=[1,0,0,0])
m.drawmeridians(np.arange(-180,181,60), labels=[0,0,0,1])

x,y = m(lon, lat)
m.plot(x, y, color="red", latlon=False, marker='.', linestyle='None')

enter image description here

最终的解决方案是将您的地面轨迹分成多个轨迹,并使用LineCollection绘制它们,如此处所述。一个更简单的方法(如果您预计经度上有一个不连续点):
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

latlon_ar = np.array(latlon)

threshold = 90
idx_wrap = np.nonzero(np.abs(np.diff(latlon_ar[:,1])) > threshold)[0]+1

lon_1 = lon[:idx_wrap]
lat_1 = lat[:idx_wrap]

lon_2 = lon[idx_wrap:]
lat_2 = lat[idx_wrap:]

f = plt.figure(figsize(10,7.5))
m = Basemap(projection="mill", lon_0=0)

m.drawcoastlines()
m.drawparallels(np.arange(-90,91,30),labels=[1,0,0,0])
m.drawmeridians(np.arange(-180,181,60), labels=[0,0,0,1])

x1, y1 = m(lon_1, lat_1)
x2, y2 = m(lon_2, lat_2)

m.plot(x1, y1, color="red", latlon=False)
m.plot(x2, y2, color="blue", latlon=False)

enter image description here

编辑 Basemap 中的 已确认的错误 是导致问题第一个示例行为的罪魁祸首,这里使用经纬度值直接调用 Basemap.plot 并将 latlon 标志设置为 True。有一个解决方案,即在绘图前手动移动输入坐标,如下面的代码。

lons, lats = m.shiftdata(lon, lat)
m.plot(lons, lats, color="blue", latlon=True, marker='.', linestyle='None')

enter image description here


太好了,谢谢。你有没有想法关于我的第一个例子(使用 latlon=true)发生了什么? - Chris
1
@Chris 这确实是一个 Basemap bug。我已经更新了答案,提供了有关该 bug 的参考和可能的解决方案。 - lmillefiori

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接