def points(self,npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # must ask for at least 2 points. if npoints <= 1: raise ValueError,'npoints must be greater than 1' elif npoints == 2: return [math.degrees(self.lon1),math.degrees(self.lon2)],[math.degrees(self.lat1),math.degrees(self.lat2)] # can't do it if endpoints are antipodal, since # route is undefined. if self.antipodal: raise ValueError,'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.gcarclen delta = 1.0/(npoints-1) f = delta*NX.arange(npoints) # f=0 is point 1, f=1 is point 2. incdist = self.distance/(npoints-1) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 # perfect sphere, use great circle formula if self.f == 0.: A = NX.sin((1-f)*d)/math.sin(d) B = NX.sin(f*d)/math.sin(d) x = A*math.cos(lat1)*math.cos(lon1)+B*math.cos(lat2)*math.cos(lon2) y = A*math.cos(lat1)*math.sin(lon1)+B*math.cos(lat2)*math.sin(lon2) z = A*math.sin(lat1) +B*math.sin(lat2) lats=NX.arctan2(z,NX.sqrt(x**2+y**2)) lons=NX.arctan2(y,x) lons = map(math.degrees,lons.tolist()) lats = map(math.degrees,lats.tolist()) # use ellipsoid formulas else: latpt = self.lat1 lonpt = self.lon1 azimuth = self.azimuth12 lons = [math.degrees(lonpt)] lats = [math.degrees(latpt)] for n in range(npoints-2): latptnew,lonptnew,alpha21=vinc_pt(self.f,self.a,latpt,lonpt,azimuth,incdist) d,azimuth,a21=vinc_dist(self.f,self.a,latptnew,lonptnew,lat2,lon2) lats.append(math.degrees(latptnew)) lons.append(math.degrees(lonptnew)) latpt = latptnew; lonpt = lonptnew lons.append(math.degrees(self.lon2)) lats.append(math.degrees(self.lat2)) return lons,lats
def points(self, npoints): """ compute arrays of npoints equally spaced intermediate points along the great circle. input parameter npoints is the number of points to compute. Returns lons, lats (lists with longitudes and latitudes of intermediate points in degrees). For example npoints=10 will return arrays lons,lats of 10 equally spaced points along the great circle. """ # must ask for at least 2 points. if npoints <= 1: raise ValueError, 'npoints must be greater than 1' elif npoints == 2: return [math.degrees(self.lon1), math.degrees(self.lon2) ], [math.degrees(self.lat1), math.degrees(self.lat2)] # can't do it if endpoints are antipodal, since # route is undefined. if self.antipodal: raise ValueError, 'cannot compute intermediate points on a great circle whose endpoints are antipodal' d = self.gcarclen delta = 1.0 / (npoints - 1) f = delta * NX.arange(npoints) # f=0 is point 1, f=1 is point 2. incdist = self.distance / (npoints - 1) lat1 = self.lat1 lat2 = self.lat2 lon1 = self.lon1 lon2 = self.lon2 # perfect sphere, use great circle formula if self.f == 0.: A = NX.sin((1 - f) * d) / math.sin(d) B = NX.sin(f * d) / math.sin(d) x = A * math.cos(lat1) * math.cos(lon1) + B * math.cos( lat2) * math.cos(lon2) y = A * math.cos(lat1) * math.sin(lon1) + B * math.cos( lat2) * math.sin(lon2) z = A * math.sin(lat1) + B * math.sin(lat2) lats = NX.arctan2(z, NX.sqrt(x**2 + y**2)) lons = NX.arctan2(y, x) lons = map(math.degrees, lons.tolist()) lats = map(math.degrees, lats.tolist()) # use ellipsoid formulas else: latpt = self.lat1 lonpt = self.lon1 azimuth = self.azimuth12 lons = [math.degrees(lonpt)] lats = [math.degrees(latpt)] for n in range(npoints - 2): latptnew, lonptnew, alpha21 = vinc_pt(self.f, self.a, latpt, lonpt, azimuth, incdist) d, azimuth, a21 = vinc_dist(self.f, self.a, latptnew, lonptnew, lat2, lon2) lats.append(math.degrees(latptnew)) lons.append(math.degrees(lonptnew)) latpt = latptnew lonpt = lonptnew lons.append(math.degrees(self.lon2)) lats.append(math.degrees(self.lat2)) return lons, lats
def draw_networkx_edges(G, pos, edgelist=None, width=1.0, edge_color='k', style='solid', alpha=1.0, edge_cmap=None, edge_vmin=None, edge_vmax=None, ax=None, arrows=True, **kwds): """Draw the edges of the graph G This draws only the edges of the graph G. pos is a dictionary keyed by vertex with a two-tuple of x-y positions as the value. See networkx_v099.layout for functions that compute node positions. edgelist is an optional list of the edges in G to be drawn. If provided, only the edges in edgelist will be drawn. edgecolor can be a list of matplotlib color letters such as 'k' or 'b' that lists the color of each edge; the list must be ordered in the same way as the edge list. Alternatively, this list can contain numbers and those number are mapped to a color scale using the color map edge_cmap. For directed graphs, "arrows" (actually just thicker stubs) are drawn at the head end. Arrows can be turned off with keyword arrows=False. See draw_networkx_v099 for the list of other optional parameters. """ if ax is None: ax=matplotlib.pylab.gca() if edgelist is None: edgelist=G.edges() if not edgelist or len(edgelist)==0: # no edges! return None # set edge positions edge_pos=asarray([(pos[e[0]],pos[e[1]]) for e in edgelist]) if not cb.iterable(width): lw = (width,) else: lw = width if not cb.is_string_like(edge_color) \ and cb.iterable(edge_color) \ and len(edge_color)==len(edge_pos): if matplotlib.numerix.alltrue([cb.is_string_like(c) for c in edge_color]): # (should check ALL elements) # list of color letters such as ['k','r','k',...] edge_colors = tuple([colorConverter.to_rgba(c,alpha) for c in edge_color]) elif matplotlib.numerix.alltrue([not cb.is_string_like(c) for c in edge_color]): # numbers (which are going to be mapped with a colormap) edge_colors = None else: raise ValueError('edge_color must consist of either color names or numbers') else: if len(edge_color)==1: edge_colors = ( colorConverter.to_rgba(edge_color, alpha), ) else: raise ValueError('edge_color must be a single color or list of exactly m colors where m is the number or edges') edge_collection = LineCollection(edge_pos, colors = edge_colors, linewidths = lw, antialiaseds = (1,), linestyle = style, transOffset = ax.transData, ) edge_collection.set_alpha(alpha) # need 0.87.7 or greater for edge colormaps mpl_version=matplotlib.__version__ if mpl_version.endswith('svn'): mpl_version=matplotlib.__version__[0:-3] if mpl_version.endswith('pre'): mpl_version=matplotlib.__version__[0:-3] if map(int,mpl_version.split('.'))>=[0,87,7]: if edge_colors is None: if edge_cmap is not None: assert(isinstance(edge_cmap, Colormap)) edge_collection.set_array(asarray(edge_color)) edge_collection.set_cmap(edge_cmap) if edge_vmin is not None or edge_vmax is not None: edge_collection.set_clim(edge_vmin, edge_vmax) else: edge_collection.autoscale() matplotlib.pylab.sci(edge_collection) # else: # sys.stderr.write(\ # """matplotlib version >= 0.87.7 required for colormapped edges. # (version %s detected)."""%matplotlib.__version__) # raise UserWarning(\ # """matplotlib version >= 0.87.7 required for colormapped edges. # (version %s detected)."""%matplotlib.__version__) arrow_collection=None if G.directed and arrows: # a directed graph hack # draw thick line segments at head end of edge # waiting for someone else to implement arrows that will work arrow_colors = ( colorConverter.to_rgba('k', alpha), ) a_pos=[] p=1.0-0.25 # make head segment 25 percent of edge length for src,dst in edge_pos: x1,y1=src x2,y2=dst dx=x2-x1 # x offset dy=y2-y1 # y offset d=sqrt(float(dx**2+dy**2)) # length of edge if d==0: # source and target at same position continue if dx==0: # vertical edge xa=x2 ya=dy*p+y1 if dy==0: # horizontal edge ya=y2 xa=dx*p+x1 else: theta=arctan2(dy,dx) xa=p*d*cos(theta)+x1 ya=p*d*sin(theta)+y1 a_pos.append(((xa,ya),(x2,y2))) arrow_collection = LineCollection(a_pos, colors = arrow_colors, linewidths = [4*ww for ww in lw], antialiaseds = (1,), transOffset = ax.transData, ) # update view minx = amin(ravel(edge_pos[:,:,0])) maxx = amax(ravel(edge_pos[:,:,0])) miny = amin(ravel(edge_pos[:,:,1])) maxy = amax(ravel(edge_pos[:,:,1])) w = maxx-minx h = maxy-miny padx, pady = 0.05*w, 0.05*h corners = (minx-padx, miny-pady), (maxx+padx, maxy+pady) ax.update_datalim( corners) ax.autoscale_view() edge_collection.set_zorder(1) # edges go behind nodes ax.add_collection(edge_collection) if arrow_collection: arrow_collection.set_zorder(1) # edges go behind nodes ax.add_collection(arrow_collection) return edge_collection