地图投影和强制插值

时间:2013-08-12 11:40:20

标签: python matplotlib matplotlib-basemap

使用不同的Basemap投影我有一种奇怪的行为。

我想在世界地图上绘制的测量网格具有形状[181,83]。 这意味着每个2°/ 2°点的值都有,范围从-180° - 180°经度和-82° - 82°纬度。

from mpl_toolkits.basemap import Basemap
import numpy as np
measurementgrid = np.random.random_sample((181,83))
m = Basemap(projection='cyl',llcrnrlon=-180, llcrnrlat=-82, urcrnrlon=180, urcrnrlat=82, resolution='l')
m.drawcoastlines()
m.drawparallels(np.arange(-90,90,30),labels=[1,0,0,0])
m.drawmeridians(np.arange(-180,180,45), labels=[0,0,0,1])
data, x, y = m.transform_scalar(measurementgrid.T, lons=np.arange(-180,182,2), lats=np.arange(-82,84,2), nx = 181, ny = 83, returnxy=True, order=0)
m.imshow(data, origin='lower', interpolation='none')

使用圆柱投影,返回的数据网格等于测量网格,并且everthing很好。如果我将投影更改为“mill”,则生成的插值数据与其原点不同。

有没有办法按原样绘制测量网格,但是相对于变化的投影?

1 个答案:

答案 0 :(得分:3)

首先,我鼓励你开始使用pcolormesh,而不是imshow。当尝试在框中绘制网格化数据时,Pcolormesh应该是您的首选可视化工具(正如在将网格化数据绘制为等值区域时,contourf就是这样)。

要使用pcolormesh,您应该通过数据的x和y 角落的坐标,所以:

x = np.linspace(-180, 180, 182)
y = np.linspace(-90, 90, 84)
m.pcolormesh(x, y, data)

但是使用Basemap,你应该总是将坐标转换为地图的坐标系 - 最终这可能意味着x和y坐标都需要是2维数组,所以我们这样做并转换:

x = np.linspace(-180, 180, 182)
y = np.linspace(-90, 90, 84)
x, y = np.meshgrid(x, y)
converted_x, converted_y = m(x, y)
m.pcolormesh(converted_x, converted_y, data)

这意味着您现在可以继续更改投影,您的数据将在正确的位置绘制。例如,我将投影改为“罗宾逊”(罗宾逊)并获得了以下图片:

Output from my fix

不幸的是,pcolormesh用于连续的数据块,如果你选择一个不共享相同中心经度(又名“lon_0”)的投影,那么你会得到不好的结果。例如,我将投影更改为projection='robin',lon_0=180,并得到以下图片:

Bad dateline

这是因为Basemap当前没有处理日期行,据我所知,没有重大的重写 - 永远不会。

好消息是,这是一个困扰我很长时间的领域,所以我开始编写一个新的软件包来处理这个问题,以及许多其他用于科学可视化的映射问题。结果是一个名为cartopy的新包,它为你做了很多工作,所以像日期线这样的东西“只是工作”:

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

x = np.linspace(-180, 180, 182)
y = np.linspace(-90, 90, 84)
measurement_grid = np.random.random_sample((83, 181)) * y[:-1, np.newaxis] ** 2

plt.axes(projection=ccrs.Robinson(central_longitude=180))
plt.pcolormesh(x, y, measurement_grid, transform=ccrs.PlateCarree())
plt.gca().coastlines()
plt.show()

Cartopy output

虽然我并不是说你现在应该改用cartopy(安装和性能仍在进行中) - 值得知道包存在,并且我预计将来会变得越来越有吸引力遇到这些问题。 http://scitools.org.uk/cartopy/docs/latest

值得指出的是,网格数据的科学可视化中出现的许多问题都来自于数据的处理,它的坐标和它们的底层坐标系,因此编写了另一个实现数据模型的包。将所有这些复杂信息封装到一个对象中,然后可以将其传递给绘图例程以进行简单的接口。我再次鼓励你看看http://scitools.org.uk/iris/docs/latest

HTH