Example #1
0
    def selectArea(self, ptlist, latlon=False, reduced=None):
        """Select an area of the grid.
        
        Parameters
        ----------
        ptlist : list
        latlon : bool
        reduced : int
            The amount by which the index array should be short (i.e., 1 for
            basic difference, 2 for center difference).
        """
        ptlist = np.asarray(ptlist)
        if latlon: 
            ptlist[:,0], ptlist[:,1] = self.basemap(ptlist[:,0], ptlist[:,1])
        # create the polygon
        path = Path(ptlist)

        if reduced is not None:
            X, Y = np.meshgrid(self.x[:-reduced], self.y[:-reduced])
            areaind = path.contains_points(zip(X.flatten(), Y.flatten()))
            areaind = areaind.reshape((self.shape[0]-reduced,
                                       self.shape[1]-reduced))
        else:
            X, Y = np.meshgrid(self.x, self.y)
            areaind = path.contains_points(zip(X.flatten(), Y.flatten()))
            areaind = areaind.reshape(self.shape)
        # return array indices
        return areaind
def reverse_geocode(tweet):
	# print index
	# latlong = json.load(tweets)[index]['coordinates']
	latlong = tweet["coordinates"]
	if latlong == [0.0, 0.0]:
		return False
	# latlong.reverse()
	with open('world-countries.json.txt', 'r') as countries_json:
		found_country = None
		countries = json.load(countries_json)['features']
		for country in countries:
			country_name = country['properties']['name']
			if country['geometry']['type'] == 'Polygon':
				country_vertices = country['geometry']['coordinates'][0]
				country_path = Path(country_vertices)
				if country_path.contains_point(latlong):
					found_country = country_name
					break
			if country['geometry']['type'] == 'MultiPolygon':
				country_polygons = country['geometry']['coordinates']
				for polygon in country_polygons:
					country_vertices = polygon[0]
					country_path = Path(country_vertices)
					if country_path.contains_point(latlong):
						found_country = country_name
						break
		if not found_country:
			found_country = False
	return found_country
# with open('Ferguson_tweets.txt', 'r') as tweets:
# 	print reverse_geocode(tweets, 0)
Example #3
0
def processPolygon(polygon, rows, columns, mode):
    """
    Finds the points within a particular polygon
    """
    length = len(polygon)
    polygon.append((0.0, 0.0))
    codes = [Path.MOVETO]
    for index in range(length - 1):
        codes.append(Path.LINETO)
    codes.append(Path.CLOSEPOLY)
    path = Path(polygon, codes)
    points = []
    if mode == 'V':
        for index in range(rows):
            row = [(x, index) for x in range(columns)]
            check = path.contains_points(row)
            temp_points = ([row[i] for i, j in enumerate(check) if j == True and not contains(row[i], polygon)])
            if (len(temp_points) > 0):
                points.append(temp_points)
    else:
        for index in range(columns):
            col = [(index, x) for x in range(rows)]
            check = path.contains_points(col)
            temp_points = ([col[i] for i, j in enumerate(check) if j == True and not contains(col[i], polygon)])
            if (len(temp_points) > 0):
                points.append(temp_points)
    return points
Example #4
0
    def __init__(self, shape, scale=1):
        """ 
        Initalize a Warper with a reference shape with coordinates in the 
        numpy array 'shape'
        """
        xy = shape.copy() * scale
        self.scale = scale
        
        xy = self.shape_to_xy(xy)
            
        xy = xy - np.min(xy,axis=0)
        dt = scipy.spatial.Delaunay(xy)
        
        # Define a grid
        cols = int(np.ceil(np.max(xy[:,0])))
        rows = int(np.ceil(np.max(xy[:,1])))
        xx, yy = np.meshgrid(range(cols),range(rows))

        xy_grid = np.vstack((xx.flatten(),yy.flatten())).T        
        
        # Define a mask 
        mask = Path(xy).contains_points(xy_grid)
        self.mask = mask.reshape(xx.shape)
        xy_grid = xy_grid[mask==True,:] # Remove pts not inside mask
        
        # Calculate barycentric coordinates for all points inside mask
        simplex_ids = dt.find_simplex(xy_grid)
        bary_coords = points_to_bary(dt,simplex_ids,xy_grid)
        
        self.tri = dt.simplices
        self.warp_template = np.hstack((simplex_ids[:,np.newaxis],bary_coords))
Example #5
0
 def transform_path_non_affine(self, path):
     # Adaptive interpolation:
     # we keep adding control points, till all control points
     # have an error of less than 0.01 (about 1%)
     # or if the number of control points is > 80.
     ra0 = self.ra0
     path = path.cleaned(curves=False)
     v = path.vertices
     diff = v[:, 0] - v[0, 0]
     v00 = v[0][0] - ra0
     while v00 > 180: v00 -= 360
     while v00 < -180: v00 += 360
     v00 += ra0
     v[:, 0] = v00 + diff
     nonstop = path.codes > 0
     path = Path(v[nonstop], path.codes[nonstop])
     isteps = path._interpolation_steps * 2
     while True:
         ipath = path.interpolated(isteps)
         tiv = self.transform(ipath.vertices)
         itv = Path(self.transform(path.vertices)).interpolated(isteps).vertices
         if np.mean(np.abs(tiv - itv)) < 0.01:
             break
         if isteps > 20:
             break
         isteps = isteps * 2
     return Path(tiv, ipath.codes)
Example #6
0
def make_venn3_region_patch(region):
    '''
    Given a venn3 region (as returned from compute_venn3_regions) produces a Patch object,
    depicting the region as a curve.

    >>> centers, radii = solve_venn3_circles((1, 1, 1, 1, 1, 1, 1))
    >>> regions = compute_venn3_regions(centers, radii)
    >>> patches = [make_venn3_region_patch(r) for r in regions]
    '''
    if region is None or len(region[0]) == 0:
        return None
    if region[0] == "CIRCLE":
        return Circle(region[1][0], region[1][1])
    pts, arcs, label_pos = region
    path = [pts[0]]
    for i in range(len(pts)):
        j = (i + 1) % len(pts)
        (center, radius, direction) = arcs[i]
        fromangle = vector_angle_in_degrees(pts[i] - center)
        toangle = vector_angle_in_degrees(pts[j] - center)
        if direction:
            vertices = Path.arc(fromangle, toangle).vertices
        else:
            vertices = Path.arc(toangle, fromangle).vertices
            vertices = vertices[np.arange(len(vertices) - 1, -1, -1)]
        vertices = vertices * radius + center
        path = path + list(vertices[1:])
    codes = [1] + [4] * (len(path) - 1)
    return PathPatch(Path(path, codes))
  def _gating(self,DF_array_data,x_ax,y_ax,coords):
 
      #np.ones(DF_array_data.shape[0],dtype=bool)
      gate=Path(coords,closed=True)
      projection=np.array(DF_array_data[[x_ax,y_ax]])
      index=gate.contains_points(projection)
      return index
Example #8
0
    def estimate_mean_extinction(self, poly):
        """Estimate the mean extinction Av in within a footprint.

        Parameters
        ----------
        poly : ndarray
            The RA,Dec polygon (a rectangle) defining the footprint.
        """
        sigma_dust = self._f[0].data
        ny, nx = sigma_dust.shape

        # Make a coordinate grid out of RA, Dec across the dust map
        y_image, x_image = np.mgrid[0:ny, 0:nx]
        y = y_image.reshape(nx * ny)
        x = x_image.reshape(nx * ny)
        ra, dec = self._wcs.all_pix2world(x, y, 0)
        points = np.vstack((ra, dec)).T

        # Find all pixels in the footprint
        path = Path(poly, closed=False)
        in_poly = path.contains_points(points)
        s = np.where(in_poly)[0]
        dust_pixels = sigma_dust[y[s], x[s]]
        mean = np.nanmean(dust_pixels)

        # Estimate Av from the Lewis et al attenuation law
        return 10. ** (-5.4) * mean
def contained_in(lat, lng, bound_coords):
    """
    Returns true if (lat, lng) is contained within the polygon formed by the
    points in bound_coords.
    """
    bound_path = Path(np.array(bound_coords))
    return bound_path.contains_point((lat, lng))
Example #10
0
    def path_contains_points(verts, points):
        p = Path(verts, closed=True)
        result = num.zeros(points.shape[0], dtype=num.bool)
        for i in range(result.size):
            result[i] = p.contains_point(points[i, :])

        return result
Example #11
0
def get_path( img, verts ):
    #verts=array( verts, int)
    path1 = Path(verts)
    print path1
    dx,dy=img.shape
    data = zeros( [dx,dy,2])
    data[:,:,0]= range(dx)
    for i in range(dy):
        data[i,:,1] = i 
    #print data
    data=data.reshape( [dx*dy,2])
    #print data.shape
    #print path1,data
    index = path1.contains_points(data)
    print index.shape, len(where(index)[0])
    #print data[index, :2]
    
    #plot(data[:,0],data[:,1], 'b.')
    fig, ax = plt.subplots(nrows=1)
    vmin=img.min();vmax=img.max()
    ax.imshow( img,cmap=plt.get_cmap('winter'), vmin=vmin,vmax=vmax )
    #ax.set_xlim(0,dx-1)
    #ax.set_ylim(0,dy-1)
    patch = patches.PathPatch(path1, facecolor='orange', lw=2)
    gca().add_patch(patch)
    plot(data[index,0], data[index,1], 'r.')
    show() 
Example #12
0
def Ablate_outside_area(n_pixels, contour_coords):
    ''' Function takes points from contour and returns list of coordinates
        lying outside of the contour - to be used to ablate image    '''
    
    #Search points outside and black them out:
    all_points = []
    for i in range(n_pixels):
        for j in range(n_pixels):
            all_points.append([i,j])

    all_points = np.array(all_points)
    vertixes = np.array(contour_coords) 
    vertixes_path = Path(vertixes)
    
    mask = vertixes_path.contains_points(all_points)
    ablate_coords=[]
    counter=0
    for i in range(n_pixels):
        for j in range(n_pixels):
            if mask[counter] == False:
                #images_processed[100][i][j]=0
                ablate_coords.append([i,j])
            counter+=1
            
    return ablate_coords
Example #13
0
def _filter_block(vertices, block_origin, block_shape):
    """

    Keyword arguments:
    vertices --
    block_origin_list -- 
    block_shape --

    Return values
    -- True/False vertices contain block

    """

    # check arguments

    # create path object
    path = Path(vertices, closed=True)

    # create path for the block
    x0 = block_origin[0]
    y0 = block_origin[1]
    w = block_shape[0]
    h = block_shape[1]
    box_vertices = np.asarray([[x0, y0], [x0 + w, y0], [x0 + w, y0 + h], [x0, y0 + h]])
    box = Path(box_vertices, closed=True)

    # determine if points inside the specified path
    # Note: there appears to be an error in contains_points(). For
    # example, reversing the direction of the vertices requires raidus=-0.01
    # to be specified. See the e-mails in the link below
    # http://matplotlib.1069221.n5.nabble.com/How-to-properly-use-path-Path-contains-point-tc40718.html#none

    return path.contains_path(box)
    def number_of_images(self, sourceposition):
        rc=self.radial_caustic()
        tc=self.tangential_caustic()

        if usePath:
        
            # New Matplotlib:
            rc=Path(rc)
            tc=Path(tc)
            if rc.contains_points(np.atleast_2d(sourceposition))[0]:
               if tc.contains_points(np.atleast_2d(sourceposition))[0]:
                   return 4
               return 2
            if tc.contains_points(np.atleast_2d(sourceposition))[0]:
               return 3
        
        else:
            # Old Matplotlib:
            if nxutils.points_inside_poly(np.atleast_2d(sourceposition),rc)[0]:
                if nxutils.points_inside_poly(np.atleast_2d(sourceposition),tc)[0]:
                    return 4
                return 2
            if nxutils.points_inside_poly(np.atleast_2d(sourceposition),tc)[0]:
                return 3

        return 1
Example #15
0
File: box.py Project: gogrean/PyXel
 def distribute_pixels(self, edges, length, width):
     corners = self.get_corners()
     reg_path = Path(corners)
     # Get region boundaries.
     bounds = reg_path.get_extents().get_points()
     [[x_min_bound, y_min_bound], [x_max_bound, y_max_bound]] = bounds
     # For cases when the boundary pixels are not integers:
     x_min_bound = floor(x_min_bound)
     y_min_bound = floor(y_min_bound)
     x_max_bound = ceil(x_max_bound)
     y_max_bound = ceil(y_max_bound)
     pixels_in_bins = []
     for x in range(max(0, x_min_bound), min(x_max_bound+1, width)):
         for y in range(max(0, y_min_bound), min(y_max_bound+1, length)):
             if reg_path.contains_point((x, y)):
                 x_nonrotated, y_nonrotated = rotate_point(self.x0, self.y0,
                                                           x - self.x0,
                                                           y - self.y0,
                                                           -self.angle)
                 dist_from_box_bottom = self.height/2. - \
                                        (self.y0 - y_nonrotated)
                 for i, edge in enumerate(edges[1:]):
                     if edge > dist_from_box_bottom:
                         pixels_in_bins.append((y, x, i))
                         break
     return pixels_in_bins
