Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 仅在matplotlib中的大陆上绘图_Python_Map_Matplotlib_Matplotlib Basemap - Fatal编程技术网

Python 仅在matplotlib中的大陆上绘图

Python 仅在matplotlib中的大陆上绘图,python,map,matplotlib,matplotlib-basemap,Python,Map,Matplotlib,Matplotlib Basemap,我正在使用matplotlib中的basemap绘制地图。这些数据分布在世界各地,但我只想保留大陆上的所有数据,并将它们放到海洋上。有没有一种方法可以过滤数据,或者有没有一种方法可以再次绘制海洋以覆盖数据?matplotlib.basemap中有一种方法:Is_land(xpt,ypt) 如果给定的x,y点(在投影坐标中)在陆地上,则返回True,否则返回False。土地的定义基于与类实例关联的GSHHS海岸线多边形。陆地区域内湖泊上方的点不算作陆地点 有关更多信息,请参阅。是陆()将循环所有多

我正在使用matplotlib中的basemap绘制地图。这些数据分布在世界各地,但我只想保留大陆上的所有数据,并将它们放到海洋上。有没有一种方法可以过滤数据,或者有没有一种方法可以再次绘制海洋以覆盖数据?

matplotlib.basemap中有一种方法:
Is_land(xpt,ypt)

如果给定的x,y点(在投影坐标中)在陆地上,则返回
True
,否则返回
False
。土地的定义基于与类实例关联的GSHHS海岸线多边形。陆地区域内湖泊上方的点不算作陆地点

有关更多信息,请参阅。

是陆()
将循环所有多边形以检查它是否是陆。对于大数据量,速度非常慢。可以使用matplotlib中的
points\u inside\u poly()
快速检查点阵列。这是代码。它不检查湖泊多边形,如果你想移除湖泊中的点,你可以添加你自己

在我的电脑上检查100000个点花了2.7秒。如果你想提高速度,你可以将多边形转换成位图,但这有点困难。请告诉我以下代码是否对您的数据集不够快

from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.nxutils as nx

def points_in_polys(points, polys):
    result = []
    for poly in polys:
        mask = nx.points_inside_poly(points, poly)
        result.extend(points[mask])
        points = points[~mask]
    return np.array(result)

points = np.random.randint(0, 90, size=(100000, 2))
m = Basemap(projection='moll',lon_0=0,resolution='c')
m.drawcoastlines()
m.fillcontinents(color='coral',lake_color='aqua')
x, y = m(points[:,0], points[:,1])
loc = np.c_[x, y]
polys = [p.boundary for p in m.landpolygons]
land_loc = points_in_polys(loc, polys)
m.plot(land_loc[:, 0], land_loc[:, 1],'ro')
plt.show()

HYRY的答案在matplotlib的新版本上不起作用(nxutils已被弃用)。我制作了一个新版本,它可以工作:

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.path import Path
import numpy as np

map = Basemap(projection='cyl', resolution='c')

lons = [0., 0., 16., 76.]
lats = [0., 41., 19., 51.]

x, y = map(lons, lats)

locations = np.c_[x, y]

polygons = [Path(p.boundary) for p in map.landpolygons]

result = np.zeros(len(locations), dtype=bool) 

for polygon in polygons:

    result += np.array(polygon.contains_points(locations))

print result

最简单的方法是使用basemap的

如果对于每个lat,你有一个数据,你想 使用等高线: 在网格和插值之后:

from scipy.interpolate import griddata as gd
from mpl_toolkits.basemap import Basemap, cm, maskoceans
xi, yi = np.meshgrid(xi, yi)
zi = gd((mlon, mlat),
            scores,
            (xi, yi),
            method=grid_interpolation_method)
#mask points on ocean
data = maskoceans(xi, yi, zi)
con = m.contourf(xi, yi, data, cmap=cm.GMT_red2green)
#note instead of zi we have data now.
更新(比陆地或多边形解决方案快得多):

如果对于每个lat,lon,您没有任何数据,您只想将点分散在陆地上:

x, y = m(lons, lats)
samples = len(lons)
ocean = maskoceans(lons, lats, datain=np.arange(samples),
                   resolution='i')
ocean_samples = np.ma.count_masked(ocean)
print('{0} of {1} points in ocean'.format(ocean_samples, samples))
m.scatter(x[~ocean.mask], y[~ocean.mask], marker='.', color=colors[~ocean.mask], s=1)
m.drawcountries()
m.drawcoastlines(linewidth=0.7)
plt.savefig('a.png')
当我被告知最好把我的答案贴在这里时,我正在回答。基本上,我的解决方案提取用于绘制
基本地图
实例海岸线的多边形,并将这些多边形与地图的轮廓相结合,生成覆盖地图海洋区域的
matplotlib.PathPatch

如果数据比较粗糙且不需要插值,这一点尤其有用。在这种情况下,使用
maskoceans
会产生非常粗糙的海岸线轮廓,看起来不太好

下面是我作为另一个问题的答案发布的相同示例:

from matplotlib import pyplot as plt
from mpl_toolkits import basemap as bm
from matplotlib import colors
import numpy as np
import numpy.ma as ma
from matplotlib.patches import Path, PathPatch

fig, ax = plt.subplots()

lon_0 = 319
lat_0 = 72

##some fake data
lons = np.linspace(lon_0-60,lon_0+60,10)
lats = np.linspace(lat_0-15,lat_0+15,5)
lon, lat = np.meshgrid(lons,lats)
TOPO = np.sin(np.pi*lon/180)*np.exp(lat/90)

m = bm.Basemap(resolution='i',projection='laea', width=1500000, height=2900000, lat_ts=60, lat_0=lat_0, lon_0=lon_0, ax = ax)
m.drawcoastlines(linewidth=0.5)

x,y = m(lon,lat)
pcol = ax.pcolormesh(x,y,TOPO)

##getting the limits of the map:
x0,x1 = ax.get_xlim()
y0,y1 = ax.get_ylim()
map_edges = np.array([[x0,y0],[x1,y0],[x1,y1],[x0,y1]])

##getting all polygons used to draw the coastlines of the map
polys = [p.boundary for p in m.landpolygons]

##combining with map edges
polys = [map_edges]+polys[:]

##creating a PathPatch
codes = [
    [Path.MOVETO] + [Path.LINETO for p in p[1:]]
    for p in polys
]
polys_lin = [v for p in polys for v in p]
codes_lin = [c for cs in codes for c in cs]
path = Path(polys_lin, codes_lin)
patch = PathPatch(path,facecolor='white', lw=0)

##masking the data:
ax.add_patch(patch)

plt.show()
这将生成以下绘图:


希望这对某人有所帮助:)

谢谢这就是我要找的。但是,当我使用is_land时,我遇到了一个问题。它是。我认为在mpl 1.2中,
points\u inside\u poly
(如果我记得整个
nxutils
)是折旧的,但它也适用于新方法(不记得新方法现在是什么,但折旧警告会告诉它)+1作为综合答案。在我的例子中,它是完全相反的,我想掩盖陆地并显示海洋中的数据。有什么可以改变,使之生效?希望你能提供帮助