Python 的底图没有与正确的坐标对齐?

Python's Basemap doesn't align with correct coordinates?

我有一个 .dat 文件,其中包含坐标列表 (~100k) 和每个坐标的温度。它的结构如下:

  -59.083  -26.583    0.2
  -58.417  -26.250    0.6
  -58.412  -26.417    0.4
   ...

为了直观地显示温度范围,我创建了一个 numpy 数组并使用 Python 的底图模块绘制了数据集。我写的代码如下:

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

m = Basemap(projection='mill',llcrnrlat=-90,urcrnrlat=90,\
            llcrnrlon=-180,urcrnrlon=180,resolution='c')
m.drawcoastlines(linewidth=0.15)

data = np.loadtxt('gridly.dat')

xcoordlist = []
ycoordlist = []
tempvallist = []

for i in data:
    xcoord = i[0]
    ycoord = i[1]
    tempval = i[2]
    xcoord2 = xcoord*111139   #<--- Multiplying converts each coordinate's degrees to meters)
    ycoord2 = ycoord*111139
    xcoordlist.append(xcoord2)
    ycoordlist.append(ycoord2)
    tempvallist.append(tempval)

xco = np.array(xcoordlist)
yco = np.array(ycoordlist)
tval = np.array(tempvallist)

gridsize = 100
m.hexbin(yco, xco, C=tval, gridsize=gridsize)

cb = m.colorbar()
plt.show()

当我绘制数据时,我几乎得到了我想要的结果,但是,由于某种原因,六角形热图发生了偏移,给出了以下图表:

我一直在网上搜索可能出现的问题,但遗憾的是找不到答案或进行故障排除。有谁知道我该如何解决这个问题?

经过数小时的挖掘,我终于弄明白了!我的代码有什么问题是我试图手动将地理坐标转换为显示图表的点坐标(乘以 111139)。

虽然这样做的逻辑是有道理的,但我相信当我开始将数据绘制到不同类型的图表(即正交、米勒投影等)上时,这个过程就崩溃了,因为不同的 projections/charts 会具有不同的点坐标(有点像您计算机屏幕上的像素位置可能与不同计算机屏幕上的像素位置不对齐)。

相反,底图模块有一个内置函数,可以将真实世界的坐标转换为可以在图表上绘制的坐标,为您服务:m(x, y).

因此,改进后的正确脚本为:

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

m = Basemap(projection='mill',llcrnrlat=-90,urcrnrlat=90,\
            llcrnrlon=-180,urcrnrlon=180,resolution='c')
m.drawcoastlines(linewidth=0.15)

data = np.loadtxt('gridly.dat')

xcoordlist = []
ycoordlist = []
tempvallist = []

for i in data:
    lat = i[0]
    lon = i[1]
    tempval = i[2]
    xpt, ypt = m(lon, lat)
    xcoordlist.append(xpt)
    ycoordlist.append(ypt)
    tempvallist.append(tempval)

xco = np.array(xcoordlist)
yco = np.array(ycoordlist)
tval = np.array(tempvallist)

gridsize = 100
m.hexbin(xco, yco, C=tval, gridsize=gridsize)

cb = m.colorbar()
plt.show()

如你所见xpt, ypt = m(lon, lat),该函数将真实世界的经度(lon)和纬度(lat)从.dat文件转换为盆栽点。希望这对以后可能遇到此问题的其他人有所帮助!