Example #16
0
def test_start_with_moveto():
    # Should be entirely clipped away to a single MOVETO
    data = b"""
ZwAAAAku+v9UAQAA+Tj6/z8CAADpQ/r/KAMAANlO+v8QBAAAyVn6//UEAAC6ZPr/2gUAAKpv+v+8
BgAAm3r6/50HAACLhfr/ewgAAHyQ+v9ZCQAAbZv6/zQKAABepvr/DgsAAE+x+v/lCwAAQLz6/7wM
AAAxx/r/kA0AACPS+v9jDgAAFN36/zQPAAAF6Pr/AxAAAPfy+v/QEAAA6f36/5wRAADbCPv/ZhIA
AMwT+/8uEwAAvh77//UTAACwKfv/uRQAAKM0+/98FQAAlT/7/z0WAACHSvv//RYAAHlV+/+7FwAA
bGD7/3cYAABea/v/MRkAAFF2+//pGQAARIH7/6AaAAA3jPv/VRsAACmX+/8JHAAAHKL7/7ocAAAP
rfv/ah0AAAO4+/8YHgAA9sL7/8QeAADpzfv/bx8AANzY+/8YIAAA0OP7/78gAADD7vv/ZCEAALf5
+/8IIgAAqwT8/6kiAACeD/z/SiMAAJIa/P/oIwAAhiX8/4QkAAB6MPz/HyUAAG47/P+4JQAAYkb8
/1AmAABWUfz/5SYAAEpc/P95JwAAPmf8/wsoAAAzcvz/nCgAACd9/P8qKQAAHIj8/7cpAAAQk/z/
QyoAAAWe/P/MKgAA+aj8/1QrAADus/z/2isAAOO+/P9eLAAA2Mn8/+AsAADM1Pz/YS0AAMHf/P/g
LQAAtur8/10uAACr9fz/2C4AAKEA/f9SLwAAlgv9/8ovAACLFv3/QDAAAIAh/f+1MAAAdSz9/ycx
AABrN/3/mDEAAGBC/f8IMgAAVk39/3UyAABLWP3/4TIAAEFj/f9LMwAANm79/7MzAAAsef3/GjQA
ACKE/f9+NAAAF4/9/+E0AAANmv3/QzUAAAOl/f+iNQAA+a/9/wA2AADvuv3/XDYAAOXF/f+2NgAA
29D9/w83AADR2/3/ZjcAAMfm/f+7NwAAvfH9/w44AACz/P3/XzgAAKkH/v+vOAAAnxL+//04AACW
Hf7/SjkAAIwo/v+UOQAAgjP+/905AAB5Pv7/JDoAAG9J/v9pOgAAZVT+/606AABcX/7/7zoAAFJq
/v8vOwAASXX+/207AAA/gP7/qjsAADaL/v/lOwAALZb+/x48AAAjof7/VTwAABqs/v+LPAAAELf+
/788AAAHwv7/8TwAAP7M/v8hPQAA9df+/1A9AADr4v7/fT0AAOLt/v+oPQAA2fj+/9E9AADQA///
+T0AAMYO//8fPgAAvRn//0M+AAC0JP//ZT4AAKsv//+GPgAAojr//6U+AACZRf//wj4AAJBQ///d
PgAAh1v///c+AAB+Zv//Dz8AAHRx//8lPwAAa3z//zk/AABih///TD8AAFmS//9dPwAAUJ3//2w/
AABHqP//ej8AAD6z//+FPwAANb7//48/AAAsyf//lz8AACPU//+ePwAAGt///6M/AAAR6v//pj8A
AAj1//+nPwAA/////w=="""

    verts = np.frombuffer(base64.decodebytes(data), dtype='<i4')
    verts = verts.reshape((len(verts) // 2, 2))
    path = Path(verts)
    segs = path.iter_segments(transforms.IdentityTransform(),
                              clip=(0.0, 0.0, 100.0, 100.0))
    segs = list(segs)
    assert len(segs) == 1
    assert segs[0][1] == Path.MOVETO
Example #17
0
 def onselect(self, verts):
     path = Path(verts)
     self.ind = np.nonzero([path.contains_point(xy) for xy in self.xys])[0]
     self.fc[:, -1] = self.alpha_other
     self.fc[self.ind, -1] = 1
     self.collection.set_facecolors(self.fc)
     self.canvas.draw_idle()
Example #18
0
def test_path_no_doubled_point_in_to_polygon():
    hand = np.array(
        [[1.64516129, 1.16145833],
         [1.64516129, 1.59375],
         [1.35080645, 1.921875],
         [1.375, 2.18229167],
         [1.68548387, 1.9375],
         [1.60887097, 2.55208333],
         [1.68548387, 2.69791667],
         [1.76209677, 2.56770833],
         [1.83064516, 1.97395833],
         [1.89516129, 2.75],
         [1.9516129, 2.84895833],
         [2.01209677, 2.76041667],
         [1.99193548, 1.99479167],
         [2.11290323, 2.63020833],
         [2.2016129, 2.734375],
         [2.25403226, 2.60416667],
         [2.14919355, 1.953125],
         [2.30645161, 2.36979167],
         [2.39112903, 2.36979167],
         [2.41532258, 2.1875],
         [2.1733871, 1.703125],
         [2.07782258, 1.16666667]])

    (r0, c0, r1, c1) = (1.0, 1.5, 2.1, 2.5)

    poly = Path(np.vstack((hand[:, 1], hand[:, 0])).T, closed=True)
    clip_rect = transforms.Bbox([[r0, c0], [r1, c1]])
    poly_clipped = poly.clip_to_bbox(clip_rect).to_polygons()[0]

    assert np.all(poly_clipped[-2] != poly_clipped[-1])
    assert np.all(poly_clipped[-1] == poly_clipped[0])
Example #19
0
def test_point_in_path_nan():
    box = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]])
    p = Path(box)
    test = np.array([[np.nan, 0.5]])
    contains = p.contains_points(test)
    assert len(contains) == 1
    assert not contains[0]
Example #20
0
    def _endGate(self, event):
        #draw gate rectangle
        start_x = self.start_x if self.start_x < event.xdata else event.xdata
        start_y = self.start_y if self.start_y < event.ydata else event.ydata
        width = np.absolute(event.xdata-self.start_x)
        height = np.absolute(event.ydata-self.start_y)
        rect = Rectangle((start_x, start_y), width, height, 
                         fill=False, ec='black', alpha=1, lw=2)
        self.ax.add_patch(rect)
        self.canvas.draw()

        #disable mouse events
        self.canvas.mpl_disconnect(self.buttonPress)
        self.canvas.mpl_disconnect(self.buttonRelease)
        self.canvas.get_tk_widget().config(cursor='arrow')
 
        #save cell gate
        gate = Path([[start_x, start_y], 
                     [start_x + width, start_y],
                     [start_x + width, start_y + height], 
                     [start_x, start_y + height],
                     [start_x, start_y]])
        gated_cells = self.scdata.tsne.index[gate.contains_points(self.scdata.tsne)]
        self.gates[self.gateName.get()] = gated_cells

        #replot tSNE w gate colored
        self.fig.clf()
        plt.scatter(self.scdata.tsne['x'], self.scdata.tsne['y'], s=10, edgecolors='none', color='lightgrey')
        plt.scatter(self.scdata.tsne.ix[gated_cells, 'x'], self.scdata.tsne.ix[gated_cells, 'y'], s=10, edgecolors='none')
        self.canvas.draw()

        self.setGateButton.config(state='disabled')
        self.visMenu.entryconfig(6, state='disabled')
    def pca_var(sub_dims):
        data = np.array([df[d] for d in sub_dims]).T
        try: pca = PCA(data, standardize=True)
        except: return 0,1,0,1,None,None,None,sub_dims

        classed_points = zip(classes, pca.Y)
        pos = [(it[0], it[1]) for c, it in classed_points if c]
        neg = [(it[0], it[1]) for c, it in classed_points if not c]
        P_hull = [pos[i] for i in ConvexHull(pos).vertices]; P_hull.append(P_hull[0])
        N_hull = [neg[i] for i in ConvexHull(neg).vertices]; N_hull.append(N_hull[0])
        P_hull = np.array(P_hull)
        N_hull = np.array(N_hull)
        P_path = Path(P_hull)
        N_path = Path(N_hull)

        N_sep = 0
        for it in neg:
            if not P_path.contains_point(it):
                N_sep += 1

        P_sep = 0
        for it in pos:
            if not N_path.contains_point(it):
                P_sep += 1

        return N_sep, float(len(neg)), P_sep, float(len(pos)), P_hull, N_hull, pca, sub_dims
Example #22
0
def paths_in_shape(paths):

    shape = shape_(shape_path)
    
    minx, miny, maxx, maxy = shape.bounds
    
    #print minx; print miny; print maxx; print maxy
    #bounding_box = geometry.box(minx, miny, maxx, maxy)

    #generate random points within bounding box! 
    
    sf = shapefile.Reader(shape_path)
    
    shape = sf.shapes()[0]

    #find polygon nodes lat lons
    verticies = shape.points
    
    #convert to a matplotlib path class!
    polygon = Path(verticies)
    points_in_shape = polygon.contains_points(paths)
    
    points_in_shape = paths[points_in_shape == True]
    
    return points_in_shape
Example #23
0
def get_mask_img(transform, target_bin, camera_model):
    """
    :param point: point that is going to be transformed
    :type point: PointStamped
    :param transform: camera_frame -> bbox_frame
    :type transform: Transform
    """
    # check frame_id of a point and transform just in case
    assert camera_model.tf_frame == transform.header.frame_id
    assert target_bin.bbox.header.frame_id == transform.child_frame_id

    transformed_list = [
            do_transform_point(corner, transform)
            for corner in target_bin.corners]
    projected_points = project_points(transformed_list, camera_model)

    # generate an polygon that covers the region
    path = Path(projected_points)
    x, y = np.meshgrid(
            np.arange(camera_model.width),
            np.arange(camera_model.height))
    x, y = x.flatten(), y.flatten()
    points = np.vstack((x, y)).T
    mask_img = path.contains_points(
            points).reshape(
                    camera_model.height, camera_model.width
                ).astype('bool')
    return mask_img
Example #24
0
 def subsample(self, vertices):
     xiyi = np.vstack((self.traj_lon[0,:], self.traj_lat[0,:])).T
     mpath = MplPath( vertices )
     outside_area = ~mpath.contains_points(xiyi)
     self.init_x, self.init_y, self.init_z, self.init_s, \
                self.traj_lon, self.traj_lat, self.traj_depth, self.traj_time, self.final_z = \
              [x.compress(outside_area,axis=-1)  for x in (self.init_x, self.init_y, self.init_z, self.init_s,
                self.traj_lon, self.traj_lat, self.traj_depth, self.traj_time, self.final_z)]
Example #25
0
def check_paths(path):
    for other_path in a:
        res = 'no cross'
        chck = Path(other_path)
        if chck.contains_path(path) == 1:
            res = 'cross'
            break
    return res
Example #26
0
    def __init__(self):
        self.inner_path = Path(inner)
        self.outer_path = Path(outer)

        self.lines = list()
        for arr in (inner, outer):
            for i in range(len(arr)-1):
                self.lines.append(self.get_line_from_two_points(arr[i], arr[i+1]))
Example #27
0
def test_point_in_path():
    # Test #1787
    verts2 = [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]

    path = Path(verts2, closed=True)
    points = [(0.5, 0.5), (1.5, 0.5)]

    assert np.all(path.contains_points(points) == [True, False])
Example #28
0
def draw_star(ax, x, y, color, scale=0.1):
    path = Path(unit_star.vertices * scale, unit_star.codes)
    trans = matplotlib.transforms.Affine2D().translate(x, y)
    t_path = path.transformed(trans)
    patch = patches.PathPatch(t_path, facecolor=color.value, lw=line_weight, zorder=2)
    a = ax.add_patch(patch)
    ma = MonosaccharidePatch(saccharide_shape=(a,))
    return ma
Example #29
0
def segments_in_polygon(segments, poly_verts):
    """Go to the centroid of each segment, see if it is in the polygon
    """
    segments = np.array(segments, dtype=float)
    pt1 = segments[:, 0]
    pt2 = segments[:, 1]
    centroids = (pt1 + pt2) / 2.
    p = Path(poly_verts)
    return p.contains_points(centroids)
Example #30
0
def test_point_in_path():
    # Test #1787
    verts2 = [(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]

    path = Path(verts2, closed=True)
    points = [(0.5, 0.5), (1.5, 0.5)]
    ret = path.contains_points(points)
    assert ret.dtype == 'bool'
    assert np.all(ret == [True, False])
Example #31
0
 def onselect(self, verts):
     path = Path(verts)
     self.poly_mask = poly2mask(self.x, self.y, path)
     self.canvas.draw_idle()
Example #32
0
    c1x_left, c1y_left, c1x_right, c1y_right = \
              get_normal_points(c1x, c1y, cos_t1, sin_t1, width*w1)
    c3x_left, c3y_left, c3x_right, c3y_right = \
              get_normal_points(c3x, c3y, cos_t2, sin_t2, width*w2)

    # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and c12-c23
    c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5
    c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5
    c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5

    # tangential angle of c123 (angle between c12 and c23)
    cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y)

    c123x_left, c123y_left, c123x_right, c123y_right = \
                get_normal_points(c123x, c123y, cos_t123, sin_t123, width*wm)

    path_left = find_control_points(c1x_left, c1y_left, c123x_left, c123y_left,
                                    c3x_left, c3y_left)
    path_right = find_control_points(c1x_right, c1y_right, c123x_right,
                                     c123y_right, c3x_right, c3y_right)

    return path_left, path_right


if 0:
    path = Path([(0, 0), (1, 0), (2, 2)],
                [Path.MOVETO, Path.CURVE3, Path.CURVE3])
    left, right = divide_path_inout(path, inside)
    clf()
    ax = gca()
