2012-12-10 10 views
9

में महाद्वीप पर प्लॉट मैं matplotlib से बेसमैप का उपयोग कर एक नक्शा खींच रहा हूं। डेटा दुनिया भर में फैल गया है, लेकिन मैं सिर्फ महाद्वीप पर सभी डेटा बनाए रखना चाहता हूं और उन लोगों को समुद्र में छोड़ देना चाहता हूं। क्या कोई तरीका है कि मैं डेटा फ़िल्टर कर सकता हूं, या फिर डेटा को कवर करने के लिए समुद्र को आकर्षित करने का कोई तरीका है?केवल matplotlib

उत्तर

6

वहाँ matplotlib.basemap में विधि है: is_land(xpt, ypt)

यह रिटर्न True दिया एक्स, वाई बिंदु (प्रक्षेपण में निर्देशांक) भूमि पर है अगर, False अन्यथा। भूमि की परिभाषा कक्षा के उदाहरण से जुड़े जीएसएचएचएस तटरेखा बहुभुज पर आधारित है। भूमि क्षेत्रों के अंदर झीलों पर अंक भूमि अंक के रूप में गिना जाता है।

अधिक जानकारी के लिए, here देखें।

+0

धन्यवाद यही वह है जिसे मैं ढूंढ रहा था। लेकिन, जब मैं 'is_land' का उपयोग करता हूं तो मैं एक समस्या में भाग जाता हूं। यह [यहां] (http://stackoverflow.com/q/13800056/1819734) है। – ZYX

6

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() 
+0

मुझे लगता है कि 'points_inside_poly' (और अगर मुझे पूरा' nxutils' याद है) mpl 1 में कमी आई है।2, लेकिन यह नई विधि के साथ भी काम करता है (याद नहीं कर सकता कि इस समय नई विधि क्या है, लेकिन मूल्यह्रास चेतावनी इसे बताएगी) – bmu

+0

https://matplotlib.org/1.2.1/api/path_api.html # matplotlib.path.Path.contains_points – Baz

4

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 
2

सबसे आसान तरीका आधार मानचित्र के 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. 
1

मैं 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() 

यह निम्न साजिश का उत्पादन:

enter image description here

आशा इस किसी के लिए उपयोगी है

:)

यहाँ एक ही उदाहरण मैं अन्य प्रश्न के लिए उत्तर के रूप में तैनात है