python-从点集创建计数网格
我有一个经度/纬度数据集,如下所示:python-从点集创建计数网格,python,matplotlib,matplotlib-basemap,Python,Matplotlib,Matplotlib Basemap,我有一个经度/纬度数据集,如下所示: id,spp,lon,lat 1a,sp1,1,9 1b,sp1,3,11 1c,sp1,6,12 2a,sp2,1,9 2b,sp2,1,10 2c,sp2,3,10 2d,sp2,4,11 2e,sp2,5,12 2f,sp2,6,12 3a,sp3,4,13 3b,sp3,5,11 3c,sp3,8,8 4a,sp4,4,12 4b,sp4,6,11 4c,sp4,7,8 5a,sp5,8,8 5b,sp5,7,6 5c,sp5,8,2 6a,sp6,
id,spp,lon,lat
1a,sp1,1,9
1b,sp1,3,11
1c,sp1,6,12
2a,sp2,1,9
2b,sp2,1,10
2c,sp2,3,10
2d,sp2,4,11
2e,sp2,5,12
2f,sp2,6,12
3a,sp3,4,13
3b,sp3,5,11
3c,sp3,8,8
4a,sp4,4,12
4b,sp4,6,11
4c,sp4,7,8
5a,sp5,8,8
5b,sp5,7,6
5c,sp5,8,2
6a,sp6,8,8
6b,sp6,7,5
6c,sp6,8,3
根据这些数据,我想生成如下网格:
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 1 2 0 0 0 0
0 0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 1 0 1 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 3 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
它使用变量“spp”作为分类(分组)因子,给出网格每个单元格中的数据记录数
从这个网格中,我想创建一个热图,叠加在一个地理地图上,这样我就可以得到下图所示的东西
我(最后)设法写了一些代码来满足我的需求
这是:
import csv
import numpy as np
from mpl_toolkits.basemap import Basemap
from matplotlib import cm as cmap
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
#read input data
with open('testdata.csv', 'r') as csvfile:
reader = csv.reader(csvfile, delimiter=',')
headers = reader.next()
input_data = list(reader)
#grid dimensions with one-degree resolution
lat_inf, lon_inf = 0, 0
lat_sup, lon_sup = 90, 360
resolution = 1
latitude, longitude = [], []
latitude = range(lat_inf, lat_sup, resolution)
longitude = range(lon_inf, lon_sup, resolution)
#create output grid
output_grid = []
for i in latitude:
output_grid.append([])
for j in longitude:
output_grid[i].append(0)
#traverse the input_data evaluating the lat, lon coordinates
#summing +1 in the output_grid[latitude][longitude].
for row in input_data:
lat = int(row[2])
lon = int(row[3])
#sp = row[1]
#check its indexes
i_lat = latitude.index(lat)
i_lon = longitude.index(lon)
#increase counter
output_grid[i_lat][i_lon] += 1
output_grid = np.array(output_grid, np.int16)
#create map
m = Basemap()
m.drawcoastlines(linewidth=0.25)
#display image
im = m.imshow(output_grid.transpose(), cmap='summer', origin='lower', aspect='auto', interpolation='none')
m.colorbar(im)
plt.show()
它(大部分)工作正常,但问题是网格图像没有正确显示:它在地图的左下角显得太小,如下图所示)
此外,除了摆弄Matplotlib颜色贴图外,还有其他方法可以更改图像栅格的背景颜色吗
如有任何提示、想法和建议,我们将不胜感激。
使用参数lon、lat调用Basemap类实例
将lon/lat(以度为单位)转换为x/y贴图投影坐标(以度为单位
米)。如果可选关键字为
反向设置为True
所以,您需要将数据转换为纬度和经度,将其传递给Basemap,并使用返回给您的数据绘制位置
您得到的颜色是“酷”的默认颜色(请参见绘图右侧的颜色栏)。我不知道如何更改它,但我认为应该有一些参数可以传递给MPL例程,告诉它使用哪种颜色表示“冷”,使用哪种颜色表示“暖”。在底图上绘制图像可能是可能的,但您需要修改坐标和范围,以使其位于正确的位置 最好使用
pcolormesh
,它支持非等距栅格,因此非常适合不同的投影。你需要的不仅仅是你的数据,还有一个网格。该网格定义数据的每个点的位置。
在使用栅格之前,需要将其转换为底图坐标系,因此如果lons,lats=np。meshgrid(…,…)
是栅格,而m=basemap(…)
,则转换后的栅格是
X, Y = m(lons,lats)
然后可以将其提供给pcolormesh
m.pcolormesh(X,Y,data)
一个完整的示例,其中我们有一个形状(60x40)的数据数组,我们希望它位于-10到50度之间的经度范围内,以及-20到20度之间的纬度范围内:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap
data = np.random.rand(40,60)
lons,lats = np.meshgrid(np.linspace(-10,50,data.shape[1]+1),
np.linspace(-20,20,data.shape[0]+1))
fig, ax = plt.subplots()
m = Basemap(projection='merc', ax=ax, lat_0=0.,lon_0=0.,
llcrnrlon=-179.,llcrnrlat=-80.,urcrnrlon=170.,urcrnrlat=80.)
m.drawcoastlines()
X, Y = m(lons,lats)
pc = m.pcolormesh(X,Y,data,cmap='RdBu_r')
m.drawparallels(np.arange(-60,61,20),labels=[1,1,0,1])
m.drawmeridians([-90,-10,50,90],labels=[1,1,0,1])
plt.show()
谢谢,但我不想打印位置,我想在地图上显示图像。此外,颜色映射通过imshow调用中的参数“cmap”进行更改(事实上,我的示例使用MPL称之为“summer”的颜色映射)。但我真正想知道的是,是否有一些棘手的方法来显示带有“透明”背景的图像。当你说“透明”时,我认为这只是意味着冷颜色(你的数据不是)应该与地图的默认颜色匹配。我认为你可以通过将你期望的背景色指定为冷色调来获得这种效果。至于将图像缩放到地图,似乎可以通过摆弄imshow()的aspect和extent参数来实现。抱歉,我误解了您的意图。已经花了很长时间摆弄imshow的参数,但没有效果。请始终提供问题的详细信息。我不明白为什么我的例子不是“最小的、完整的和可验证的”。如果我没有得到答案,那是因为要么没有人知道答案。哦,好吧,对不起,如果上面的代码真的是完整的,那么你缺少关于坐标的信息。网格中的每个像素都有哪个坐标?非常感谢您的回答,@ImportanceOfBeingErnest。它对meshgrid和pcolormesh很有帮助。然而,我还没有弄清楚如何正确地调整我的数据到地图上。我确实有问题弄清楚你的例子的坐标应该是什么。这就是为什么我提供了一个通用示例。如果你能回答评论中的问题“网格中的每个像素有哪个坐标?”你可能会进一步帮助你。嗨,再次感谢。所以,我没有回答的原因是!问题是我不明白。。。网格的像素坐标是什么意思?在我的例子中,我有一个90行(lats)x360列(lons),因此它是一个1度的分辨率。在上面的答案中,我有40行60列,分辨率为1度。有什么区别?