Example #33
0
class Ticks(AttributeCopier, Line2D):
    """
    Ticks are derived from Line2D, and note that ticks themselves
    are markers. Thus, you should use set_mec, set_mew, etc.

    To change the tick size (length), you need to use
    set_ticksize. To change the direction of the ticks (ticks are
    in opposite direction of ticklabels by default), use
    set_tick_out(False).
    """
    def __init__(self, ticksize, tick_out=False, *, axis=None, **kwargs):
        self._ticksize = ticksize
        self.locs_angles_labels = []

        self.set_tick_out(tick_out)

        self._axis = axis
        if self._axis is not None:
            if "color" not in kwargs:
                kwargs["color"] = "auto"
            if "mew" not in kwargs and "markeredgewidth" not in kwargs:
                kwargs["markeredgewidth"] = "auto"

        Line2D.__init__(self, [0.], [0.], **kwargs)
        self.set_snap(True)

    def get_ref_artist(self):
        # docstring inherited
        return self._axis.majorTicks[0].tick1line

    def get_color(self):
        return self.get_attribute_from_ref_artist("color")

    def get_markeredgecolor(self):
        return self.get_attribute_from_ref_artist("markeredgecolor")

    def get_markeredgewidth(self):
        return self.get_attribute_from_ref_artist("markeredgewidth")

    def set_tick_out(self, b):
        """Set whether ticks are drawn inside or outside the axes."""
        self._tick_out = b

    def get_tick_out(self):
        """Return whether ticks are drawn inside or outside the axes."""
        return self._tick_out

    def set_ticksize(self, ticksize):
        """Set length of the ticks in points."""
        self._ticksize = ticksize

    def get_ticksize(self):
        """Return length of the ticks in points."""
        return self._ticksize

    def set_locs_angles(self, locs_angles):
        self.locs_angles = locs_angles

    _tickvert_path = Path([[0., 0.], [1., 0.]])

    def draw(self, renderer):
        if not self.get_visible():
            return

        gc = renderer.new_gc()
        gc.set_foreground(self.get_markeredgecolor())
        gc.set_linewidth(self.get_markeredgewidth())
        gc.set_alpha(self._alpha)

        path_trans = self.get_transform()
        marker_transform = (Affine2D().scale(
            renderer.points_to_pixels(self._ticksize)))
        if self.get_tick_out():
            marker_transform.rotate_deg(180)

        for loc, angle in self.locs_angles:
            locs = path_trans.transform_non_affine(np.array([loc]))
            if self.axes and not self.axes.viewLim.contains(*locs[0]):
                continue
            renderer.draw_markers(
                gc, self._tickvert_path,
                marker_transform + Affine2D().rotate_deg(angle), Path(locs),
                path_trans.get_affine())

        gc.restore()
Example #34
0
def _points_inside_poly(points, verts):
    poly = Path(verts)
    return [ind for ind, p in enumerate(points) if poly.contains_point(p)]
def getAlertMasks(map_group):
    _, graphics = map_group

    # mask will have shape defined by the image map extent divided
    # into 0.1 degree grid
    res = 0.1
    # lon_min, lon_max, lat_min, lat_max = [round(x, 1) for x in extent_MAP_IMG]
    # nx, ny = np.array([lon_max - lon_min, lat_max - lat_min])/res
    # img_shape = (round(nx), round(ny), 3)
    lon_min, lon_max, lat_min, lat_max = extent_MAP_IMG
    x = np.arange(lon_min, lon_max, res) # [round(x,1) for x in x]
    y = np.arange(lat_min, lat_max, res) # [round(y,1) for y in y]
    xx, yy = np.meshgrid(x, y)
    xy = np.vstack((xx.ravel(), yy.ravel())).T

    # Create transformation matrix
    tm = np.array([res, 0, 0, res, lon_min, lat_min])
    m = np.hstack((tm.reshape(3,2), np.array([[0],[0],[1]])))
    try:
        m_inv = LA.inv(m)
    except LinAlgError:
        sys.exit("Could not invert transformation matrix")

    mask_list = []
    for i in range(len(graphics)):
        col = graphics[i]['path']['colour']
        print(col)
        if col['stroke'] is not None and col['stroke'].count(col['stroke'][0]) != 3:
            # got a contour with RGB colour
            alert_val = 0
            r, g, b = col
            if col == (0.0, 0.0, 0.0):
                print("colour: black")
            elif col == (1.0, 1.0, 0.0):
                print("colour: yellow")
                alert_val = 1
            elif g > 0.33 and g < 0.66:
                # (0.89, 0.424, 0.0392)
                # (0.969, 0.588, 0.275)
                print("colour: orange")
                alert_val = 2
            elif g < 0.33:
                print("colour: red")
                alert_val = 3
            else:
                print("colour: other")

            #img = np.zeros(img_shape, dtype = np.double)
            img2 = np.array([alert_val]*xx.size).reshape(xx.shape)
            img = np.zeros(xx.shape, dtype = np.double)

            # nodes_new = []
            # for curve in graphics[i]['path']['contour']:
            #     # transform curve to grid coords
            #     nodes = curve.nodes
            #     for i in range(len(nodes.T)):
            #         # Multiply node by transformation matrix m to
            #         # get grid coordinates
            #         v = np.matmul(np.append(nodes.T[i], 1), m_inv)
            #         nodes_new.append(v[:-1])
            # nodes = np.array([node.round() for node in nodes_new])
            # mask = skimage.draw.polygon2mask(img_shape[:-1], nodes)
            # img[mask] = col
            #mask_list.append(img)

            ## alternative approach
            vv = np.vstack([curve.nodes.T for curve in graphics[i]['path']['contour']])
            # construct a Path from the vertices
            pth = Path(vv, closed=False)

            # test which pixels fall within the path
            mask = pth.contains_points(xy)

            # reshape to the same size as the grid
            mask = mask.reshape(xx.shape)

            # create a masked array
            masked = np.ma.masked_array(img2, ~mask)

            # or simply set values for masked pixels
            img[mask] = alert_val

            # combine with coords...
            am = np.stack((xx, yy, img))

            mask_list.append(am)
    return mask_list
Example #36
0
from py_eddy_tracker.dataset.grid import RegularGridDataset
from py_eddy_tracker.data import get_path
from matplotlib.path import Path
from pytest import approx

G = RegularGridDataset(get_path("mask_1_60.nc"), "lon", "lat")
X = 0.025
contour = Path(((-X, 0), (X, 0), (X, X), (-X, X), (-X, 0),))


# contour
def test_contour_lon():
    assert (contour.lon == (-X, X, X, -X, -X)).all()


def test_contour_lat():
    assert (contour.lat == (0, 0, X, X, 0)).all()


def test_contour_mean():
    assert (contour.mean_coordinates == (0, X / 2)).all()


def test_contour_fit_circle():
    x, y, r, err = contour.fit_circle()
    assert x == approx(0)
    assert y == approx(X / 2)
    assert r == approx(3108, rel=1e-1)
    assert err == approx(49.1, rel=1e-1)

df = pd.read_csv('Columbus_TVData_GradeB_SepDis.csv')
cols_to_use = df.columns
cols_to_use = []
for degree in range(1, 360, 2):
    cols_to_use.append("Latitude." + str(degree))
    cols_to_use.append("Longitude." + str(degree))
dfa = df[cols_to_use]
fr = dfa
fr.values.shape
poly_overall = fr.values.reshape((len(dfa), 180, 2))
path_overall = []
for row in range(0, len(dfa)):
    temp = dfa.ix[row]
    path_individual_row = [m(t[1], t[0]) for t in poly_overall[row]]
    path_overall.append(Path(path_individual_row))
chan_NA = []
chan_NA_co = []
chan_NA_adj = []
chan_NA_SET = []
Num_chan_avl = []
chan_avl = []
CELL_MAX = len(center)  #Total number of cells in the area
out_channels = {}
for cell in range(0, CELL_MAX):
    CHAN_CNT_USE = []
    center_ext = []
    print 'Cell no is'
    print cell
    TV_loc = []
    TV_ERP = []
Example #38
0
def triplot(ax, *args, **kwargs):
    """
    Draw a unstructured triangular grid as lines and/or markers to
    the :class:`~matplotlib.axes.Axes`.

    The triangulation to plot can be specified in one of two ways;
    either::

      triplot(triangulation, ...)

    where triangulation is a :class:`~matplotlib.tri.Triangulation`
    object, or

    ::

      triplot(x, y, ...)
      triplot(x, y, triangles, ...)
      triplot(x, y, triangles=triangles, ...)
      triplot(x, y, mask, ...)
      triplot(x, y, mask=mask, ...)
      triplot(x, y, triangles, mask, ...)
      triplot(x, y, triangles, mask=mask, ...)

    in which case a Triangulation object will be created.  See
    :class:`~matplotlib.tri.Triangulation` for a explanation of these
    possibilities.

    The remaining args and kwargs are the same as for
    :meth:`~matplotlib.axes.Axes.plot`.

    **Example:**

        .. plot:: mpl_examples/pylab_examples/triplot_demo.py
    """
    import matplotlib.axes

    tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)

    x = tri.x
    y = tri.y
    edges = tri.edges

    # If draw both lines and markers at the same time, e.g.
    #     ax.plot(x[edges].T, y[edges].T, *args, **kwargs)
    # then the markers are drawn more than once which is incorrect if alpha<1.
    # Hence draw lines and markers separately.

    # Decode plot format string, e.g. 'ro-'
    fmt = ''
    if len(args) > 0:
        fmt = args[0]
    linestyle, marker, color = matplotlib.axes._process_plot_format(fmt)

    # Draw lines without markers, if lines are required.
    if linestyle is not None and linestyle is not 'None':
        kw = kwargs.copy()
        kw.pop('marker', None)     # Ignore marker if set.
        kw['linestyle'] = ls_mapper[linestyle]
        kw['edgecolor'] = color
        kw['facecolor'] = None

        vertices = np.column_stack((x[edges].flatten(), y[edges].flatten()))
        codes = ([Path.MOVETO] + [Path.LINETO])*len(edges)

        path = Path(vertices, codes)
        pathpatch = PathPatch(path, **kw)

        ax.add_patch(pathpatch)

    # Draw markers without lines.
    # Should avoid drawing markers for points that are not in any triangle?
    kwargs['linestyle'] = ''
    ax.plot(x, y, *args, **kwargs)
Example #39
0
def test_path_to_polygons():
    data = [[10, 10], [20, 20]]
    p = Path(data)

    assert_array_equal(p.to_polygons(width=40, height=40), [])
    assert_array_equal(p.to_polygons(width=40, height=40, closed_only=False),
                       [data])
    assert_array_equal(p.to_polygons(), [])
    assert_array_equal(p.to_polygons(closed_only=False), [data])

    data = [[10, 10], [20, 20], [30, 30]]
    closed_data = [[10, 10], [20, 20], [30, 30], [10, 10]]
    p = Path(data)

    assert_array_equal(p.to_polygons(width=40, height=40), [closed_data])
    assert_array_equal(p.to_polygons(width=40, height=40, closed_only=False),
                       [data])
    assert_array_equal(p.to_polygons(), [closed_data])
    assert_array_equal(p.to_polygons(closed_only=False), [data])
Example #40
0
def test_make_compound_path_empty():
    # We should be able to make a compound path with no arguments.
    # This makes it easier to write generic path based code.
    r = Path.make_compound_path()
    assert r.vertices.shape == (0, 2)
Example #41
0
    def get_markers_per_structure(self):
        """Sort markers into ROIs.

        The markers in the hdf5 file will be sorted into each identified
        ROI and a table with counts per ROI is returned.

        Returns
        -------
        pandas.Series
            A pandas table with ROI name and cell counts
        """
        ontology = Ontology()
        sorted_markers = pd.DataFrame(index=np.arange(self.nmarkers))
        for roi_name, roi_xy in self.rois.items():
            path = Path(roi_xy)
            sorted_markers[roi_name] = path.contains_points(
                    self.markers)

        # Raise an error if a marker is not assigned to at least one
        # ROI.
        if not np.all(sorted_markers.sum(axis=1) > 0):
            msg = "There are markers with no ROI ({})".format(
                    os.path.split(self.fname)[-1])
            raise ValueError(msg)

        # Remove the structures without markers from analysis.
        sorted_markers = sorted_markers[
                sorted_markers.columns[sorted_markers.sum(0) > 0]]

        # Verify that all structure names in the set do exist as
        # acronyms in the Allen ontology.
        structs = [ontology(name) for name in
                   sorted_markers.columns.values]
        if None in structs:
            indices = np.where(structs)
            iswrong = np.ones(sorted_markers.columns.size, bool)
            iswrong[indices] = False
            iswrong = sorted_markers.columns.values[iswrong]
            msg = '{}: invalid acronym(s) {}'.format(
                        self.fname, iswrong)
            self.ISW = iswrong
            raise ValueError(msg)

        # Some markers may fall inside more than one structure. In
        # those cases the sum per row (i.e. sum of True values per
        # marker) will be more than one: sorted_mrk[sorted_mrk.sum(1)
        # > 1]. We must decide which structure to assign the marker to
        # on a case-by-case basis. Each series in the following
        # iteration is a marker with boolean values of the structure it
        # falls into.
        is_repeated = sorted_markers.sum(1) > 1
        for indx, ser in sorted_markers[is_repeated].iterrows():
            # Use only the True values in the series.
            ser = ser[ser]

            # Create a list of structures that all contain the same
            # marker.
            isin = [ontology[key] for key in list(ser.keys())]

            # 'None' will be returned from ontology if the key is not
            # in it, ie if the acronym does not exist in the ontology
            # database (as would happen when typing wrong
            # capitalisation, not naming roi, etc).
            if None in isin:
                msg = 'File {}: {} is not a valid acronym'.format(
                        self.fname, ser.index.values)
                raise ValueError(msg)

            # I have not decided how to deal with cases where the
            # marker falls inside more that 2 structures.
            msg = 'One marker in more than one structure {}'.format(
               isin)
            assert len(isin) == 2, msg

            # Sort list of structures. The order will increase with
            # depth in the ontology tree, so we expect the last
            # structure in the list to be within the first one.
            isin.sort()
            if isin[-1] not in isin[0]:
                msg = 'Structure {} is not part of structure {}'.format(
                        isin[-1], isin[0])
                raise ValueError(msg)

            # If the above assumptions are true (ie that, compared to
            # the first structure, the second structure in the list is
            # deeper in the ontology and it is its subset), then we can
            # set the membership of the marker to the topmost structure
            # to false. That is, of the two structures, the marker is
            # assigned to the deeper one.
            sorted_markers.loc[indx][isin[0].acronym] = False

        # Confirm that now each marker belongs to only one structure.
        assert np.all(sorted_markers.sum(axis=1) == 1)

        # Finally, quantify and return the number of markers per
        # structure.
        return sorted_markers.sum(axis=0)
