Matplotlib cartopy中shapefile的匹配投影
我正在尝试使用matplotlib和cartopy制作Choropleth贴图,显然我需要先绘制一个shapefile。然而,我没有做到这一点,即使有人问了我一个类似的问题,我也没有做到。我怀疑投影或边界指定错误 我的形状文件有投影Matplotlib cartopy中shapefile的匹配投影,matplotlib,projection,cartopy,Matplotlib,Projection,Cartopy,我正在尝试使用matplotlib和cartopy制作Choropleth贴图,显然我需要先绘制一个shapefile。然而,我没有做到这一点,即使有人问了我一个类似的问题,我也没有做到。我怀疑投影或边界指定错误 我的形状文件有投影 PROJCS["WGS_1984_UTM_Zone_32Nz", GEOGCS["GCS_WGS_1984", DATUM["WGS_1984", SPHEROID["WGS_84",6378137,298.25722
PROJCS["WGS_1984_UTM_Zone_32Nz",
GEOGCS["GCS_WGS_1984",
DATUM["WGS_1984",
SPHEROID["WGS_84",6378137,298.257223563]],
PRIMEM["Greenwich",0],
UNIT["Degree",0.017453292519943295]],
PROJECTION["Transverse_Mercator"],
PARAMETER["False_Easting",32500000],
PARAMETER["False_Northing",0],
PARAMETER["Central_Meridian",9],
PARAMETER["Scale_Factor",0.9996],
PARAMETER["Latitude_Of_Origin",0],
UNIT["Meter",1]]
可以在我谈论的vg250_2010-01-01.utm32w.shape.ebenen/vg250_ebenen-historisch/de1001/vg250_gem.shp的地方下载
我的代码是
#!/usr/local/bin/python
# -*- coding: utf8 -*-
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import matplotlib.pyplot as plt
fname = 'path/vg250_gem.shp'
proj = ccrs.TransverseMercator(central_longitude=0.0,central_latitude=0.0,
false_easting=32500000.0,false_northing=0.0,
scale_factor=0.9996)
municipalities = list(shpreader.Reader(fname).geometries())
ax = plt.axes(projection=proj)
plt.title('Deutschland')
ax.add_geometries(municipalities,proj,edgecolor='black',facecolor='gray',alpha=0.5)
ax.set_extent([32458044.649189778*0.9, 5556418.748046352*1.1, 32465287.307457082*0.9, 5564153.5456742775*1.1],proj)
plt.show()
使用菲奥娜的相应方法求出边界。Python抛出一个错误
Traceback (most recent call last):
File "***/src/analysis/test.py", line 16, in <module>
ax.set_extent([32458044.649189778, 5556418.748046352, 32465287.307457082, 5564153.5456742775],proj)
File "/usr/local/lib/python2.7/site-packages/cartopy/mpl/geoaxes.py", line 652, in set_extent
ylim=self.projection.y_limits))
ValueError: Failed to determine the required bounds in projection coordinates. Check that the values provided are within the valid range (x_limits=[-20000000.0, 20000000.0], y_limits=[-10000000.0, 10000000.0]).
[Finished in 53.9s with exit code 1]
回溯(最近一次呼叫最后一次):
文件“***/src/analysis/test.py”,第16行,在
ax.设置范围([32458044.649189778,5556418.748046352,32465287.307457082,5564153.5456742775],项目)
文件“/usr/local/lib/python2.7/site packages/cartopy/mpl/geoaxes.py”,第652行,在set_范围内
ylim=自投影y_极限)
ValueError:无法确定投影坐标中所需的边界。检查提供的值是否在有效范围内(x_限值=[-20000000.0,20000000.0],y_限值=[-10000000.0,10000000.0])。
[完成时间为53.9秒,退出代码为1]
这对我来说毫无意义。另外,使用ccrs.UTM()进行实验会得到一个显示白色区域的图。如果有人能告诉我如何解决这个问题,我将不胜感激。谢谢大家! 我发现了两个问题。一个是调用set\u extent
时限制的规格不正确,指定的[x0,x1,y0,y1]
应该是输入,您似乎已经给出了[x0,y0,x1,y1]
。
另一个问题似乎是cartopy中的一个限制,正如我所能说的那样。看起来超出错误消息中列出的限制的投影总是会失败,并且这些限制是硬编码的。您只需编辑源代码(),将-2e7
更改为-4e7
,上限也是如此。在这些修复之后,将生成没有问题的绘图:
新的set\u区段
行:
ax.set_extent([32458044.649189778*0.975, 32465287.307457082*1.025,5556418.748046352*0.9, 556415,3.5456742775*1.1],proj)
您可能还希望在您的横切面编辑器中设置中心经度=9.0
,这似乎是您的shapefile中指定的
我建议与开发人员联系,他们可能有很好的理由设置这些界限,或者他们可能有更好的解决方法,或者他们可能会在以后的版本中扩大界限
更新
您的边界似乎也仅基于城市中的第一个城市设置:
In [34]: municipalities[0].bounds
Out[34]: (32458044.649189778, 5556418.748046352, 32465287.307457082, 5564153.5456742775)
但是其他元素有不同的界限。您可以根据所有城市
边界的最小/最大值将限制刷新到实际图形
bnd = np.array([i.bounds for i in municipalities])
x0,x1 = np.min(bnd[:,0]),np.max(bnd[:,2])
y0,y1 = np.min(bnd[:,1]),np.max(bnd[:,3])
ax.set_extent([x0,x1,y0,y1],proj)
我不知道有关cartopy等的任何信息,但阅读错误消息中最后一行的下一行,列出了一些必需的x和y限制,但是调用set\u extent
(导致错误的调用)中的限制超出了这些必需的限制。这就是我所说的“这对我来说没有意义”因为我使用菲奥娜提取了SeFFEFILE的边界。在上面,我尝试了set\u extent
方法,包括完全删除这一行,但这也不起作用。不管给出了什么界限,它们都超出了cartopy愿意接受的界限。同样,我不熟悉这些包,但我注意到在构建proj
时,您提供了一个32.5M的false\u easting
。这可能会导致x方向的移动。在对set_extent
的调用中,有两个接近32.5M的值可以通过这种偏移进行校正。查看cartopy的文档,set\u extent
的输入是(x0,x1,y0,y1),但看起来您可能已经给出了(x0,y0,x1,y1),因此false\u easting
不会让您回到可接受的范围。谢谢您的努力,@tsj。我不太明白为什么我用菲奥娜得到的SefFeFiele的边界并没有给我一个最小的可能的平方,这个国家是合适的。我上面的代码中是否(仍然)错误指定了投影?菲奥娜或卡托比有错吗?至少有一个不一致的地方?同样,仅仅是一个想法,+/-2e7从卡托比的角度来看应该足够了,因为地球的周长大约是40e6。也许有某种方法可以改变你的输入,使它被引用到-7.5e6而不是32.5e6,这样你就不必去编辑cartopy的源代码了。所以几何体方法实际上返回一个shapley对象,这就是为什么我可以调用边界,对吗?因为它返回(x0,y0,x1,y1)
,而cartopy期望(x0,x1,y0,y1)
,所以我需要按照您在代码片段中显示的那样重新组织。明白了,谢谢-很有魅力。