我有一个美国的shapefile,我有一个m x n的笛卡尔数据数组,这些数组代表每个像素的温度。我可以加载shapefile并将其绘制出来:
import shapefile as shp
import matplotlib.pyplot as plt
sf = shp.Reader("/path/to/USA.shp")
plt.figure()
for shape in sf.shapeRecords():
for i in range(len(shape.shape.parts)):
i_start = shape.shape.parts[i]
if i==len(shape.shape.parts)-1:
i_end = len(shape.shape.points)
else:
i_end = shape.shape.parts[i+1]
x = [i[0] for i in shape.shape.points[i_start:i_end]]
y = [i[1] for i in shape.shape.points[i_start:i_end]]
plt.plot(x,y, color = 'black')
plt.show()
我可以读取我的数据并将其绘制出来:
import pickle
from matplotlib import pyplot as mp
Tfile = '/path/to/file.pkl'
with open(Tfile) as f:
reshapeT = pickle.load(f)
mp.matshow(reshapeT)
问题是reshapeT的尺寸为536 x 592,是美国的子域。但是,我确实有关于reshapeT网格(经度/长度)的左上角以及每个像素之间的间距(0.01)的信息
我的问题是:如何在shapefile域的顶部覆盖reshapeT数据?
答案 0 :(得分:1)
如果我对您的理解正确,那么您希望在绘制的shapefile的特定部分上覆盖536x592的numpy数组。我建议您使用带有imwshow()
参数的Matplotlib的extent
方法,该方法可以将图像放置在绘图中。
您绘制shapefile的方式很好,但是,如果可以使用geopandas,它将大大简化事情。绘制shapefile将减少到以下几行:
import geopandas as gpd
sf = gpd.read_file("/path/to/USA.shp")
ax1 = sf.plot(edgecolor='black', facecolor='none')
像以前一样,让我们现在加载数组数据:
import pickle
Tfile = '/path/to/file.pkl'
with open(Tfile) as f:
reshapeT = pickle.load(f)
现在,为了能够在正确的位置绘制numpy数组,我们首先需要计算其范围(它将覆盖的面积以坐标表示)。您提到您拥有有关左上角和分辨率(0.01)的信息-这就是我们所需要的。在下文中,我假设有关左上角的经/纬度信息保存在top_left_lat
和top_left_lon
变量中。范围需要在元组中传递,并为每个边(以左,右,下,顶的顺序)传递一个值。
因此,我们的范围可以计算如下:
extent_mat = (top_left_lon, top_left_lon + reshapeT.shape[1] * 0.01, top_left_lat - reshapeT.shape[0] * 0.01, top_left_lat)
最后,我们将矩阵绘制到同一轴对象ax1
上,在该对象上,我们已经将形状文件绘制到了计算范围:
# Let's turn off autoscale first. This prevents
# the view of the plot to be limited to the image
# dimensions (instead of the entire shapefile). If you prefer
# that behaviour, just remove the following line
ax1.autoscale(False)
# Finally, let's plot!
ax1.imshow(reshapeT, extent=extent_mat)