Example #42
0
 def _get_transformed_clip_path(self):
     x, y, width, height = self.state.clipping_path
     rect = ((x, y), (x + width, y), (x + width, y + height), (x,
                                                               y + height))
     transform = Affine2D.from_values(*affine.affine_params(self.get_ctm()))
     return TransformedPath(Path(rect), transform)
Example #43
0
lim = -5.8, 5.7
ax.set(xlim=lim, ylim=lim)

print(mpl.__file__)

marker_obj = m.MarkerStyle('$?$')
path = marker_obj.get_path().transformed(marker_obj.get_transform())

path._vertices = np.array(path._vertices) * 8  #To make it larger
path._vertices[4] = [0, 0]  #This is where the vertices close
full_codes = path.codes
full_vertices = path._vertices
mark_vertices = full_vertices[5:]
mark_codes = full_codes[5:]

circ_path = Path.unit_circle()
circ_verts = circ_path._vertices * 0.65 + [0.1, -3]
circ_codes = circ_path.codes

##print(circ_verts)
##print(circ_codes)

new_vertices = np.append(circ_verts, mark_vertices, axis=0) - [0, 0.5]
new_codes = np.append(circ_codes, mark_codes, axis=0)
"""All this stuff that is commented out was used to make this path.
when ? was used to create the path. The little dot under the ? was
shown as a square, not a circle. So I had to modify the geometric
descriptors of the patch to make it look better. DO NOT ATTEMPT
THIS ON IMPORTANT FILES"""

##print(new_vertices)
Example #44
0
code_map = {
    'M': (Path.MOVETO, 1),
    'C': (Path.CURVE4, 3),
    'L': (Path.LINETO, 1)
}

while i < len(parts):
    code = parts[i]
    path_code, npoints = code_map[code]
    codes.extend([path_code] * npoints)
    vertices.extend([[float(x) for x in y.split(',')]
                     for y in parts[i + 1:i + npoints + 1]])
    i += npoints + 1
vertices = np.array(vertices, np.float)
vertices[:, 1] -= 160

dolphin_path = Path(vertices, codes)
dolphin_patch = PathPatch(dolphin_path,
                          facecolor=(0.6, 0.6, 0.6),
                          edgecolor=(0.0, 0.0, 0.0))
ax.add_patch(dolphin_patch)

vertices = Affine2D().rotate_deg(60).transform(vertices)
dolphin_path2 = Path(vertices, codes)
dolphin_patch2 = PathPatch(dolphin_path2,
                           facecolor=(0.5, 0.5, 0.5),
                           edgecolor=(0.0, 0.0, 0.0))
ax.add_patch(dolphin_patch2)

plt.show()
Example #45
0
    plt.connect('button_press_event', cnv.update_path_mouse)
    plt.connect('motion_notify_event', cnv.set_location)
    plt.connect('key_press_event', cnv.update_path_key)

    if args.keepROI:
        print "Keep points inside ROI"
    else:
        print "Throw away points inside ROI"
    plt.show()

    myVerts = cnv.vert
    eigvec.attrs['/outlierROI'] = myVerts
    print "myVerts: ", myVerts

    path1 = Path(myVerts)
    index = path1.contains_points(eigvec[:, np.array([eigs[0], eigs[1]])])

    if args.keepROI:
        myRejects = np.sort(np.asarray(
            np.where(index == 0)[0]))  # reject indices outside ROI
        myKeeps = np.asarray(
            np.where(index == 1)[0])  # keep indices inside ROI
    else:
        myRejects = np.sort(np.asarray(
            np.where(index == 1)[0]))  # reject indices inside ROI
        myKeeps = np.asarray(
            np.where(index == 0)[0])  # keep indices outside ROI

    numRejects = len(myRejects)
    print "myRejects: ", numRejects
Example #46
0
    def __init__(self,
                 llcrnrlon,
                 llcrnrlat,
                 urcrnrlon,
                 urcrnrlat,
                 resolution='i',
                 projection='merc',
                 rasterize=True,
                 rasterize_resolution=500):

        logging.debug('Creating Basemap...')

        if projection == 'cyl':  # TODO: should be fixed
            raise ValueError(
                'Cyl projection not supported, as rasterisation needs units of m'
            )

        # Generate Basemap instane
        self.map = Basemap(llcrnrlon,
                           llcrnrlat,
                           urcrnrlon,
                           urcrnrlat,
                           area_thresh=0,
                           resolution=resolution,
                           projection=projection)

        # Store proj4 string
        self.proj4 = self.map.proj4string

        # Run constructor of parent Reader class
        super(Reader, self).__init__()

        # Depth
        self.z = None

        # Time
        self.start_time = None
        self.end_time = None
        self.time_step = None

        # Read and store min, max and step of x and y
        self.xmin, self.ymin = self.lonlat2xy(llcrnrlon, llcrnrlat)
        self.xmax, self.ymax = self.lonlat2xy(urcrnrlon, urcrnrlat)
        self.delta_x = None
        self.delta_y = None

        # Extract polygons for faster checking of stranding
        if has_nxutils is True:
            self.polygons = [p.boundary for p in self.map.landpolygons]
        else:
            self.polygons = [Path(p.boundary) for p in self.map.landpolygons]

        # Generate rasterized version of polygons for faster checking of stranding
        # (if enabled)
        if (rasterize == True):
            if (len(self.map.landpolygons) == 0):
                logging.debug('No land polygons to rasterize...')
                self.bmap_raster = None
            else:
                logging.debug('Creating rasterized Basemap...')
                try:
                    self.bmap_raster = self.gen_land_bitmap(
                        self.map, rasterize_resolution)
                except Exception as e:
                    logging.warning(
                        'Rasterizing Basemap failed! Continuing without rasterized version. Received "'
                        + e.message + '"')
                    self.bmap_raster = None
        else:
            self.bmap_raster = None

        # Calculate aspect ratio, to minimise whitespace on figures
        # Drawback is that empty figure is created in interactive mode
        meanlat = (llcrnrlat + urcrnrlat) / 2
        aspect_ratio = np.float(urcrnrlat - llcrnrlat) / \
            (np.float(urcrnrlon-llcrnrlon))
        if projection != 'cyl':
            aspect_ratio = aspect_ratio / np.cos(np.radians(meanlat))
        if aspect_ratio > 1:
            self.figsize = (10. / aspect_ratio, 10.)
            plt.figure(0, figsize=(10. / aspect_ratio, 10.))
        else:
            self.figsize = (11., 11. * aspect_ratio)
            plt.figure(0, figsize=(11., 11. * aspect_ratio))
        ax = plt.axes([.05, .05, .85, .9])
Example #47
0
def action_method(parentwidget):
    from matplotlib.patches import FancyArrowPatch,PathPatch
    from matplotlib.path import Path
    import dev_tools.hierarchy
    plt.ion()
    operations = parentwidget.design.operations
    ids = [operation.id for operation in operations]

    children = {}
    for item in ids:
        children[item] = []
        
#    labels = dict([(operation.id,str(operation)) for operation in operations])
#    links = []
    for child in operations:
#        parentrefs = child.parentrefs()
        for parentref in child.parentrefs():
#            links.append([parentref,child.id])
            children[parentref].append(child.id)
#    edges = [(item[0],item[1]) for item in links]

    connections = dev_tools.hierarchy.create_sorted_connections(ids,lambda item:children[item])
#    num_levels = dev_tools.hierarchy.num_levels(connections)
    
    arrow_points = {}
    arrow_points2 = {}
#    codes = [Path.MOVETO,Path.CURVE3,Path.CURVE3]    
    codes = []
    codes.append(Path.MOVETO)
    codes.append(Path.LINETO)
#    codes.append(Path.CURVE3)
#    codes.append(Path.CURVE3)
#    codes.append(Path.LINETO)
#    codes.append(Path.CURVE3)
#    codes.append(Path.CURVE3)
#    codes.append(Path.LINETO)
    codes.append(Path.CURVE4)
    codes.append(Path.CURVE4)
    codes.append(Path.CURVE4)
    codes.append(Path.LINETO)

    for c in connections:
        vertices = []
        vertices.append((0,-c.ii))
        vertices.append((.25,-c.ii))
#        vertices.append((c.level+.75,c.ii))
        vertices.append((c.level+1,-c.ii))
#        vertices.append((c.level+1,c.ii+.25))
#        vertices.append((c.level+1,c.jj-.25))
        vertices.append((c.level+1,-c.jj))
#        vertices.append((c.level+.75,c.jj))
        vertices.append((.25,-c.jj))
        vertices.append((0,-c.jj))
        arrow_points[c]=Path(vertices,codes)
        arrow_points2[c]=Path([(.25,-c.jj),(0,-c.jj),(0,-c.jj)],[Path.MOVETO,Path.CURVE3,Path.CURVE3])
    
#    y = numpy.r_[spacing*len(ids):0:-1*spacing]
#    xy = numpy.c_[y*0,y]    
#    pos = dict([(item,pos) for item,pos in zip(ids,xy)])

    w = GraphView(parentwidget)
    w.axes.autoscale(True)
#    labelpos = dict((key,value+[-0.1,0]) for key,value in pos.items())

    w.clear()
#    for link,(x,y) in labelpos.items():
#        w.text(x, y,labels[link],**text_style)
    for ii,operation in enumerate(operations):
        w.text(0,-ii,str(operation),**text_style)
#    for edge in edges:
    for c in connections:
        w.add_patch(PathPatch(path=arrow_points[c],facecolor='none', lw=2))
        w.add_patch(FancyArrowPatch(path=arrow_points2[c],**arrow_style))
#    circlepos = numpy.array([(0,-item) for item in range(len(operations))])
#    w.scatter(circlepos[:,0],circlepos[:,1],**circle_style)        
    w.axes.axis('equal')
    w.axes.axis('off')
    w.draw()
    return w
def print_multiplepath(x,y,stations_coord,h=20,l=20, Dlab = 10, Slab = 20, name = 0):
  # plot

   
    verts_x = []
    for st in x: # take the best path and plot
      try:
        verts_x.append(stations_coord[st])
      except Exception as e: 
        print(e)
    codes_x = [Path.MOVETO]*len(verts_x)
    path_x = Path(verts_x, codes_x)

    verts_y = []
    for st in y: # take the best path and plot
      try:
        verts_y.append(stations_coord[st])
      except Exception as e: 
        print(e)
    codes_y = [Path.MOVETO]*len(verts_y)
    path_y = Path(verts_y, codes_y)

    fig = plt.figure(figsize=(h,l))
    #ax1 = fig.add_subplot(111)
    ax1 = plt.axes()
    plt.grid()
    #fig, ax = plt.subplots()
    
    patch_x = patches.PathPatch(path_x, facecolor='none', lw=2)
    ax1.add_patch(patch_x)
    x_xs, x_ys = zip(*verts_x)

    patch_y = patches.PathPatch(path_y, facecolor='none', lw=2)
    ax1.add_patch(patch_y)
    y_xs, y_ys = zip(*verts_y)

    # settings of plto
    ax1.plot(x_xs, x_ys, lw=4, color='blue', ms=10,alpha = 0.3, label='x')
    ax1.plot(y_xs, y_ys, lw=4, color='red', ms=10,alpha = 0.5, label='y')

    #plot ticks
    ax1.set_xticks(np.arange(min(x_xs)-1, max(x_xs)+1,max(x_xs)/10))
    ax1.set_yticks(np.arange(min(x_ys)-1, max(x_ys)+1,max(x_ys)/10))

    
    for i,txt in enumerate(labels_stations):
      if i != len(labels_stations)-1:
        dx,dy = get_labels_distances(x_xs[i],x_ys[i],d=Dlab)
        plt.annotate(txt, 
                    (x_xs[i], x_ys[i]),
                    textcoords="offset points", # how to position the text
                      xytext=(dx,dy), # distance from text to points (x,y)
                      ha='center', # horizontal alignment can be left, right or center 
                    size = Slab
                    )
    #plot the nodes
    ax1.scatter(x_xs,x_ys, s=10, c='b', marker="s", alpha = 0.3)
    ax1.scatter(y_xs,y_ys, s=10, c='r', marker="o", alpha = 0.5)
    
    #plot legend and title
    plt.legend(loc='upper left');
    if name != 0:
      plotlabel = "%s" %name
      plt.title (plotlabel , size=20)


    plt.show()
def createGriddedData(map_groups, alert_data, file_path=None):
    # container for gridded data layers
    vars = {}

    # data will have shape defined by the image map extent divided
    # into 0.1 degree grid
    res = 0.1
    lon_min, lon_max, lat_min, lat_max = extent_MAP_IMG
    x = np.arange(lon_min, lon_max, res) # [round(x,1) for x in x]
    y = np.arange(lat_min, lat_max, res) # [round(y,1) for y in y]
    xx, yy = np.meshgrid(x, y)
    xy = np.vstack((xx.ravel(), yy.ravel())).T

    # Create transformation matrix
    tm = np.array([res, 0, 0, res, lon_min, lat_min])
    m = np.hstack((tm.reshape(3,2), np.array([[0],[0],[1]])))
    try:
        m_inv = LA.inv(m)
    except LinAlgError:
        sys.exit("Could not invert transformation matrix")

    for i, mg in enumerate(map_groups):
        _, graphics = mg
        print(i)

        # count arrays added for this group
        n = 0

        for j, gfx in enumerate(graphics):
            colour = gfx['path']['colour']
            print(colour)
            col = None
            if colour['stroke'] is not None and len(colour['stroke']) == 3:
                col = colour['stroke']
            elif colour['fill'] is not None and len(colour['fill']) == 3:
                col = colour['fill']
            if col is not None:
                # got a contour with associated RGB colour
                print(col)
                alert_val = 0
                r, g, b = col
                if col == (0.0, 0.0, 0.0):
                    print("colour: black")
                elif col == (1.0, 1.0, 0.0):
                    print("colour: yellow")
                    alert_val = 1
                elif col == (1.0, 0.0, 0.0):
                    print("colour: red")
                    alert_val = 3
                elif g > 0.25 and g < 0.66:
                    # (0.89, 0.424, 0.0392)
                    # (0.969, 0.588, 0.275)
                    # (0.596, 0.282, 0.0275)
                    print("colour: orange")
                    alert_val = 2
                elif r > 0.9 and g < 0.25:
                    print("colour: red")
                    alert_val = 3
                else:
                    print("colour: other")

                img = np.zeros(xx.shape, dtype = np.double)

                # get nodes for the alert area
                vv = np.vstack([curve.nodes.T for curve in gfx['path']['contour']])

                # construct a Path from the vertices
                pth = Path(vv, closed=False)

                # test which pixels fall within the path
                mask = pth.contains_points(xy)

                # reshape to the same size as the grid
                mask = mask.reshape(xx.shape)

                # set values for masked pixels
                img[mask] = alert_val

                da = xr.DataArray(data=img, dims=["lat", "lon"], coords=[y, x])

                da.attrs = {
                    'issue_date': alert_data.loc[i,'issue_date'],
                    'alert_date': alert_data.loc[i,'date'],
                    'alert_day': alert_data.loc[i,'day'],
                    'alert_weekday': alert_data.loc[i,'weekday'],
                    'alert_id': n+1,
                    'alert_type': '',
                    'alert_text': alert_data.loc[i,'alert_text'],
                }

                var_name = '_'.join(['alert', 'day'+str(da.attrs['alert_day']),
                                     str(da.attrs['alert_id'])])
                vars[var_name] = da
                n += 1

    # combine data arrays into data set
    issue_date = alert_data.loc[0, 'issue_date']
    ds = xr.Dataset(data_vars=vars,
                    attrs={
                        'title': 'TMA weather warnings for ' + issue_date,
                        'issue_date': issue_date,
                    })
    if file_path is None:
        file_path = 'TMA_weather_warning_'+issue_date+'.nc'
    ds.to_netcdf(file_path)
