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度。有什么区别?