में महाद्वीप पर प्लॉट मैं matplotlib से बेसमैप का उपयोग कर एक नक्शा खींच रहा हूं। डेटा दुनिया भर में फैल गया है, लेकिन मैं सिर्फ महाद्वीप पर सभी डेटा बनाए रखना चाहता हूं और उन लोगों को समुद्र में छोड़ देना चाहता हूं। क्या कोई तरीका है कि मैं डेटा फ़िल्टर कर सकता हूं, या फिर डेटा को कवर करने के लिए समुद्र को आकर्षित करने का कोई तरीका है?केवल matplotlib
उत्तर
वहाँ matplotlib.basemap में विधि है: is_land(xpt, ypt)
यह रिटर्न True
दिया एक्स, वाई बिंदु (प्रक्षेपण में निर्देशांक) भूमि पर है अगर, False
अन्यथा। भूमि की परिभाषा कक्षा के उदाहरण से जुड़े जीएसएचएचएस तटरेखा बहुभुज पर आधारित है। भूमि क्षेत्रों के अंदर झीलों पर अंक भूमि अंक के रूप में गिना जाता है।
अधिक जानकारी के लिए, here देखें।
is_land()
सभी बहुभुजों को यह जांचने के लिए लूप करेगा कि यह भूमि है या नहीं। बड़े डेटा आकार के लिए, यह बहुत धीमी है। आप बिंदुओं की सरणी को तुरंत जांचने के लिए matplotlib से points_inside_poly()
का उपयोग कर सकते हैं। कोड यहाँ है। यह lakepolygons
की जांच नहीं करता है, यदि आप झीलों में अंक निकालना चाहते हैं, तो आप अपना स्वयं जोड़ सकते हैं।
मेरे पीसी पर 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()
मुझे लगता है कि 'points_inside_poly' (और अगर मुझे पूरा' nxutils' याद है) mpl 1 में कमी आई है।2, लेकिन यह नई विधि के साथ भी काम करता है (याद नहीं कर सकता कि इस समय नई विधि क्या है, लेकिन मूल्यह्रास चेतावनी इसे बताएगी) – bmu
https://matplotlib.org/1.2.1/api/path_api.html # matplotlib.path.Path.contains_points – Baz
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
सबसे आसान तरीका आधार मानचित्र के maskoceans उपयोग करने के लिए है: मुझे लगता है कि काम करता है एक नया संस्करण बनाया है।
meshgrid और प्रक्षेप के बाद:
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.
मैं this question का जवाब दे रहा था, जब मुझे बताया गया था कि यह यहाँ पर मेरा उत्तर पोस्ट करने के लिए बेहतर होगा। असल में, मेरा समाधान उन बहुभुजों को निकालता है जिनका उपयोग Basemap
उदाहरण की तटीय रेखाओं को आकर्षित करने के लिए किया जाता है और मानचित्र के सागर क्षेत्रों को ओवरले करने वाले 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' का उपयोग करता हूं तो मैं एक समस्या में भाग जाता हूं। यह [यहां] (http://stackoverflow.com/q/13800056/1819734) है। – ZYX