def print_path(current_path,stations_coord,test,h=30,l=30, Dlab = 10, Slab = 20, name = 0):
  # plot

  if test != None: 
    verts = []
    #best_path = optimized_paths[len(optimized_paths)-1]
    best_path = current_path
    for st in best_path: # take the best path and plot
      try:
        verts.append(stations_coord[st])
      except Exception as e: 
        print(e)


    codes = [Path.MOVETO]*len(verts)

    #print (best_path)
    #print (len(verts))
    #print ((len(codes)))
    path = Path(verts, codes)

    fig = plt.figure(figsize=(h,l))
    ax = plt.axes()
    plt.grid()
    #fig, ax = plt.subplots()
    
    patch = patches.PathPatch(path, facecolor='none', lw=2)
    ax.add_patch(patch)

    xs, ys = zip(*verts)

    # settings of plto
    ax.plot(xs, ys, lw=2, color='red', ms=10)
    x_axis = np.arange(min(xs)-1, max(xs)+1,max(xs)/10)
    ax.set_xticks(x_axis)
    xlabels = ["%.2f"%x for x in x_axis]
    ax.set_xticklabels(xlabels, rotation=90)
    ax.set_yticks(np.arange(min(ys)-1, max(ys)+1,max(ys)/10))

    if this_type == ("ex_circular" or "circular"):
      for i,txt in enumerate(labels_stations):
        if i < len(current_path):
          dx,dy = get_labels_distances(xs[i],ys[i],d=Dlab)
          plt.annotate(txt, 
                      (xs[i], ys[i]),
                      textcoords="offset points", # how to position the text
                        xytext=(dx,dy), # distance from text to points (x,y)
                        ha='center', # horizontal alignment can be left, right or center 
                      size = Slab
                      )
    else: 
      for i,txt in enumerate(labels_stations):
        if i < len(current_path):
          plt.annotate(txt, 
                      (xs[i], ys[i]),
                      size = Slab
                      )
          
    plt.scatter(xs, ys)

    #ax.set_xlim(-0.1, 200)
    #ax.set_ylim(-0.1, 200)
    if name != 0:
      plotlabel = "%s" %name
      plt.title (plotlabel , size=20)
    plt.show()
Example #51
0
        img = cv2.imread(img_path)
        rois = read_roi_zip(img_path.replace(".tif", ".zip"))
        height_o, width_o, channel = img.shape
        finished_image = np.zeros((height_o, width_o), np.uint8)
        h = height_o
        w = width_o
        rois_len = len(rois)
        for iter, roi in enumerate(rois):
            x = rois[roi]['x']
            y = rois[roi]['y']
            n = len(x)
            i = 0
            ListOfCorners = []
            for i in range(i, n):
                ListOfCorners.append((int((y[i])), int((x[i]))))
            poly_path = Path(ListOfCorners)
            Nx, Ny = np.mgrid[:h, :w]
            coordinates = np.hstack((Nx.reshape(-1, 1), Ny.reshape(-1, 1)))
            mask = poly_path.contains_points(coordinates)
            mask = mask.reshape(h, w)
            mask = np.array(mask, dtype=bool)
            mask = np.array(mask, dtype='uint8')
            # EROSION
            eroded_image = cv2.erode(mask, kernel_one, iterations=1)
            eroded_image = cv2.erode(eroded_image, kernel_two, iterations=1)
            border_erosion = mask - eroded_image
            # DILATION
            dilation = cv2.dilate(mask, kernel_two, iterations=1)
            border_dilatation = dilation - mask
            end_result = cv2.add(border_erosion, border_dilatation)
Example #52
0
def draw_graph(obstacles, grownobstacles, edges, sp, bb):
    fig, ax = plt.subplots()

    #DRAW GROWN OBSTACLES
    for vertices in grownobstacles:
        codes = [Path.MOVETO]
        for vertex in range(0, len(vertices) - 2):
            codes.append(Path.LINETO)
        codes.append(Path.CLOSEPOLY)

        newvertices = []
        for vertex in vertices:
            newvertices.append((vertex[0], vertex[1]))

        path = Path(newvertices, codes)

        ax = fig.add_subplot(111)
        patch = patches.PathPatch(path, facecolor='#BEDB39', lw=0, alpha=0.3)
        ax.add_patch(patch)

    #DRAW SMALL OBSTACLES
    for vertices in obstacles:
        codes = [Path.MOVETO]
        for vertex in range(0, len(vertices) - 2):
            codes.append(Path.LINETO)
        codes.append(Path.CLOSEPOLY)

        newvertices = []
        for vertex in vertices:
            newvertices.append((vertex[0], vertex[1]))

        path = Path(newvertices, codes)

        ax = fig.add_subplot(111)
        patch = patches.PathPatch(path, facecolor='#BEDB39', lw=0)
        ax.add_patch(patch)

    # DRAW ALL POSSIBLE LINES IN VISIBILITY GRAPH
    lines = []
    for edge in edges:
        lines.append([(edge[0][0], edge[0][1]), (edge[1][0], edge[1][1])])

    c = np.array(['#077EA8'])

    lc = mc.LineCollection(lines, colors=c, linewidths=2)
    ax.add_collection(lc)

    # DRAW SHORTEST PATH
    to_highlight = []
    for i in range(0, len(sp) - 1):
        to_highlight.append([sp[i], sp[i + 1]])

    c = np.array(['#FD7400'])
    lc = mc.LineCollection(to_highlight, colors=c, linewidths=3)
    ax.add_collection(lc)

    # DRAW BOUNDING BOX
    bounding = []
    for i in range(0, len(bb) - 1):
        bounding.append([bb[i], bb[i + 1]])

    c = np.array(['#BEDB39'])
    lc = mc.LineCollection(bounding, colors=c, linewidths=2)
    ax.add_collection(lc)

    ax.autoscale()
    ax.margins(0.1)

    plt.show()
Example #53
0
def sankey(ax,
           outputs=[100.],
           outlabels=None,
           inputs=[100.],
           inlabels='',
           dx=40,
           dy=10,
           outangle=45,
           w=3,
           inangle=30,
           offset=2,
           **kwargs):
    """Draw a Sankey diagram.

    outputs: array of outputs, should sum up to 100%
    outlabels: output labels (same length as outputs),
    or None (use default labels) or '' (no labels)
    inputs and inlabels: similar for inputs
    dx: horizontal elongation
    dy: vertical elongation
    outangle: output arrow angle [deg]
    w: output arrow shoulder
    inangle: input dip angle
    offset: text offset
    **kwargs: propagated to Patch (e.g. fill=False)

    Return (patch,[intexts,outtexts]).
    """
    import matplotlib.patches as mpatches
    from matplotlib.path import Path

    outs = np.absolute(outputs)
    outsigns = np.sign(outputs)
    outsigns[-1] = 0  # Last output

    ins = np.absolute(inputs)
    insigns = np.sign(inputs)
    insigns[0] = 0  # First input

    assert sum(outs) == 100, "Outputs don't sum up to 100%"
    assert sum(ins) == 100, "Inputs don't sum up to 100%"

    def add_output(path, loss, sign=1):
        h = (loss / 2 + w) * np.tan(
            outangle / 180. * np.pi)  # Arrow tip height
        move, (x, y) = path[-1]  # Use last point as reference
        if sign == 0:  # Final loss (horizontal)
            path.extend([
                (Path.LINETO, [x + dx, y]),
                (Path.LINETO, [x + dx, y + w]),
                (Path.LINETO, [x + dx + h, y - loss / 2]),  # Tip
                (Path.LINETO, [x + dx, y - loss - w]),
                (Path.LINETO, [x + dx, y - loss])
            ])
            outtips.append((sign, path[-3][1]))
        else:  # Intermediate loss (vertical)
            path.extend([
                (Path.CURVE4, [x + dx / 2, y]),
                (Path.CURVE4, [x + dx, y]),
                (Path.CURVE4, [x + dx, y + sign * dy]),
                (Path.LINETO, [x + dx - w, y + sign * dy]),
                (Path.LINETO, [x + dx + loss / 2, y + sign * (dy + h)]),  # Tip
                (Path.LINETO, [x + dx + loss + w, y + sign * dy]),
                (Path.LINETO, [x + dx + loss, y + sign * dy]),
                (Path.CURVE3, [x + dx + loss, y - sign * loss]),
                (Path.CURVE3, [x + dx / 2 + loss, y - sign * loss])
            ])
            outtips.append((sign, path[-5][1]))

    def add_input(path, gain, sign=1):
        h = (gain / 2) * np.tan(inangle / 180. * np.pi)  # Dip depth
        move, (x, y) = path[-1]  # Use last point as reference
        if sign == 0:  # First gain (horizontal)
            path.extend([
                (Path.LINETO, [x - dx, y]),
                (Path.LINETO, [x - dx + h, y + gain / 2]),  # Dip
                (Path.LINETO, [x - dx, y + gain])
            ])
            xd, yd = path[-2][1]  # Dip position
            indips.append((sign, [xd - h, yd]))
        else:  # Intermediate gain (vertical)
            path.extend([
                (Path.CURVE4, [x - dx / 2, y]),
                (Path.CURVE4, [x - dx, y]),
                (Path.CURVE4, [x - dx, y + sign * dy]),
                (Path.LINETO, [x - dx - gain / 2, y + sign * (dy - h)]),  # Dip
                (Path.LINETO, [x - dx - gain, y + sign * dy]),
                (Path.CURVE3, [x - dx - gain, y - sign * gain]),
                (Path.CURVE3, [x - dx / 2 - gain, y - sign * gain])
            ])
            xd, yd = path[-4][1]  # Dip position
            indips.append((sign, [xd, yd + sign * h]))

    outtips = []  # Output arrow tip dir. and positions
    urpath = [(Path.MOVETO, [0, 100])]  # 1st point of upper right path
    lrpath = [(Path.LINETO, [0, 0])]  # 1st point of lower right path
    for loss, sign in zip(outs, outsigns):
        add_output(sign >= 0 and urpath or lrpath, loss, sign=sign)

    indips = []  # Input arrow tip dir. and positions
    llpath = [(Path.LINETO, [0, 0])]  # 1st point of lower left path
    ulpath = [(Path.MOVETO, [0, 100])]  # 1st point of upper left path
    for gain, sign in reversed(list(zip(ins, insigns))):
        add_input(sign <= 0 and llpath or ulpath, gain, sign=sign)

    def revert(path):
        """A path is not just revertable by path[::-1] because of Bezier
        curves."""
        rpath = []
        nextmove = Path.LINETO
        for move, pos in path[::-1]:
            rpath.append((nextmove, pos))
            nextmove = move
        return rpath

    # Concatenate subpathes in correct order
    path = urpath + revert(lrpath) + llpath + revert(ulpath)

    codes, verts = zip(*path)
    verts = np.array(verts)

    # Path patch
    path = Path(verts, codes)
    patch = mpatches.PathPatch(path, **kwargs)
    ax.add_patch(patch)

    if False:  # DEBUG
        print("urpath", urpath)
        print("lrpath", revert(lrpath))
        print("llpath", llpath)
        print("ulpath", revert(ulpath))
        xs, ys = zip(*verts)
        ax.plot(xs, ys, 'go-')

    # Labels

    def set_labels(labels, values):
        """Set or check labels according to values."""
        if labels == '':  # No labels
            return labels
        elif labels is None:  # Default labels
            return ['%2d%%' % val for val in values]
        else:
            assert len(labels) == len(values)
            return labels

    def put_labels(labels, positions, output=True):
        """Put labels to positions."""
        texts = []
        lbls = output and labels or labels[::-1]
        for i, label in enumerate(lbls):
            s, (x, y) = positions[i]  # Label direction and position
            if s == 0:
                t = ax.text(x + offset,
                            y,
                            label,
                            ha=output and 'left' or 'right',
                            va='center')
            elif s > 0:
                t = ax.text(x, y + offset, label, ha='center', va='bottom')
            else:
                t = ax.text(x, y - offset, label, ha='center', va='top')
            texts.append(t)
        return texts

    outlabels = set_labels(outlabels, outs)
    outtexts = put_labels(outlabels, outtips, output=True)

    inlabels = set_labels(inlabels, ins)
    intexts = put_labels(inlabels, indips, output=False)

    # Axes management
    ax.set_xlim(verts[:, 0].min() - dx, verts[:, 0].max() + dx)
    ax.set_ylim(verts[:, 1].min() - dy, verts[:, 1].max() + dy)
    ax.set_aspect('equal', adjustable='datalim')

    return patch, [intexts, outtexts]
Example #54
0
    verts = [
        (ymin, xmin),  # left, bottom
        (ymin, xmax),  # left, top
        (ymax, xmax),  # right, top
        (ymax, xmin),  # right, bottom
        (0., 0.),  # ignored
    ]

    codes = [
        Path.MOVETO,
        Path.LINETO,
        Path.LINETO,
        Path.LINETO,
        Path.CLOSEPOLY,
    ]
    path = Path(verts, codes)

    y0 = median(xx)
    x0 = median(yy)

    # rgb2 = rgb[:, :, 1]
    loop += 1
    sio.savemat('rgb' + str(loop) + '.mat', {'rgb': rgb})
    sio.savemat('depth' + str(loop) + '.mat', {'depth': depth})
    #
    ######################################################################
    ## Plotting depth image
    ######################################################################
    # fig = plt.figure(1)
    ax0 = fig.add_subplot(121)
    # ax0.image_depth.set_data(depth)
Example #55
0
def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
    """ divide a path into two segment at the point where inside(x, y)
    becomes False. 
    """

    path_iter = path.iter_segments()

    ctl_points, command = path_iter.next()
    begin_inside = inside(ctl_points[-2:])  # true if begin point is inside

    bezier_path = None
    ctl_points_old = ctl_points

    concat = np.concatenate

    iold = 0
    i = 1

    for ctl_points, command in path_iter:
        iold = i
        i += len(ctl_points) / 2
        if inside(ctl_points[-2:]) != begin_inside:
            bezier_path = concat([ctl_points_old[-2:], ctl_points])
            break

        ctl_points_old = ctl_points

    if bezier_path is None:
        raise ValueError("The path does not seem to intersect with the patch")

    bp = zip(bezier_path[::2], bezier_path[1::2])
    left, right = split_bezier_intersecting_with_closedpath(
        bp, inside, tolerence)
    if len(left) == 2:
        codes_left = [Path.LINETO]
        codes_right = [Path.MOVETO, Path.LINETO]
    elif len(left) == 3:
        codes_left = [Path.CURVE3, Path.CURVE3]
        codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
    elif len(left) == 4:
        codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
        codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
    else:
        raise ValueError()

    verts_left = left[1:]
    verts_right = right[:]

    #i += 1

    if path.codes is None:
        path_in = Path(concat([path.vertices[:i], verts_left]))
        path_out = Path(concat([verts_right, path.vertices[i:]]))

    else:
        path_in = Path(concat([path.vertices[:iold], verts_left]),
                       concat([path.codes[:iold], codes_left]))

        path_out = Path(concat([verts_right, path.vertices[i:]]),
                        concat([codes_right, path.codes[i:]]))

    if reorder_inout and begin_inside == False:
        path_in, path_out = path_out, path_in

    return path_in, path_out
Example #56
0
    def add(self,
            patchlabel='',
            flows=np.array([1.0, -1.0]),
            orientations=[0, 0],
            labels='',
            trunklength=1.0,
            pathlengths=0.25,
            prior=None,
            connect=(0, 0),
            rotation=0,
            **kwargs):
        """
        call signature::

          add(patchlabel='', flows=np.array([1.0,-1.0]), orientations=[0,0],
              labels='', trunklength=1.0, pathlengths=0.25, prior=None,
              connect=(0,0), rotation=0, **kwargs)

        Add a simple Sankey diagram with flows at the same hierarchical level.

        Return value is the instance of :class:`Sankey`.

        Optional keyword arguments:

          ===============   ==========================================
          Keyword           Description
          ===============   ==========================================
          *patchlabel*      label to be placed at the center of the diagram
                            Note: *label* (not *patchlabel*) will be passed to
                            the patch through **kwargs and can be used to create
                            an entry in the legend.
          *flows*           array of flow values
                            By convention, inputs are positive and outputs are
                            negative.
          *orientations*    list of orientations of the paths
                            Valid values are 1 (from/to the top), 0 (from/to the
                            left or right), or -1 (from/to the bottom).  If
                            *orientations* == 0, inputs will break in from the
                            left and outputs will break away to the right.
          *labels*          list of specifications of the labels for the flows
                            Each value may be None (no labels), '' (just label
                            the quantities), or a labeling string.  If a single
                            value is provided, it will be applied to all flows.
                            If an entry is a non-empty string, then the quantity
                            for the corresponding flow will be shown below the
                            string.  However, if the *unit* of the main diagram
                            is None, then quantities are never shown, regardless
                            of the value of this argument.
          *trunklength*     length between the bases of the input and output
                            groups
          *pathlengths*     list of lengths of the arrows before break-in or
                            after break-away
                            If a single value is given, then it will be applied
                            to the first (inside) paths on the top and bottom,
                            and the length of all other arrows will be justified
                            accordingly.  The *pathlengths* are not applied to
                            the horizontal inputs and outputs.
          *prior*           index of the prior diagram to which this diagram
                            should be connected
          *connect*         a (prior, this) tuple indexing the flow of the prior
                            diagram and the flow of this diagram which should be
                            connected
                            If this is the first diagram or *prior* is None,
                            *connect* will be ignored.
          *rotation*        angle of rotation of the diagram [deg]
                            *rotation* is ignored if this diagram is connected
                            to an existing one (using *prior* and *connect*).
                            The interpretation of the *orientations* argument
                            will be rotated accordingly (e.g., if *rotation*
                            == 90, an *orientations* entry of 1 means to/from
                            the left).
          ===============   ==========================================

        Valid kwargs are :meth:`~matplotlib.patches.PathPatch` arguments:
        %(PathPatch)s
        As examples, *fill*=False and *label*="A legend entry".  By default,
        *facecolor*='#bfd1d4' (light blue) and *lineweight*=0.5.

        The indexing parameters (*prior* and *connect*) are zero-based.

        The flows are placed along the top of the diagram from the inside out in
        order of their index within the *flows* list or array.  They are placed
        along the sides of the diagram from the top down and along the bottom
        from the outside in.

        If the the sum of the inputs and outputs is nonzero, the discrepancy
        will appear as a cubic Bezier curve along the top and bottom edges of
        the trunk.

        .. seealso::

            :meth:`finish`
        """
        # Check and preprocess the arguments.
        flows = np.array(flows)
        n = flows.shape[0]  # Number of flows
        if rotation == None:
            rotation = 0
        else:
            rotation /= 90.0  # In the code below, angles are expressed in deg/90
        assert len(orientations) == n, (
            "orientations and flows must have the "
            "same length.\norientations has length "
            "%d, but flows has length %d." % len(orientations), n)
        if getattr(labels, '__iter__', False):
            # iterable() isn't used because it would give True if labels is a string
            assert len(labels) == n, ("If labels is a list, then labels and "
                                      "flows must have the same length.\n"
                                      "labels has length %d, but flows has "
                                      "length %d." % len(labels), n)
        else:
            labels = [labels] * n
        assert trunklength >= 0, ("trunklength is negative.\nThis isn't "
                                  "allowed, because it would cause poor "
                                  "layout.")
        if np.absolute(np.sum(flows)) > self.tolerance:
            verbose.report(
                "The sum of the flows is nonzero (%f).\nIs the "
                "system not at steady state?" % np.sum(flows), 'helpful')
        scaled_flows = self.scale * flows
        gain = sum(max(flow, 0) for flow in scaled_flows)
        loss = sum(min(flow, 0) for flow in scaled_flows)
        if not (0.5 <= gain <= 2.0):
            verbose.report(
                "The scaled sum of the inputs is %f.\nThis may "
                "cause poor layout.\nConsider changing the scale so "
                "that the scaled sum is approximately 1.0." % gain, 'helpful')
        if not (-2.0 <= loss <= -0.5):
            verbose.report(
                "The scaled sum of the outputs is %f.\nThis may "
                "cause poor layout.\nConsider changing the scale so "
                "that the scaled sum is approximately 1.0." % gain, 'helpful')
        if prior is not None:
            assert prior >= 0, "The index of the prior diagram is negative."
            assert min(connect) >= 0, (
                "At least one of the connection indices "
                "is negative.")
            assert prior < len(self.diagrams), ("The index of the prior "
                                                "diagram is %d, but there are "
                                                "only %d other diagrams.\nThe "
                                                "index is zero-based." % prior,
                                                len(self.diagrams))
            assert connect[0] < len(self.diagrams[prior].flows), \
                   ("The connection index to the source diagram is %d, but "
                    "that diagram has only %d flows.\nThe index is zero-based."
                    % connect[0], len(self.diagrams[prior].flows))
            assert connect[1] < n, ("The connection index to this diagram is "
                                    "%d, but this diagram has only %d flows.\n"
                                    "The index is zero-based." % connect[1], n)
            assert self.diagrams[prior].angles[connect[0]] is not None, \
                   ("The connection cannot be made.  Check that the magnitude "
                    "of flow %d of diagram %d is greater than or equal to the "
                    "specified tolerance." % connect[0], prior)
            flow_error = self.diagrams[prior].flows[connect[0]] \
                         + flows[connect[1]]
            assert abs(flow_error) < self.tolerance, \
                  ("The scaled sum of the connected flows is %f, which is not "
                   "within the tolerance (%f)." % flow_error, self.tolerance)

        # Determine if the flows are inputs.
        are_inputs = [None] * n
        for i, flow in enumerate(flows):
            if flow >= self.tolerance:
                are_inputs[i] = True
            elif flow <= -self.tolerance:
                are_inputs[i] = False
            else:
                verbose.report(
                    "The magnitude of flow %d (%f) is below the "
                    "tolerance (%f).\nIt will not be shown, and it "
                    "cannot be used in a connection." %
                    (i, flow, self.tolerance), 'helpful')

        # Determine the angles of the arrows (before rotation).
        angles = [None] * n
        for i, (orient, is_input) in enumerate(zip(orientations, are_inputs)):
            if orient == 1:
                if is_input:
                    angles[i] = DOWN
                elif is_input == False:  # Be specific since is_input can be None.
                    angles[i] = UP
            elif orient == 0:
                if is_input is not None:
                    angles[i] = RIGHT
            else:
                assert orient == -1, ("The value of orientations[%d] is %d, "
                                      "but it must be -1, 0, or 1." % i,
                                      orient)
                if is_input:
                    angles[i] = UP
                elif is_input == False:
                    angles[i] = DOWN

        # Justify the lengths of the paths.
        if iterable(pathlengths):
            assert len(pathlengths) == n, (
                "If pathlengths is a list, then "
                "pathlengths and flows must have "
                "the same length.\npathlengths has "
                "length %d, but flows has length %d." % len(pathlengths), n)
        else:  # Make pathlengths into a list.
            urlength = pathlengths
            ullength = pathlengths
            lrlength = pathlengths
            lllength = pathlengths
            d = dict(RIGHT=pathlengths)
            pathlengths = [d.get(angle, 0) for angle in angles]
            # Determine the lengths of the top-side arrows
            # from the middle outwards.
            for i, (angle, is_input, flow) \
                in enumerate(zip(angles, are_inputs, scaled_flows)):
                if angle == DOWN and is_input:
                    pathlengths[i] = ullength
                    ullength += flow
                elif angle == UP and not is_input:
                    pathlengths[i] = urlength
                    urlength -= flow  # Flow is negative for outputs.
            # Determine the lengths of the bottom-side arrows
            # from the middle outwards.
            for i, (angle, is_input, flow) \
                in enumerate(zip(angles, are_inputs, scaled_flows)[::-1]):
                if angle == UP and is_input:
                    pathlengths[n - i - 1] = lllength
                    lllength += flow
                elif angle == DOWN and not is_input:
                    pathlengths[n - i - 1] = lrlength
                    lrlength -= flow
            # Determine the lengths of the left-side arrows
            # from the bottom upwards.
            has_left_input = False
            for i, (angle, is_input, spec) \
                in enumerate(zip(angles, are_inputs, zip(scaled_flows,
                                                         pathlengths))[::-1]):
                if angle == RIGHT:
                    if is_input:
                        if has_left_input:
                            pathlengths[n - i - 1] = 0
                        else:
                            has_left_input = True
            # Determine the lengths of the right-side arrows
            # from the top downwards.
            has_right_output = False
            for i, (angle, is_input, spec) \
                in enumerate(zip(angles, are_inputs, zip(scaled_flows,
                                                         pathlengths))):
                if angle == RIGHT:
                    if not is_input:
                        if has_right_output:
                            pathlengths[i] = 0
                        else:
                            has_right_output = True

        # Begin the subpaths, and smooth the transition if the sum of the flows
        # is nonzero.
        urpath = [
            (
                Path.MOVETO,
                [
                    (self.gap - trunklength / 2.0),  # Upper right
                    gain / 2.0
                ]),
            (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, gain / 2.0]),
            (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, gain / 2.0]),
            (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, -loss / 2.0]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, -loss / 2.0]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap), -loss / 2.0])
        ]
        llpath = [
            (
                Path.LINETO,
                [
                    (trunklength / 2.0 - self.gap),  # Lower left
                    loss / 2.0
                ]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, loss / 2.0]),
            (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, loss / 2.0]),
            (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, -gain / 2.0]),
            (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, -gain / 2.0]),
            (Path.LINETO, [(self.gap - trunklength / 2.0), -gain / 2.0])
        ]
        lrpath = [(
            Path.LINETO,
            [
                (trunklength / 2.0 - self.gap),  # Lower right
                loss / 2.0
            ])]
        ulpath = [(
            Path.LINETO,
            [
                self.gap - trunklength / 2.0,  # Upper left
                gain / 2.0
            ])]

        # Add the subpaths and assign the locations of the tips and labels.
        tips = np.zeros((n, 2))
        label_locations = np.zeros((n, 2))
        # Add the top-side inputs and outputs from the middle outwards.
        for i, (angle, is_input, spec) \
            in enumerate(zip(angles, are_inputs,
                             zip(scaled_flows, pathlengths))):
            if angle == DOWN and is_input:
                tips[i, :], label_locations[i, :] = self._add_input(
                    ulpath, angle, *spec)
            elif angle == UP and not is_input:
                tips[i, :], label_locations[i, :] = self._add_output(
                    urpath, angle, *spec)
        # Add the bottom-side inputs and outputs from the middle outwards.
        for i, (angle, is_input, spec) \
            in enumerate(zip(angles, are_inputs,
                             zip(scaled_flows, pathlengths))[::-1]):
            if angle == UP and is_input:
                (tips[n - i - 1, :],
                 label_locations[n - i - 1, :]) = self._add_input(
                     llpath, angle, *spec)
            elif angle == DOWN and not is_input:
                (tips[n - i - 1, :],
                 label_locations[n - i - 1, :]) = self._add_output(
                     lrpath, angle, *spec)
        # Add the left-side inputs from the bottom upwards.
        has_left_input = False
        for i, (angle, is_input, spec) \
            in enumerate(zip(angles, are_inputs,
                             zip(scaled_flows, pathlengths))[::-1]):
            if angle == RIGHT and is_input:
                if not has_left_input:
                    # Make sure the lower path extends
                    # at least as far as the upper one.
                    if llpath[-1][1][0] > ulpath[-1][1][0]:
                        llpath.append(
                            (Path.LINETO, [ulpath[-1][1][0],
                                           llpath[-1][1][1]]))
                    has_left_input = True
                (tips[n - i - 1, :],
                 label_locations[n - i - 1, :]) = self._add_input(
                     llpath, angle, *spec)
        # Add the right-side outputs from the top downwards.
        has_right_output = False
        for i, (angle, is_input, spec) \
            in enumerate(zip(angles, are_inputs,
                             zip(scaled_flows, pathlengths))):
            if angle == RIGHT and not is_input:
                if not has_right_output:
                    # Make sure the upper path extends
                    # at least as far as the lower one.
                    if urpath[-1][1][0] < lrpath[-1][1][0]:
                        urpath.append(
                            (Path.LINETO, [lrpath[-1][1][0],
                                           urpath[-1][1][1]]))
                    has_right_output = True
                (tips[i, :], label_locations[i, :]) = self._add_output(
                    urpath, angle, *spec)
        # Trim any hanging vertices.
        if not has_left_input:
            ulpath.pop()
            llpath.pop()
        if not has_right_output:
            lrpath.pop()
            urpath.pop()

        # Concatenate the subpaths in the correct order (clockwise from top).
        path = (urpath + self._revert(lrpath) + llpath + self._revert(ulpath) +
                [(Path.CLOSEPOLY, urpath[0][1])])

        # Create a patch with the Sankey outline.
        codes, vertices = zip(*path)
        vertices = np.array(vertices)

        def _get_angle(a, r):
            if a is None: return None
            else: return a + r

        if prior is None:
            if rotation != 0:  # By default, none of this is needed.
                angles = [_get_angle(angle, rotation) for angle in angles]
                rotate = Affine2D().rotate_deg(rotation * 90).transform_point
                tips = rotate(tips)
                label_locations = rotate(label_locations)
                vertices = rotate(vertices)
            text = self.ax.text(0, 0, s=patchlabel, ha='center', va='center')
        else:
            rotation = (self.diagrams[prior].angles[connect[0]] -
                        angles[connect[1]])
            angles = [_get_angle(angle, rotation) for angle in angles]
            rotate = Affine2D().rotate_deg(rotation * 90).transform_point
            tips = rotate(tips)
            offset = self.diagrams[prior].tips[connect[0]] - tips[connect[1]]
            translate = Affine2D().translate(*offset).transform_point
            tips = translate(tips)
            label_locations = translate(rotate(label_locations))
            vertices = translate(rotate(vertices))
            kwds = dict(s=patchlabel, ha='center', va='center')
            text = self.ax.text(*offset, **kwds)
        if False:  # Debug
            print "llpath\n", llpath
            print "ulpath\n", self._revert(ulpath)
            print "urpath\n", urpath
            print "lrpath\n", self._revert(lrpath)
            xs, ys = zip(*vertices)
            self.ax.plot(xs, ys, 'go-')
        patch = PathPatch(
            Path(vertices, codes),
            fc=kwargs.pop('fc', kwargs.pop('facecolor',
                                           '#bfd1d4')),  # Custom defaults
            lw=kwargs.pop('lw', kwargs.pop('linewidth', '0.5')),
            **kwargs)
        self.ax.add_patch(patch)

        # Add the path labels.
        for i, (number, angle) in enumerate(zip(flows, angles)):
            if labels[i] is None or angle is None:
                labels[i] = ''
            elif self.unit is not None:
                quantity = self.format % abs(number) + self.unit
                if labels[i] != '':
                    labels[i] += "\n"
                labels[i] += quantity
        texts = []
        for i, (label, location) in enumerate(zip(labels, label_locations)):
            if label: s = label
            else: s = ''
            texts.append(
                self.ax.text(x=location[0],
                             y=location[1],
                             s=s,
                             ha='center',
                             va='center'))
        # Text objects are placed even they are empty (as long as the magnitude
        # of the corresponding flow is larger than the tolerance) in case the
        # user wants to provide labels later.

        # Expand the size of the diagram if necessary.
        self.extent = (min(np.min(vertices[:, 0]),
                           np.min(label_locations[:, 0]), self.extent[0]),
                       max(np.max(vertices[:, 0]),
                           np.max(label_locations[:, 0]), self.extent[1]),
                       min(np.min(vertices[:, 1]),
                           np.min(label_locations[:, 1]), self.extent[2]),
                       max(np.max(vertices[:, 1]),
                           np.max(label_locations[:, 1]), self.extent[3]))
        # Include both vertices _and_ label locations in the extents; there are
        # where either could determine the margins (e.g., arrow shoulders).

        # Add this diagram as a subdiagram.
        self.diagrams.append(
            Bunch(patch=patch,
                  flows=flows,
                  angles=angles,
                  tips=tips,
                  text=text,
                  texts=texts))

        # Allow a daisy-chained call structure (see docstring for the class).
        return self
Example #57
0
def plot(
    trj: TrajaDataFrame,
    n_coords: Optional[int] = None,
    show_time: bool = False,
    accessor: Optional[traja.TrajaAccessor] = None,
    ax=None,
    **kwargs,
) -> matplotlib.collections.PathCollection:
    """Plot trajectory for single animal over period.

    Args:
      trj (:class:`traja.TrajaDataFrame`): trajectory
      n_coords (int, optional): Number of coordinates to plot
      show_time (bool): Show colormap as time
      accessor (:class:`~traja.accessor.TrajaAccessor`, optional): TrajaAccessor instance
      ax (:class:`~matplotlib.axes.Axes`): axes for plotting
      interactive (bool): show plot immediately
      **kwargs: additional keyword arguments to :meth:`matplotlib.axes.Axes.scatter`

    Returns:
        collection (:class:`~matplotlib.collections.PathCollection`): collection that was plotted

    """
    import matplotlib.patches as patches
    from matplotlib.path import Path

    after_plot_args, kwargs = _get_after_plot_args(**kwargs)

    GRAY = "#999999"

    xlim = kwargs.pop("xlim", None)
    ylim = kwargs.pop("ylim", None)
    if not xlim or not ylim:
        xlim, ylim = traja.trajectory._get_xylim(trj)

    title = kwargs.pop("title", None)
    time_units = kwargs.pop("time_units", "s")
    fps = kwargs.pop("fps", None)
    figsize = kwargs.pop("figsize", None)

    coords = trj[["x", "y"]]
    time_col = traja.trajectory._get_time_col(trj)

    if time_col == "index":
        is_datetime = True
    else:
        is_datetime = is_datetime64_any_dtype(
            trj[time_col]) if time_col else False

    if n_coords is None:
        # Plot all coords
        start, end = 0, len(coords)
        verts = coords.iloc[start:end].values
    else:
        # Plot first `n_coords`
        verts = coords.iloc[:n_coords].values

    n_coords = len(verts)

    codes = [Path.MOVETO] + [Path.LINETO] * (len(verts) - 1)
    path = Path(verts, codes)

    if not ax:
        fig, ax = plt.subplots(figsize=figsize)
        fig.canvas.draw()

    patch = patches.PathPatch(path,
                              edgecolor=GRAY,
                              facecolor="none",
                              lw=3,
                              alpha=0.3)
    ax.add_patch(patch)

    xs, ys = zip(*verts)

    if time_col == "index":
        # DatetimeIndex determines color
        colors = [ind for ind, x in enumerate(trj.index[:n_coords])]
    elif time_col and time_col != "index":
        # `time_col` determines color
        colors = [ind for ind, x in enumerate(trj[time_col].iloc[:n_coords])]
    else:
        # Frame count determines color
        colors = trj.index[:n_coords]

    if time_col:
        # TODO: Calculate fps if not in datetime
        vmin = min(colors)
        vmax = max(colors)
        if is_datetime:
            # Show timestamps without units
            time_units = ""
    else:
        # Index/frame count is our only reference
        vmin = trj.index[0]
        vmax = trj.index[n_coords - 1]
        if not show_time:
            time_units = ""
    label = f"Time ({time_units})" if time_units else ""

    collection = ax.scatter(
        xs,
        ys,
        c=colors,
        s=kwargs.pop("s", 1),
        cmap=plt.cm.viridis,
        alpha=0.7,
        vmin=vmin,
        vmax=vmax,
        **kwargs,
    )

    ax.set_xlim(xlim)
    ax.set_ylim(ylim)

    if kwargs.pop("invert_yaxis", None):
        plt.gca().invert_yaxis()

    _label_axes(trj, ax)
    ax.set_title(title)
    ax.set_aspect("equal")

    # Number of color bar ticks
    CBAR_TICKS = 10 if n_coords > 20 else n_coords
    indices = np.linspace(0,
                          n_coords - 1,
                          CBAR_TICKS,
                          endpoint=True,
                          dtype=int)
    cbar = plt.colorbar(collection,
                        fraction=0.046,
                        pad=0.04,
                        orientation="vertical",
                        label=label)

    # Get colorbar labels from time
    if time_col == "index":
        if is_datetime64_any_dtype(trj.index):
            cbar_labels = (trj.index[indices].strftime(
                "%Y-%m-%d %H:%M:%S").values.astype(str))
        elif is_timedelta64_dtype(trj.index):
            if time_units in ("s", "", None):
                cbar_labels = [
                    round(x, 2) for x in trj.index[indices].total_seconds()
                ]
            else:
                logger.error(
                    "Time unit {} not yet implemented".format(time_units))
        else:
            raise NotImplementedError(
                "Indexing on {} is not yet implemented".format(type(
                    trj.index)))
    elif time_col and is_timedelta64_dtype(trj[time_col]):
        cbar_labels = trj[time_col].iloc[indices].dt.total_seconds().values
        cbar_labels = ["%.2f" % number for number in cbar_labels]
    elif time_col and is_datetime:
        cbar_labels = (trj[time_col].iloc[indices].dt.strftime(
            "%Y-%m-%d %H:%M:%S").values.astype(str))
    else:
        # Convert frames to time
        if time_col:
            cbar_labels = trj[time_col][indices].values
        else:
            cbar_labels = trj.index[indices].values
        cbar_labels = np.round(cbar_labels, 6)
        if fps is not None and fps > 0 and fps is not 1 and show_time:
            cbar_labels = cbar_labels / fps

    cbar.set_ticks(indices)
    cbar.set_ticklabels(cbar_labels)
    plt.tight_layout()

    _process_after_plot_args(**after_plot_args)
    return collection
 def transform_path_non_affine(self, path):
     vertices = path.vertices
     ipath = path.interpolated(self._resolution)
     return Path(self.transform(ipath.vertices), ipath.codes)
Example #59
0
def draw_labels(fig,
                ax,
                out_value,
                features,
                feature_type,
                offset_text,
                total_effect=0,
                min_perc=0.05):
    start_text = out_value
    pre_val = out_value

    # Define variables specific to positive and negative effect features
    if feature_type == 'positive':
        colors = ['#FF0D57', '#FFC3D5']
        alignement = 'right'
        sign = 1
    else:
        colors = ['#1E88E5', '#D1E6FA']
        alignement = 'left'
        sign = -1

    # Draw initial line
    if feature_type == 'positive':
        x, y = np.array([[pre_val, pre_val], [0, -0.18]])
        line = lines.Line2D(x, y, lw=1., alpha=0.5, color=colors[0])
        line.set_clip_on(False)
        ax.add_line(line)
        start_text = pre_val

    box_end = out_value
    val = out_value
    for feature in features:
        # Exclude all labels that do not contribute at least 10% to the total
        feature_contribution = np.abs(float(feature[0]) -
                                      pre_val) / np.abs(total_effect)
        if feature_contribution < min_perc:
            break

        # Compute value for current feature
        val = float(feature[0])

        # Draw labels.
        if feature[1] == "":
            text = feature[2]
        else:
            text = feature[2] + ' = ' + feature[1]
        text_out_val = plt.text(start_text - sign * offset_text,
                                -0.15,
                                text,
                                fontsize=12,
                                color=colors[0],
                                horizontalalignment=alignement)
        text_out_val.set_bbox(dict(facecolor='none', edgecolor='none'))

        # We need to draw the plot to be able to get the size of the
        # text box
        fig.canvas.draw()
        box_size = text_out_val.get_bbox_patch().get_extents()\
                               .transformed(ax.transData.inverted())
        if feature_type == 'positive':
            box_end_ = box_size.get_points()[0][0]
        else:
            box_end_ = box_size.get_points()[1][0]

        # If the feature goes over the side of the plot, we remove that label
        # and stop drawing labels
        if box_end_ > ax.get_xlim()[1]:
            text_out_val.remove()
            break

        # Create end line
        if (sign * box_end_) > (sign * val):
            x, y = np.array([[val, val], [0, -0.18]])
            line = lines.Line2D(x, y, lw=1., alpha=0.5, color=colors[0])
            line.set_clip_on(False)
            ax.add_line(line)
            start_text = val
            box_end = val

        else:
            box_end = box_end_ - sign * offset_text
            x, y = np.array([[val, box_end, box_end], [0, -0.08, -0.18]])
            line = lines.Line2D(x, y, lw=1., alpha=0.5, color=colors[0])
            line.set_clip_on(False)
            ax.add_line(line)
            start_text = box_end

        # Update previous value
        pre_val = float(feature[0])

    # Create line for labels
    extent_shading = [out_value, box_end, 0, -0.31]
    path = [[out_value, 0], [pre_val, 0], [box_end, -0.08], [box_end, -0.2],
            [out_value, -0.2], [out_value, 0]]

    path = Path(path)
    patch = PathPatch(path, facecolor='none', edgecolor='none')
    ax.add_patch(patch)

    # Extend axis if needed
    lower_lim, upper_lim = ax.get_xlim()
    if (box_end < lower_lim):
        ax.set_xlim(box_end, upper_lim)

    if (box_end > upper_lim):
        ax.set_xlim(lower_lim, box_end)

    # Create shading
    if feature_type == 'positive':
        colors = np.array([(255, 13, 87), (255, 255, 255)]) / 255.
    else:
        colors = np.array([(30, 136, 229), (255, 255, 255)]) / 255.

    cm = matplotlib.colors.LinearSegmentedColormap.from_list('cm', colors)

    Z, Z2 = np.meshgrid(np.linspace(0, 10), np.linspace(-10, 10))
    im = plt.imshow(Z2,
                    interpolation='quadric',
                    cmap=cm,
                    vmax=0.01,
                    alpha=0.3,
                    origin='lower',
                    extent=extent_shading,
                    clip_path=patch,
                    clip_on=True,
                    aspect='auto')
    im.set_clip_path(patch)

    return fig, ax
Example #60
0
def pressure_design(
        capsule_material='copper',
        pressure_medium_material='BaCO$_3$',
        sleeve_material='pyrophyllite',
        buffer_material='H$_2$O, Ni,\nNiO, SC ol.,\nSC enst.',
        lid_shape='bevel',  # or flat or suaged
        h_graphite_button=1.5,
        h_pressure_medium=33.35,
        h_graphite_cylinder=33.35,
        h_sleeve=11.5,
        h_sleeve_bottom=1.,
        h_capsule=9.7,
        h_lid=1.,  # total 
        h_MgO_base=10.6,
        h_MgO_wafer=1.5,
        h_MgO_top=10.6,
        od_pressure_medium=18.9,
        od_graphite_cylinder=11.5,
        id_graphite_cylinder=10.0,
        id_sleeve=8.7,
        id_capsule=6.7,
        legend_on=True,
        figsize=(3., 3),
):
    """Creates and returns figure and axis
    showing experimental setup for a high pressure 
    experiment used to hydrate olivine and potentially
    other nominally anhydrous minerals in the green 4-post piston cylinder 
    at Lamont. All dimensions are input in mm. h=height, d=diameter,
    od=outer diameter, id=inner diameter
    """
    # reset all style labels to None for legend
    style_capsule['color'] = None
    style_buffer['label'] = buffer_material
    for style in [style_graphite, style_MgO, style_capsule]:
        style['label'] = None

    d_graphite_button = od_pressure_medium
    od_MgO_base = id_graphite_cylinder
    od_sleeve = id_graphite_cylinder

    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111)
    ax.set_xlim(0, od_pressure_medium)
    ax.set_xlabel('(mm)')
    ax.set_ylabel('(mm)')
    h_guts = h_MgO_base + h_sleeve + h_MgO_wafer + h_MgO_top
    highest_point = max(h_pressure_medium, h_graphite_cylinder, h_guts)
    ax.set_ylim(0., h_graphite_button + highest_point + 2.)
    plt.tick_params(axis='x', top='off')
    ax.spines['top'].set_visible(False)
    ax.spines['left'].set_visible(False)
    ax.spines['right'].set_visible(False)

    th_gc = (od_graphite_cylinder - id_graphite_cylinder) / 2.
    xgc = (od_pressure_medium - od_graphite_cylinder) / 2.

    style_pressure_medium['label'] = pressure_medium_material
    pressure_medium = patches.Rectangle(
        (0., h_graphite_button),  # (x,y)
        od_pressure_medium,  # width
        h_pressure_medium,  # height
        **style_pressure_medium)

    graphite_button = patches.Rectangle((0., 0.), d_graphite_button,
                                        h_graphite_button, **style_graphite)

    style_graphite['label'] = 'graphite'
    graphite_cylinder = patches.Rectangle(
        (xgc, h_graphite_button), od_graphite_cylinder, h_graphite_cylinder,
        **style_graphite)

    the_guts = patches.Rectangle((xgc + th_gc, h_graphite_button),
                                 id_graphite_cylinder,
                                 h_graphite_cylinder,
                                 facecolor='w')

    MgO_base = patches.Rectangle((xgc + th_gc, h_graphite_button), od_MgO_base,
                                 h_MgO_base, **style_MgO)

    def make_capsule_shape(x, y, height, outerD, innerD, shape='regular'):
        thick = (outerD - innerD) / 2.
        if shape == 'regular':
            verts = [(x + thick * 2 + innerD, y), (x, y), (x, y + height),
                     (x + thick, y + height), (x + thick, y + innerD / 2.),
                     (x + thick + innerD / 2., y + thick),
                     (x + thick + innerD, y + innerD / 2.),
                     (x + thick + innerD, y + height),
                     (x + thick * 2 + innerD, y + height), (0., 0.)]
            codes = [Path.MOVETO] + ([Path.LINETO] * 8) + [Path.CLOSEPOLY]
        elif shape == 'suaged':
            th_flap = thick / 2.
            verts = [(x + thick * 2 + innerD, y), (x, y),
                     (x, y + height + th_flap),
                     (x + thick + innerD / 2., y + height + th_flap),
                     (x + thick + innerD / 2., y + height),
                     (x + thick, y + height), (x + thick, y + thick),
                     (x + thick + innerD, y + thick),
                     (x + thick + innerD, y + height),
                     (x + thick + innerD / 2., y + height),
                     (x + thick + innerD / 2., y + height + th_flap),
                     (x + thick * 2 + innerD, y + height + th_flap),
                     (x + thick * 2 + innerD, y + height - th_flap), (0., 0.)]
            codes = [Path.MOVETO] + ([Path.LINETO] *
                                     (len(verts) - 2)) + [Path.CLOSEPOLY]
        path = Path(verts, codes)
        return path

    # sleeve around capsule
    sleeve_path = make_capsule_shape(x=xgc + th_gc,
                                     y=h_graphite_button + h_MgO_base,
                                     height=h_sleeve,
                                     outerD=od_sleeve,
                                     innerD=id_sleeve)
    if sleeve_material == 'MgO':
        style_sleeve = style_MgO.copy()
    elif sleeve_material == 'pyrophyllite':
        style_sleeve = style_pyrophyllite.copy()
        style_sleeve['label'] = 'pyrophyllite'
    else:
        print 'unknown sleeve material. Assuming pyrophyllite'
        style_sleeve = style_pyrophyllite.copy()
        style_sleeve['label'] = 'pyrophyllite'

    sleeve = patches.PathPatch(sleeve_path, **style_sleeve)

    # capsule
    th_sleeve = (od_sleeve - id_sleeve) / 2.
    if (lid_shape == 'bevel') or (lid_shape == 'flat'):
        capsule_path = make_capsule_shape(x=xgc + th_gc + th_sleeve,
                                          y=h_graphite_button + h_MgO_base +
                                          h_sleeve_bottom,
                                          height=h_capsule,
                                          outerD=id_sleeve,
                                          innerD=id_capsule)
    elif lid_shape == 'suaged':
        capsule_path = make_capsule_shape(x=xgc + th_gc + th_sleeve,
                                          y=h_graphite_button + h_MgO_base +
                                          h_sleeve_bottom,
                                          height=h_capsule,
                                          outerD=id_sleeve,
                                          innerD=id_capsule,
                                          shape='suaged')
    else:
        print 'valid entries for lid_shape are flat, bevel, and suaged'
        capsule_path = make_capsule_shape(x=xgc + th_gc + th_sleeve,
                                          y=h_graphite_button + h_MgO_base +
                                          h_sleeve_bottom,
                                          height=h_capsule,
                                          outerD=id_sleeve,
                                          innerD=id_capsule)

    if capsule_material == 'copper':
        style_capsule['label'] = 'copper'
        style_capsule['facecolor'] = 'orange'
    elif capsule_material == 'silver':
        style_capsule['label'] = 'silver'
        style_capsule['facecolor'] = 'silver'
    elif capsule_material == 'gold':
        style_capsule['label'] = 'gold'
        style_capsule['facecolor'] = 'gold'
    elif capsule_material == 'platinum':
        style_capsule['label'] = 'platinum'
        style_capsule['facecolor'] = 'lightblue'
    elif capsule_material == 'nickel':
        style_capsule['label'] = 'nickel'
        style_capsule['facecolor'] = 'lightsage'
    else:
        print 'unknown capsule material'
        style_capsule['label'] = 'capsule'
    capsule = patches.PathPatch(capsule_path, **style_capsule)

    # MgO on top
    MgO_wafer = patches.Rectangle(
        (xgc + th_gc, h_graphite_button + h_MgO_base + h_sleeve), od_MgO_base,
        h_MgO_wafer, **style_MgO)

    style_MgO['label'] = 'MgO'
    MgO_top = patches.Rectangle(
        (xgc + th_gc, h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer),
        od_MgO_base, h_MgO_top, **style_MgO)

    thermocouple = patches.Rectangle(
        (od_pressure_medium / 2. - 0.5,
         h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer),
        1.,
        h_MgO_top,
        facecolor='w')
    ax.plot([od_pressure_medium / 2 - 0.15, od_pressure_medium / 2. - 0.15], [
        h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer + h_MgO_top +
        2., h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer
    ],
            color='r',
            linewidth=1)
    ax.plot([od_pressure_medium / 2 + 0.15, od_pressure_medium / 2. + 0.15], [
        h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer + h_MgO_top +
        2., h_graphite_button + h_MgO_base + h_sleeve + h_MgO_wafer
    ],
            color='b',
            linewidth=1)

    # buffer
    th_capsule = (id_sleeve - id_capsule) / 2.
    buffer_inside = patches.Rectangle(
        (xgc + th_gc + th_sleeve + th_capsule,
         h_graphite_button + h_MgO_base + h_sleeve_bottom + th_capsule),
        id_capsule, h_capsule - th_capsule, **style_buffer)

    # capsule lid
    del style_capsule['label']  # so it doesn't appear twice in the legend
    if lid_shape == 'flat':
        lid = patches.Rectangle(
            (xgc + th_gc + th_sleeve,
             h_graphite_button + h_MgO_base + h_sleeve_bottom + h_capsule),
            id_sleeve, h_lid, **style_capsule)
    elif lid_shape == 'bevel':
        x = xgc + th_gc + th_sleeve
        y = h_graphite_button + h_MgO_base + h_sleeve_bottom + h_capsule
        th_lid = h_lid / 2.
        th_capsule = (id_sleeve - id_capsule) / 2.
        lid_verts = [(x + th_capsule, y), (x, y), (x, y + th_lid),
                     (x + id_sleeve, y + th_lid), (x + id_sleeve, y),
                     (x + id_sleeve - th_capsule, y),
                     (x + id_sleeve - th_capsule, y - th_lid),
                     (x + th_capsule, y - th_lid), (0., 0.)]
        lid_codes = [Path.MOVETO] + ([Path.LINETO] * 7) + [Path.CLOSEPOLY]
        lid_path = Path(lid_verts, lid_codes)
        lid = patches.PathPatch(lid_path, **style_capsule)
    elif lid_shape == 'suaged':
        th_flap = th_capsule / 2.
        x = xgc + th_gc + th_sleeve + th_flap
        ystart = h_graphite_button + h_MgO_base + h_sleeve_bottom
        y = ystart + h_capsule - th_flap * 2
        th_lid = h_lid / 2.
        th_capsule = (id_sleeve - id_capsule) / 2.
        lid_verts = [(x + th_capsule - th_flap, y), (x, y), (x, y + th_lid),
                     (x + id_sleeve - th_capsule, y + th_lid),
                     (x + id_sleeve - th_capsule, y),
                     (x + id_sleeve - th_capsule - th_flap, y),
                     (x + id_sleeve - th_capsule - th_flap, y - th_lid),
                     (x + th_capsule - th_flap, y - th_lid), (0., 0.)]
        lid_codes = [Path.MOVETO] + ([Path.LINETO] * 7) + [Path.CLOSEPOLY]
        lid_path = Path(lid_verts, lid_codes)
        lid = patches.PathPatch(lid_path, **style_capsule)
    else:
        print 'valid entries for lid_shape are flat, bevel, and suaged'
        lid = patches.Rectangle(
            (xgc + th_gc + th_sleeve,
             h_graphite_button + h_MgO_base + th_sleeve + h_capsule),
            id_sleeve, h_lid, **style_capsule)

    ax.add_patch(pressure_medium)
    ax.add_patch(graphite_button)
    ax.add_patch(graphite_cylinder)
    ax.add_patch(the_guts)
    ax.add_patch(MgO_base)
    ax.add_patch(sleeve)
    ax.add_patch(buffer_inside)
    ax.add_patch(MgO_wafer)
    ax.add_patch(MgO_top)
    ax.add_patch(thermocouple)
    ax.add_patch(capsule)
    ax.add_patch(lid)

    fig.tight_layout()
    if legend_on is True:
        plt.subplots_adjust(right=0.55, left=0.17, bottom=0.15, top=0.9)
        ax.legend(bbox_to_anchor=(2.25, 0.8), frameon=False)
    else:
        plt.subplots_adjust(right=0.9, left=0.17, bottom=0.15, top=0.9)
    return fig, ax