Python matplotlib.path.Path.LINETO() Examples

The following are code examples for showing how to use matplotlib.path.Path.LINETO(). They are from open source Python projects. You can vote up the examples you like or vote down the ones you don't like.

Example 1
Project: 3d-vehicle-tracking   Author: ucbdrive   File: show_labels.py    BSD 3-Clause "New" or "Revised" License 9 votes vote down vote up
def poly2patch(self, poly2d, closed=False, alpha=1., color=None):
        moves = {'L': Path.LINETO,
                 'C': Path.CURVE4}
        points = [p[:2] for p in poly2d]
        codes = [moves[p[2]] for p in poly2d]
        codes[0] = Path.MOVETO

        if closed:
            points.append(points[0])
            codes.append(Path.CLOSEPOLY)

        if color is None:
            color = random_color()

        # print(codes, points)
        return mpatches.PathPatch(
            Path(points, codes),
            facecolor=color if closed else 'none',
            edgecolor=color,  # if not closed else 'none',
            lw=1 if closed else 2 * self.scale, alpha=alpha,
            antialiased=False, snap=True) 
Example 2
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 6 votes vote down vote up
def _get_bracket(self, x0, y0,
                         cos_t, sin_t, width, length):

            # arrow from x0, y0 to x1, y1
            from matplotlib.bezier import get_normal_points
            x1, y1, x2, y2 = get_normal_points(x0, y0, cos_t, sin_t, width)

            dx, dy = length * cos_t, length * sin_t

            vertices_arrow = [(x1 + dx, y1 + dy),
                              (x1, y1),
                              (x2, y2),
                              (x2 + dx, y2 + dy)]
            codes_arrow = [Path.MOVETO,
                           Path.LINETO,
                           Path.LINETO,
                           Path.LINETO]

            return vertices_arrow, codes_arrow 
Example 3
Project: LaserTOF   Author: kyleuckert   File: table.py    MIT License 6 votes vote down vote up
def get_path(self):
        'Return a path where the edges specificed by _visible_edges are drawn'

        codes = [Path.MOVETO]

        for edge in self._edges:
            if edge in self._visible_edges:
                codes.append(Path.LINETO)
            else:
                codes.append(Path.MOVETO)

        if Path.MOVETO not in codes[1:]:  # All sides are visible
            codes[-1] = Path.CLOSEPOLY

        return Path(
            [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]],
            codes,
            readonly=True
            ) 
Example 4
Project: LaserTOF   Author: kyleuckert   File: sankey.py    MIT License 6 votes vote down vote up
def _revert(self, path, first_action=Path.LINETO):
        """
        A path is not simply revertable by path[::-1] since the code
        specifies an action to take from the **previous** point.
        """
        reverse_path = []
        next_code = first_action
        for code, position in path[::-1]:
            reverse_path.append((next_code, position))
            next_code = code
        return reverse_path
        # This might be more efficient, but it fails because 'tuple' object
        # doesn't support item assignment:
        # path[1] = path[1][-1:0:-1]
        # path[1][0] = first_action
        # path[2] = path[2][::-1]
        # return path 
Example 5
Project: mkipp   Author: orlox   File: kipp_data.py    GNU General Public License v2.0 6 votes vote down vote up
def get_path(self):
        self.old_blocks.extend(self.last_blocks)
        vertices = []
        coords = []
        codes = []
        for block in self.old_blocks:
            vertices.extend(block.vertices)

        for starting_vertex in vertices:
            if starting_vertex.checked:
                continue
            starting_vertex.checked = True
            coords.append(starting_vertex.coords)
            codes.append(Path.MOVETO)
            current_vertex = starting_vertex
            while current_vertex.next_vertex != starting_vertex and not current_vertex.next_vertex.checked:
                current_vertex = current_vertex.next_vertex
                current_vertex.checked = True
                coords.append(current_vertex.coords)
                codes.append(Path.LINETO)
            coords.append((0,0))
            codes.append(Path.CLOSEPOLY)

        return Path(coords, codes) 
Example 6
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: backend_cairo.py    MIT License 6 votes vote down vote up
def _append_path(ctx, path, transform, clip=None):
    for points, code in path.iter_segments(
            transform, remove_nans=True, clip=clip):
        if code == Path.MOVETO:
            ctx.move_to(*points)
        elif code == Path.CLOSEPOLY:
           ctx.close_path()
        elif code == Path.LINETO:
            ctx.line_to(*points)
        elif code == Path.CURVE3:
            cur = np.asarray(ctx.get_current_point())
            a = points[:2]
            b = points[-2:]
            ctx.curve_to(*(cur / 3 + a * 2 / 3), *(a * 2 / 3 + b / 3), *b)
        elif code == Path.CURVE4:
            ctx.curve_to(*points) 
Example 7
Project: ble5-nrf52-mac   Author: tomasero   File: backend_cairo.py    MIT License 6 votes vote down vote up
def _append_paths_slow(ctx, paths, transforms, clip=None):
    for path, transform in zip(paths, transforms):
        for points, code in path.iter_segments(
                transform, remove_nans=True, clip=clip):
            if code == Path.MOVETO:
                ctx.move_to(*points)
            elif code == Path.CLOSEPOLY:
                ctx.close_path()
            elif code == Path.LINETO:
                ctx.line_to(*points)
            elif code == Path.CURVE3:
                cur = ctx.get_current_point()
                ctx.curve_to(
                    *np.concatenate([cur / 3 + points[:2] * 2 / 3,
                                     points[:2] * 2 / 3 + points[-2:] / 3]))
            elif code == Path.CURVE4:
                ctx.curve_to(*points) 
Example 8
Project: ble5-nrf52-mac   Author: tomasero   File: test_transforms.py    MIT License 6 votes vote down vote up
def test_clipping_of_log():
    # issue 804
    M, L, C = Path.MOVETO, Path.LINETO, Path.CLOSEPOLY
    points = [(0.2, -99), (0.4, -99), (0.4, 20), (0.2, 20), (0.2, -99)]
    codes = [M, L, L, L, C]
    path = Path(points, codes)

    # something like this happens in plotting logarithmic histograms
    trans = mtransforms.BlendedGenericTransform(mtransforms.Affine2D(),
                                            LogScale.Log10Transform('clip'))
    tpath = trans.transform_path_non_affine(path)
    result = tpath.iter_segments(trans.get_affine(),
                                 clip=(0, 0, 100, 100),
                                 simplify=False)

    tpoints, tcodes = zip(*result)
    assert_allclose(tcodes, [M, L, L, L, C]) 
Example 9
Project: ble5-nrf52-mac   Author: tomasero   File: test_table.py    MIT License 6 votes vote down vote up
def test_customcell():
    types = ('horizontal', 'vertical', 'open', 'closed', 'T', 'R', 'B', 'L')
    codes = (
        (Path.MOVETO, Path.LINETO, Path.MOVETO, Path.LINETO, Path.MOVETO),
        (Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO, Path.LINETO),
        (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO),
        (Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY),
        (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO),
        (Path.MOVETO, Path.MOVETO, Path.LINETO, Path.MOVETO, Path.MOVETO),
        (Path.MOVETO, Path.LINETO, Path.MOVETO, Path.MOVETO, Path.MOVETO),
        (Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.MOVETO, Path.LINETO),
        )

    for t, c in zip(types, codes):
        cell = CustomCell((0, 0), visible_edges=t, width=1, height=1)
        code = tuple(s for _, s in cell.get_path().iter_segments())
        assert c == code 
Example 10
Project: ble5-nrf52-mac   Author: tomasero   File: sankey.py    MIT License 6 votes vote down vote up
def _revert(self, path, first_action=Path.LINETO):
        """
        A path is not simply revertable by path[::-1] since the code
        specifies an action to take from the **previous** point.
        """
        reverse_path = []
        next_code = first_action
        for code, position in path[::-1]:
            reverse_path.append((next_code, position))
            next_code = code
        return reverse_path
        # This might be more efficient, but it fails because 'tuple' object
        # doesn't support item assignment:
        # path[1] = path[1][-1:0:-1]
        # path[1][0] = first_action
        # path[2] = path[2][::-1]
        # return path 
Example 11
Project: 3d-vehicle-tracking   Author: ucbdrive   File: show_labels.py    BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def poly2patch(self, vertices, types, closed=False, alpha=1., color=None):
        moves = {'L': Path.LINETO,
                 'C': Path.CURVE4}
        points = [v for v in vertices]
        codes = [moves[t] for t in types]
        codes[0] = Path.MOVETO

        if closed:
            points.append(points[0])
            codes.append(Path.CLOSEPOLY)

        if color is None:
            color = random_color()

        # print(codes, points)
        return mpatches.PathPatch(
            Path(points, codes),
            facecolor=color if closed else 'none',
            edgecolor=color,  # if not closed else 'none',
            lw=1 if closed else 2 * self.scale, alpha=alpha,
            antialiased=False, snap=True) 
Example 12
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 6 votes vote down vote up
def _get_bracket(self, x0, y0,
                         cos_t, sin_t, width, length,
                        ):

            # arrow from x0, y0 to x1, y1
            from matplotlib.bezier import get_normal_points
            x1, y1, x2, y2 = get_normal_points(x0, y0, cos_t, sin_t, width)

            dx, dy = length * cos_t, length * sin_t

            vertices_arrow = [(x1 + dx, y1 + dy),
                              (x1, y1),
                              (x2, y2),
                              (x2 + dx, y2 + dy)]
            codes_arrow = [Path.MOVETO,
                           Path.LINETO,
                           Path.LINETO,
                           Path.LINETO]

            return vertices_arrow, codes_arrow 
Example 13
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 6 votes vote down vote up
def transmute(self, path, mutation_size, linewidth):

            x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)

            arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
            b_plus, b_minus = make_wedged_bezier2(
                                    arrow_path,
                                    self.tail_width * mutation_size / 2.,
                                    wm=self.shrink_factor)

            patch_path = [(Path.MOVETO, b_plus[0]),
                          (Path.CURVE3, b_plus[1]),
                          (Path.CURVE3, b_plus[2]),
                          (Path.LINETO, b_minus[2]),
                          (Path.CURVE3, b_minus[1]),
                          (Path.CURVE3, b_minus[0]),
                          (Path.CLOSEPOLY, b_minus[0]),
                          ]
            path = Path([p for c, p in patch_path], [c for c, p in patch_path])

            return path, True 
Example 14
Project: Computable   Author: ktraunmueller   File: sankey.py    MIT License 6 votes vote down vote up
def _revert(self, path, first_action=Path.LINETO):
        """
        A path is not simply revertable by path[::-1] since the code
        specifies an action to take from the **previous** point.
        """
        reverse_path = []
        next_code = first_action
        for code, position in path[::-1]:
            reverse_path.append((next_code, position))
            next_code = code
        return reverse_path
        # This might be more efficient, but it fails because 'tuple' object
        # doesn't support item assignment:
        #path[1] = path[1][-1:0:-1]
        #path[1][0] = first_action
        #path[2] = path[2][::-1]
        #return path 
Example 15
Project: Computable   Author: ktraunmueller   File: axisline_style.py    MIT License 6 votes vote down vote up
def _extend_path(self, path, mutation_size=10):
            """
            Extend the path to make a room for drawing arrow.
            """
            from matplotlib.bezier import get_cos_sin

            x0, y0 = path.vertices[-2]
            x1, y1 = path.vertices[-1]
            cost, sint = get_cos_sin(x0, y0, x1, y1)

            d = mutation_size * 1.
            x2, y2 = x1 + cost*d, y1+sint*d

            if path.codes is None:
                _path = Path(np.concatenate([path.vertices, [[x2, y2]]]))
            else:
                _path = Path(np.concatenate([path.vertices, [[x2, y2]]]),
                             np.concatenate([path.codes, [Path.LINETO]]))

            return _path 
Example 16
Project: Computable   Author: ktraunmueller   File: inset_locator.py    MIT License 6 votes vote down vote up
def connect_bbox(bbox1, bbox2, loc1, loc2=None):
       if isinstance(bbox1, Rectangle):
          transform = bbox1.get_transfrom()
          bbox1 = Bbox.from_bounds(0, 0, 1, 1)
          bbox1 = TransformedBbox(bbox1, transform)

       if isinstance(bbox2, Rectangle):
          transform = bbox2.get_transform()
          bbox2 = Bbox.from_bounds(0, 0, 1, 1)
          bbox2 = TransformedBbox(bbox2, transform)

       if loc2 is None:
          loc2 = loc1

       x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1)
       x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2)

       verts = [[x1, y1], [x2,y2]]
       #Path()

       codes = [Path.MOVETO, Path.LINETO]

       return Path(verts, codes) 
Example 17
Project: bdd-data   Author: ucbdrive   File: show_labels.py    BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def poly2patch(self, poly2d, closed=False, alpha=1., color=None):
        moves = {'L': Path.LINETO,
                 'C': Path.CURVE4}
        points = [p[:2] for p in poly2d]
        codes = [moves[p[2]] for p in poly2d]
        codes[0] = Path.MOVETO

        if closed:
            points.append(points[0])
            if codes[-1] == 4:
                codes.append(Path.LINETO)
            else:
                codes.append(Path.CLOSEPOLY)

        if color is None:
            color = random_color()

        # print(codes, points)
        return mpatches.PathPatch(
            Path(points, codes),
            facecolor=color if closed else 'none',
            edgecolor=color,  # if not closed else 'none',
            lw=1 if closed else 2 * self.scale, alpha=alpha,
            antialiased=False, snap=True) 
Example 18
Project: bdd-data   Author: ucbdrive   File: show_labels.py    BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def poly2patch(self, vertices, types, closed=False, alpha=1., color=None):
        moves = {'L': Path.LINETO,
                 'C': Path.CURVE4}
        points = [v for v in vertices]
        codes = [moves[t] for t in types]
        codes[0] = Path.MOVETO

        if closed:
            points.append(points[0])
            codes.append(Path.CLOSEPOLY)

        if color is None:
            color = random_color()

        # print(codes, points)
        return mpatches.PathPatch(
            Path(points, codes),
            facecolor=color if closed else 'none',
            edgecolor=color,  # if not closed else 'none',
            lw=1 if closed else 2 * self.scale, alpha=alpha,
            antialiased=False, snap=True) 
Example 19
Project: viznet   Author: GiggleLiu   File: shapes.py    MIT License 6 votes vote down vote up
def rounded_path(vertices, roundness, close=False):
    '''make rounded path from vertices.'''
    vertices = np.asarray(vertices)
    if roundness == 0:
        vertices = vertices if not close else np.concatenate([vertices, vertices[:1]],axis=0)
        return Path(vertices, codes=[Path.MOVETO]+[Path.LINETO]*(len(vertices)-1))
    if close:
        vertices = np.concatenate([vertices, vertices[:2]], axis=0)

    codes = [Path.MOVETO]
    vertices_new = [vertices[0]]
    if close:
        cur, nex = vertices[:2]
        vertices_new[0] = cur + (nex - cur)/norm(cur-nex)*roundness
    for pre, cur, nex in zip(vertices[:-2], vertices[1:-1], vertices[2:]):
        codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3])
        dv_pre = (pre - cur)/norm(cur-pre)*roundness
        dv_nex = (nex - cur)/norm(cur-nex)*roundness
        vertices_new.extend([cur+dv_pre,cur,cur+dv_nex])
    if not close:
        codes.append(Path.LINETO)
        vertices_new.append(vertices[-1])
    return Path(vertices_new, codes) 
Example 20
Project: PyMICAPS   Author: flashlxy   File: maskout.py    GNU General Public License v2.0 5 votes vote down vote up
def getPathFromShp(shpfile, region):
    try:
        sf = shapefile.Reader(shpfile)
        vertices = []  # 这块是已经修改的地方
        codes = []  # 这块是已经修改的地方
        paths = []
        for shape_rec in sf.shapeRecords():
            # if shape_rec.record[3] == region:  # 这里需要找到和region匹配的唯一标识符,record[]中必有一项是对应的。
            if region == [100000] or shape_rec.record[4] in region:  # 这块是已经修改的地方
                pts = shape_rec.shape.points
                prt = list(shape_rec.shape.parts) + [len(pts)]
                for i in range(len(prt) - 1):
                    for j in range(prt[i], prt[i + 1]):
                        vertices.append((pts[j][0], pts[j][1]))
                    codes += [Path.MOVETO]
                    codes += [Path.LINETO] * (prt[i + 1] - prt[i] - 2)
                    codes += [Path.CLOSEPOLY]
                path = Path(vertices, codes)
                paths.append(path)
        if paths:
            path = Path.make_compound_path(*paths)
        else:
            path = None
        return path
    except Exception as err:
        print(err)
        return None 
Example 21
Project: OpenBTE   Author: romanodev   File: plot2.py    GNU General Public License v2.0 5 votes vote down vote up
def create_path(obj):

   codes = [Path.MOVETO]
   for n in range(len(obj)-1):
    codes.append(Path.LINETO)
   codes.append(Path.CLOSEPOLY)

   verts = []
   for tmp in obj:
     verts.append(tmp)
   verts.append(verts[0])

   path = Path(verts,codes)
   return path 
Example 22
Project: OpenBTE   Author: romanodev   File: geometry2_old.py    GNU General Public License v2.0 5 votes vote down vote up
def create_path(obj):

   codes = [Path.MOVETO]
   for n in list(range(len(obj)-1)):
    codes.append(Path.LINETO)
   codes.append(Path.CLOSEPOLY)

   verts = []
   for tmp in obj:
     verts.append(tmp)
   verts.append(verts[0])

   path = Path(verts,codes)
   return path 
Example 23
Project: OpenBTE   Author: romanodev   File: geometry2.py    GNU General Public License v2.0 5 votes vote down vote up
def create_path(obj):

   codes = [Path.MOVETO]
   for n in list(range(len(obj)-1)):
    codes.append(Path.LINETO)
   codes.append(Path.CLOSEPOLY)

   verts = []
   for tmp in obj:
     verts.append(tmp)
   verts.append(verts[0])

   path = Path(verts,codes)
   return path 
Example 24
Project: OpenBTE   Author: romanodev   File: plot.py    GNU General Public License v2.0 5 votes vote down vote up
def create_path(obj):

   codes = [Path.MOVETO]
   for n in range(len(obj)-1):
    codes.append(Path.LINETO)
   codes.append(Path.CLOSEPOLY)

   verts = []
   for tmp in obj:
     verts.append(tmp)
   verts.append(verts[0])

   path = Path(verts,codes)
   return path 
Example 25
Project: OpenBTE   Author: romanodev   File: geometry.py    GNU General Public License v2.0 5 votes vote down vote up
def create_path(obj):

   codes = [Path.MOVETO]
   for n in list(range(len(obj)-1)):
    codes.append(Path.LINETO)
   codes.append(Path.CLOSEPOLY)

   verts = []
   for tmp in obj:
     verts.append(tmp)
   verts.append(verts[0])

   path = Path(verts,codes)
   return path 
Example 26
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 5 votes vote down vote up
def _recompute_path(self):
        # Inner and outer rings are connected unless the annulus is complete
        if abs((self.theta2 - self.theta1) - 360) <= 1e-12:
            theta1, theta2 = 0, 360
            connector = Path.MOVETO
        else:
            theta1, theta2 = self.theta1, self.theta2
            connector = Path.LINETO

        # Form the outer ring
        arc = Path.arc(theta1, theta2)

        if self.width is not None:
            # Partial annulus needs to draw the outer ring
            # followed by a reversed and scaled inner ring
            v1 = arc.vertices
            v2 = arc.vertices[::-1] * float(self.r - self.width) / self.r
            v = np.vstack([v1, v2, v1[0, :], (0, 0)])
            c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY])
            c[len(arc.codes)] = connector
        else:
            # Wedge doesn't need an inner ring
            v = np.vstack([arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]])
            c = np.hstack([arc.codes, [connector, connector, Path.CLOSEPOLY]])

        # Shift and scale the wedge to the final location.
        v *= self.r
        v += np.asarray(self.center)
        self._path = Path(v, c) 
Example 27
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 5 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):
            pad = mutation_size * self.pad

            # width and height with padding added.
            width, height = width + 2*pad, height + 2*pad

            # boundary of the padded box
            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            vertices = [(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)]
            codes = [Path.MOVETO] + [Path.LINETO] * 3 + [Path.CLOSEPOLY]
            return Path(vertices, codes) 
Example 28
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 5 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):
            # padding
            pad = mutation_size * self.pad

            # width and height with padding added.
            width, height = width + 2. * pad, height + 2. * pad

            # boundary of the padded box
            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            dx = (y1 - y0) / 2.
            dxx = dx * .5
            # adjust x0.  1.4 <- sqrt(2)
            x0 = x0 + pad / 1.4

            cp = [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1),
                  (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
                  (x0 + dxx, y0 - dxx),  # arrow
                  (x0 + dxx, y0), (x0 + dxx, y0)]

            com = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
                   Path.LINETO, Path.LINETO, Path.LINETO,
                   Path.LINETO, Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 29
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 5 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):

            # padding
            pad = mutation_size * self.pad

            # width and height with padding added.
            # The width is padded by the arrows, so we don't need to pad it.
            height = height + 2. * pad

            # boundary of the padded box
            x0, y0 = x0 - pad, y0 - pad
            x1, y1 = x0 + width, y0 + height

            dx = (y1 - y0)/2.
            dxx = dx * .5
            # adjust x0.  1.4 <- sqrt(2)
            x0 = x0 + pad / 1.4

            cp = [(x0 + dxx, y0), (x1, y0),  # bot-segment
                  (x1, y0 - dxx), (x1 + dx + dxx, y0 + dx),
                  (x1, y1 + dxx),  # right-arrow
                  (x1, y1), (x0 + dxx, y1),  # top-segment
                  (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
                  (x0 + dxx, y0 - dxx),  # left-arrow
                  (x0 + dxx, y0), (x0 + dxx, y0)]  # close-poly

            com = [Path.MOVETO, Path.LINETO,
                   Path.LINETO, Path.LINETO,
                   Path.LINETO,
                   Path.LINETO, Path.LINETO,
                   Path.LINETO, Path.LINETO,
                   Path.LINETO,
                   Path.LINETO, Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 30
Project: LaserTOF   Author: kyleuckert   File: hatch.py    MIT License 5 votes vote down vote up
def __init__(self, hatch, density):
        self.num_rows = (hatch.count('*')) * density
        path = Path.unit_regular_star(5)
        self.shape_vertices = path.vertices
        self.shape_codes = np.ones(len(self.shape_vertices)) * Path.LINETO
        self.shape_codes[0] = Path.MOVETO
        Shapes.__init__(self, hatch, density) 
Example 31
Project: LaserTOF   Author: kyleuckert   File: backend_cairo.py    MIT License 5 votes vote down vote up
def convert_path(ctx, path, transform, clip=None):
        for points, code in path.iter_segments(transform, clip=clip):
            if code == Path.MOVETO:
                ctx.move_to(*points)
            elif code == Path.CLOSEPOLY:
                ctx.close_path()
            elif code == Path.LINETO:
                ctx.line_to(*points)
            elif code == Path.CURVE3:
                ctx.curve_to(points[0], points[1],
                             points[0], points[1],
                             points[2], points[3])
            elif code == Path.CURVE4:
                ctx.curve_to(*points) 
Example 32
Project: LaserTOF   Author: kyleuckert   File: backend_wx.py    MIT License 5 votes vote down vote up
def convert_path(gfx_ctx, path, transform):
        wxpath = gfx_ctx.CreatePath()
        for points, code in path.iter_segments(transform):
            if code == Path.MOVETO:
                wxpath.MoveToPoint(*points)
            elif code == Path.LINETO:
                wxpath.AddLineToPoint(*points)
            elif code == Path.CURVE3:
                wxpath.AddQuadCurveToPoint(*points)
            elif code == Path.CURVE4:
                wxpath.AddCurveToPoint(*points)
            elif code == Path.CLOSEPOLY:
                wxpath.CloseSubpath()
        return wxpath 
Example 33
Project: LaserTOF   Author: kyleuckert   File: backend_pgf.py    MIT License 5 votes vote down vote up
def _print_pgf_path(self, gc, path, transform, rgbFace=None):
        f = 1. / self.dpi
        # check for clip box / ignore clip for filled paths
        bbox = gc.get_clip_rectangle() if gc else None
        if bbox and (rgbFace is None):
            p1, p2 = bbox.get_points()
            clip = (p1[0], p1[1], p2[0], p2[1])
        else:
            clip = None
        # build path
        for points, code in path.iter_segments(transform, clip=clip):
            if code == Path.MOVETO:
                x, y = tuple(points)
                writeln(self.fh, r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CLOSEPOLY:
                writeln(self.fh, r"\pgfpathclose")
            elif code == Path.LINETO:
                x, y = tuple(points)
                writeln(self.fh, r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CURVE3:
                cx, cy, px, py = tuple(points)
                coords = cx * f, cy * f, px * f, py * f
                writeln(self.fh, r"\pgfpathquadraticcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords)
            elif code == Path.CURVE4:
                c1x, c1y, c2x, c2y, px, py = tuple(points)
                coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
                writeln(self.fh, r"\pgfpathcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords) 
Example 34
Project: LaserTOF   Author: kyleuckert   File: bezier.py    MIT License 5 votes vote down vote up
def make_path_regular(p):
    """
    fill in the codes if None.
    """
    c = p.codes
    if c is None:
        c = np.empty(p.vertices.shape[:1], "i")
        c.fill(Path.LINETO)
        c[0] = Path.MOVETO

        return Path(p.vertices, c)
    else:
        return p 
Example 35
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: hatch.py    MIT License 5 votes vote down vote up
def __init__(self, hatch, density):
        self.num_rows = (hatch.count('*')) * density
        path = Path.unit_regular_star(5)
        self.shape_vertices = path.vertices
        self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO,
                                   dtype=Path.code_type)
        self.shape_codes[0] = Path.MOVETO
        Shapes.__init__(self, hatch, density) 
Example 36
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: backend_wx.py    MIT License 5 votes vote down vote up
def convert_path(gfx_ctx, path, transform):
        wxpath = gfx_ctx.CreatePath()
        for points, code in path.iter_segments(transform):
            if code == Path.MOVETO:
                wxpath.MoveToPoint(*points)
            elif code == Path.LINETO:
                wxpath.AddLineToPoint(*points)
            elif code == Path.CURVE3:
                wxpath.AddQuadCurveToPoint(*points)
            elif code == Path.CURVE4:
                wxpath.AddCurveToPoint(*points)
            elif code == Path.CLOSEPOLY:
                wxpath.CloseSubpath()
        return wxpath 
Example 37
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: backend_pgf.py    MIT License 5 votes vote down vote up
def _print_pgf_path(self, gc, path, transform, rgbFace=None):
        f = 1. / self.dpi
        # check for clip box / ignore clip for filled paths
        bbox = gc.get_clip_rectangle() if gc else None
        if bbox and (rgbFace is None):
            p1, p2 = bbox.get_points()
            clip = (p1[0], p1[1], p2[0], p2[1])
        else:
            clip = None
        # build path
        for points, code in path.iter_segments(transform, clip=clip):
            if code == Path.MOVETO:
                x, y = tuple(points)
                writeln(self.fh,
                        r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CLOSEPOLY:
                writeln(self.fh, r"\pgfpathclose")
            elif code == Path.LINETO:
                x, y = tuple(points)
                writeln(self.fh,
                        r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CURVE3:
                cx, cy, px, py = tuple(points)
                coords = cx * f, cy * f, px * f, py * f
                writeln(self.fh,
                        r"\pgfpathquadraticcurveto"
                        r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
                        % coords)
            elif code == Path.CURVE4:
                c1x, c1y, c2x, c2y, px, py = tuple(points)
                coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
                writeln(self.fh,
                        r"\pgfpathcurveto"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        % coords) 
Example 38
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: bezier.py    MIT License 5 votes vote down vote up
def make_path_regular(p):
    """
    If the :attr:`codes` attribute of `Path` *p* is None, return a copy of *p*
    with the :attr:`codes` set to (MOVETO, LINETO, LINETO, ..., LINETO);
    otherwise return *p* itself.
    """
    c = p.codes
    if c is None:
        c = np.full(len(p.vertices), Path.LINETO, dtype=Path.code_type)
        c[0] = Path.MOVETO
        return Path(p.vertices, c)
    else:
        return p 
Example 39
Project: unmixing   Author: arthur-e   File: visualize.py    MIT License 5 votes vote down vote up
def plot_2d_mixing_space(self, features, hold=False):
        '''
        Draws a 2D (triangular) mixing space.
        '''
        codes = [VectorPath.MOVETO, VectorPath.LINETO, VectorPath.LINETO, VectorPath.CLOSEPOLY]
        verts = features[...,0:2].tolist()
        verts.append((0, 0)) # Dummy vertex
        path = VectorPath(verts, codes)
        patch = patches.PathPatch(path, facecolor='black', alpha=0.3, lw=0)
        plt.gca().add_patch(patch)

        if not hold:
            plt.show() 
Example 40
Project: jMetalPy   Author: jMetal   File: chord_plot.py    MIT License 5 votes vote down vote up
def draw_sector(start_angle=0, end_angle=60, radius=1.0, width=0.2, lw=2, ls='-', ax=None, fc=(1, 0, 0), ec=(0, 0, 0),
                z_order=1):
    if start_angle > end_angle:
        start_angle, end_angle = end_angle, start_angle
    start_angle *= np.pi / 180.
    end_angle *= np.pi / 180.

    # https://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves
    opt = 4. / 3. * np.tan((end_angle - start_angle) / 4.) * radius
    inner = radius * (1 - width)

    vertsPath = [polar_to_cartesian(radius, start_angle),
                 polar_to_cartesian(radius, start_angle) + polar_to_cartesian(opt, start_angle + 0.5 * np.pi),
                 polar_to_cartesian(radius, end_angle) + polar_to_cartesian(opt, end_angle - 0.5 * np.pi),
                 polar_to_cartesian(radius, end_angle),
                 polar_to_cartesian(inner, end_angle),
                 polar_to_cartesian(inner, end_angle) + polar_to_cartesian(opt * (1 - width), end_angle - 0.5 * np.pi),
                 polar_to_cartesian(inner, start_angle) + polar_to_cartesian(opt * (1 - width),
                                                                             start_angle + 0.5 * np.pi),
                 polar_to_cartesian(inner, start_angle),
                 polar_to_cartesian(radius, start_angle)]

    codesPaths = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, Path.LINETO, Path.CURVE4, Path.CURVE4,
                  Path.CURVE4, Path.CLOSEPOLY]

    if ax is None:
        return vertsPath, codesPaths
    else:
        path = Path(vertsPath, codesPaths)
        patch = patches.PathPatch(path, facecolor=fc, edgecolor=ec, lw=lw, linestyle=ls, zorder=z_order)
        ax.add_patch(patch)
        return (patch) 
Example 41
Project: ble5-nrf52-mac   Author: tomasero   File: hatch.py    MIT License 5 votes vote down vote up
def __init__(self, hatch, density):
        self.num_rows = (hatch.count('*')) * density
        path = Path.unit_regular_star(5)
        self.shape_vertices = path.vertices
        self.shape_codes = np.ones(len(self.shape_vertices)) * Path.LINETO
        self.shape_codes[0] = Path.MOVETO
        Shapes.__init__(self, hatch, density) 
Example 42
Project: ble5-nrf52-mac   Author: tomasero   File: backend_wx.py    MIT License 5 votes vote down vote up
def convert_path(gfx_ctx, path, transform):
        wxpath = gfx_ctx.CreatePath()
        for points, code in path.iter_segments(transform):
            if code == Path.MOVETO:
                wxpath.MoveToPoint(*points)
            elif code == Path.LINETO:
                wxpath.AddLineToPoint(*points)
            elif code == Path.CURVE3:
                wxpath.AddQuadCurveToPoint(*points)
            elif code == Path.CURVE4:
                wxpath.AddCurveToPoint(*points)
            elif code == Path.CLOSEPOLY:
                wxpath.CloseSubpath()
        return wxpath 
Example 43
Project: ble5-nrf52-mac   Author: tomasero   File: backend_pgf.py    MIT License 5 votes vote down vote up
def _print_pgf_path(self, gc, path, transform, rgbFace=None):
        f = 1. / self.dpi
        # check for clip box / ignore clip for filled paths
        bbox = gc.get_clip_rectangle() if gc else None
        if bbox and (rgbFace is None):
            p1, p2 = bbox.get_points()
            clip = (p1[0], p1[1], p2[0], p2[1])
        else:
            clip = None
        # build path
        for points, code in path.iter_segments(transform, clip=clip):
            if code == Path.MOVETO:
                x, y = tuple(points)
                writeln(self.fh,
                        r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CLOSEPOLY:
                writeln(self.fh, r"\pgfpathclose")
            elif code == Path.LINETO:
                x, y = tuple(points)
                writeln(self.fh,
                        r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CURVE3:
                cx, cy, px, py = tuple(points)
                coords = cx * f, cy * f, px * f, py * f
                writeln(self.fh,
                        r"\pgfpathquadraticcurveto"
                        r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
                        % coords)
            elif code == Path.CURVE4:
                c1x, c1y, c2x, c2y, px, py = tuple(points)
                coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
                writeln(self.fh,
                        r"\pgfpathcurveto"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        r"{\pgfqpoint{%fin}{%fin}}"
                        % coords) 
Example 44
Project: ble5-nrf52-mac   Author: tomasero   File: test_marker.py    MIT License 5 votes vote down vote up
def test_marker_path():
    marker_style = markers.MarkerStyle()
    path = Path([[0, 0], [1, 0]], [Path.MOVETO, Path.LINETO])
    # Checking this doesn't fail.
    marker_style.set_marker(path) 
Example 45
Project: ble5-nrf52-mac   Author: tomasero   File: test_path.py    MIT License 5 votes vote down vote up
def test_path_deepcopy():
    # Should not raise any error
    verts = [[0, 0], [1, 1]]
    codes = [Path.MOVETO, Path.LINETO]
    path1 = Path(verts)
    path2 = Path(verts, codes)
    copy.deepcopy(path1)
    copy.deepcopy(path2) 
Example 46
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 5 votes vote down vote up
def _recompute_path(self):
        # Inner and outer rings are connected unless the annulus is complete
        if abs((self.theta2 - self.theta1) - 360) <= 1e-12:
            theta1, theta2 = 0, 360
            connector = Path.MOVETO
        else:
            theta1, theta2 = self.theta1, self.theta2
            connector = Path.LINETO

        # Form the outer ring
        arc = Path.arc(theta1, theta2)

        if self.width is not None:
            # Partial annulus needs to draw the outer ring
            # followed by a reversed and scaled inner ring
            v1 = arc.vertices
            v2 = arc.vertices[::-1] * float(self.r - self.width) / self.r
            v = np.vstack([v1, v2, v1[0, :], (0, 0)])
            c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY])
            c[len(arc.codes)] = connector
        else:
            # Wedge doesn't need an inner ring
            v = np.vstack([arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]])
            c = np.hstack([arc.codes, [connector, connector, Path.CLOSEPOLY]])

        # Shift and scale the wedge to the final location.
        v *= self.r
        v += np.asarray(self.center)
        self._path = Path(v, c) 
Example 47
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 5 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):

            # padding
            pad = mutation_size * self.pad

            # width and height with padding added.
            width, height = width + 2. * pad, \
                            height + 2. * pad,

            # boundary of the padded box
            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            cp = [(x0, y0), (x1, y0), (x1, y1), (x0, y1),
                  (x0, y0), (x0, y0)]

            com = [Path.MOVETO,
                   Path.LINETO,
                   Path.LINETO,
                   Path.LINETO,
                   Path.LINETO,
                   Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 48
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 5 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):

            # padding
            pad = mutation_size * self.pad

            # width and height with padding added.
            width, height = width + 2. * pad, \
                            height + 2. * pad,

            # boundary of the padded box
            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            dx = (y1 - y0) / 2.
            dxx = dx * .5
            # adjust x0.  1.4 <- sqrt(2)
            x0 = x0 + pad / 1.4

            cp = [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1),
                  (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
                  (x0 + dxx, y0 - dxx),  # arrow
                  (x0 + dxx, y0), (x0 + dxx, y0)]

            com = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
                   Path.LINETO, Path.LINETO, Path.LINETO,
                   Path.LINETO, Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 49
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 5 votes vote down vote up
def connect(self, posA, posB):
            x1, y1 = posA
            x2, y2 = posB

            cosA, sinA = math.cos(self.angleA / 180. * math.pi),\
                         math.sin(self.angleA / 180. * math.pi),
            cosB, sinB = math.cos(self.angleB / 180. * math.pi),\
                         math.sin(self.angleB / 180. * math.pi),

            cx, cy = get_intersection(x1, y1, cosA, sinA,
                                      x2, y2, cosB, sinB)

            vertices = [(x1, y1)]
            codes = [Path.MOVETO]

            if self.rad == 0.:
                vertices.append((cx, cy))
                codes.append(Path.LINETO)
            else:
                dx1, dy1 = x1 - cx, y1 - cy
                d1 = (dx1 ** 2 + dy1 ** 2) ** .5
                f1 = self.rad / d1
                dx2, dy2 = x2 - cx, y2 - cy
                d2 = (dx2 ** 2 + dy2 ** 2) ** .5
                f2 = self.rad / d2
                vertices.extend([(cx + dx1 * f1, cy + dy1 * f1),
                                 (cx, cy),
                                 (cx + dx2 * f2, cy + dy2 * f2)])
                codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3])

            vertices.append((x2, y2))
            codes.append(Path.LINETO)

            return Path(vertices, codes) 
Example 50
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 5 votes vote down vote up
def _get_arrow_wedge(self, x0, y0, x1, y1,
                             head_dist, cos_t, sin_t, linewidth
                            ):
            """
            Return the paths for arrow heads. Since arrow lines are
            drawn with capstyle=projected, The arrow goes beyond the
            desired point. This method also returns the amount of the path
            to be shrinked so that it does not overshoot.
            """

            # arrow from x0, y0 to x1, y1

            dx, dy = x0 - x1, y0 - y1
            cp_distance = math.sqrt(dx ** 2 + dy ** 2)

            # pad_projected : amount of pad to account the
            # overshooting of the projection of the wedge
            pad_projected = (.5 * linewidth / sin_t)

            # apply pad for projected edge
            ddx = pad_projected * dx / cp_distance
            ddy = pad_projected * dy / cp_distance

            # offset for arrow wedge
            dx = dx / cp_distance * head_dist
            dy = dy / cp_distance * head_dist

            dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy
            dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy

            vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1),
                              (x1 + ddx, y1 + ddy),
                              (x1 + ddx + dx2, y1 + ddy + dy2)]
            codes_arrow = [Path.MOVETO,
                           Path.LINETO,
                           Path.LINETO]

            return vertices_arrow, codes_arrow, ddx, ddy 
Example 51
Project: Computable   Author: ktraunmueller   File: hatch.py    MIT License 5 votes vote down vote up
def __init__(self, hatch, density):
        self.num_rows = (hatch.count('*')) * density
        path = Path.unit_regular_star(5)
        self.shape_vertices = path.vertices
        self.shape_codes = np.ones(len(self.shape_vertices)) * Path.LINETO
        self.shape_codes[0] = Path.MOVETO
        Shapes.__init__(self, hatch, density) 
Example 52
Project: Computable   Author: ktraunmueller   File: backend_pdf.py    MIT License 5 votes vote down vote up
def pathOperations(path, transform, clip=None, simplify=None, sketch=None):
        cmds = []
        last_points = None
        for points, code in path.iter_segments(transform, clip=clip,
                                               simplify=simplify,
                                               sketch=sketch):
            if code == Path.MOVETO:
                # This is allowed anywhere in the path
                cmds.extend(points)
                cmds.append(Op.moveto)
            elif code == Path.CLOSEPOLY:
                cmds.append(Op.closepath)
            elif last_points is None:
                # The other operations require a previous point
                raise ValueError('Path lacks initial MOVETO')
            elif code == Path.LINETO:
                cmds.extend(points)
                cmds.append(Op.lineto)
            elif code == Path.CURVE3:
                points = quad2cubic(*(list(last_points[-2:]) + list(points)))
                cmds.extend(points[2:])
                cmds.append(Op.curveto)
            elif code == Path.CURVE4:
                cmds.extend(points)
                cmds.append(Op.curveto)
            last_points = points
        return cmds 
Example 53
Project: Computable   Author: ktraunmueller   File: backend_ps.py    MIT License 5 votes vote down vote up
def _convert_path(self, path, transform, clip=False, simplify=None):
        ps = []
        last_points = None
        if clip:
            clip = (0.0, 0.0, self.width * 72.0,
                    self.height * 72.0)
        else:
            clip = None
        for points, code in path.iter_segments(transform, clip=clip,
                                               simplify=simplify):
            if code == Path.MOVETO:
                ps.append("%g %g m" % tuple(points))
            elif code == Path.CLOSEPOLY:
                ps.append("cl")
            elif last_points is None:
                # The other operations require a previous point
                raise ValueError('Path lacks initial MOVETO')
            elif code == Path.LINETO:
                ps.append("%g %g l" % tuple(points))
            elif code == Path.CURVE3:
                points = quad2cubic(*(list(last_points[-2:]) + list(points)))
                ps.append("%g %g %g %g %g %g c" %
                          tuple(points[2:]))
            elif code == Path.CURVE4:
                ps.append("%g %g %g %g %g %g c" % tuple(points))
            last_points = points

        ps = "\n".join(ps)
        return ps 
Example 54
Project: Computable   Author: ktraunmueller   File: backend_wx.py    MIT License 5 votes vote down vote up
def convert_path(gfx_ctx, path, transform):
        wxpath = gfx_ctx.CreatePath()
        for points, code in path.iter_segments(transform):
            if code == Path.MOVETO:
                wxpath.MoveToPoint(*points)
            elif code == Path.LINETO:
                wxpath.AddLineToPoint(*points)
            elif code == Path.CURVE3:
                wxpath.AddQuadCurveToPoint(*points)
            elif code == Path.CURVE4:
                wxpath.AddCurveToPoint(*points)
            elif code == Path.CLOSEPOLY:
                wxpath.CloseSubpath()
        return wxpath 
Example 55
Project: Computable   Author: ktraunmueller   File: backend_pgf.py    MIT License 5 votes vote down vote up
def _print_pgf_path(self, gc, path, transform):
        f = 1. / self.dpi
        # check for clip box
        bbox = gc.get_clip_rectangle() if gc else None
        if bbox:
            p1, p2 = bbox.get_points()
            clip = (p1[0], p1[1], p2[0], p2[1])
        else:
            clip = None
        # build path
        for points, code in path.iter_segments(transform, clip=clip):
            if code == Path.MOVETO:
                x, y = tuple(points)
                writeln(self.fh, r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CLOSEPOLY:
                writeln(self.fh, r"\pgfpathclose")
            elif code == Path.LINETO:
                x, y = tuple(points)
                writeln(self.fh, r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
                        (f * x, f * y))
            elif code == Path.CURVE3:
                cx, cy, px, py = tuple(points)
                coords = cx * f, cy * f, px * f, py * f
                writeln(self.fh, r"\pgfpathquadraticcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords)
            elif code == Path.CURVE4:
                c1x, c1y, c2x, c2y, px, py = tuple(points)
                coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
                writeln(self.fh, r"\pgfpathcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords) 
Example 56
Project: TAGGS   Author: jensdebruijn   File: geo.py    MIT License 5 votes vote down vote up
def PolygonCodes(shape):
    def coding(ob):
        n = len(getattr(ob, 'coords', None) or ob)
        vals = np.ones(n, dtype=Path.code_type) * Path.LINETO
        vals[0] = Path.MOVETO
        return vals

    vertices = np.concatenate(
                            [np.asarray(shape.exterior)] +
                            [np.asarray(r) for r in shape.interiors] + [np.zeros((1, 2))])
    codes = np.concatenate(
                    [coding(shape.exterior)] +
                    [coding(r) for r in shape.interiors] + [np.array([Path.CLOSEPOLY])])
    return codes, vertices 
Example 57
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 4 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):

            # padding
            pad = mutation_size * self.pad

            # size of the roudning corner
            if self.rounding_size:
                dr = mutation_size * self.rounding_size
            else:
                dr = pad

            width, height = width + 2. * pad, height + 2. * pad

            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            # Round corners are implemented as quadratic bezier. e.g.,
            # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
            cp = [(x0 + dr, y0),
                  (x1 - dr, y0),
                  (x1, y0), (x1, y0 + dr),
                  (x1, y1 - dr),
                  (x1, y1), (x1 - dr, y1),
                  (x0 + dr, y1),
                  (x0, y1), (x0, y1 - dr),
                  (x0, y0 + dr),
                  (x0, y0), (x0 + dr, y0),
                  (x0 + dr, y0)]

            com = [Path.MOVETO,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 58
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 4 votes vote down vote up
def connect(self, posA, posB):
            x1, y1 = posA
            x2, y2 = posB

            vertices = [(x1, y1)]
            rounded = []
            codes = [Path.MOVETO]

            if self.armA:
                cosA = math.cos(self.angleA / 180. * math.pi)
                sinA = math.sin(self.angleA / 180. * math.pi)
                # x_armA, y_armB
                d = self.armA - self.rad
                rounded.append((x1 + d * cosA, y1 + d * sinA))
                d = self.armA
                rounded.append((x1 + d * cosA, y1 + d * sinA))

            if self.armB:
                cosB = math.cos(self.angleB / 180. * math.pi)
                sinB = math.sin(self.angleB / 180. * math.pi)
                x_armB, y_armB = x2 + self.armB * cosB, y2 + self.armB * sinB

                if rounded:
                    xp, yp = rounded[-1]
                    dx, dy = x_armB - xp, y_armB - yp
                    dd = (dx * dx + dy * dy) ** .5

                    rounded.append((xp + self.rad * dx / dd,
                                    yp + self.rad * dy / dd))
                    vertices.extend(rounded)
                    codes.extend([Path.LINETO,
                                  Path.CURVE3,
                                  Path.CURVE3])
                else:
                    xp, yp = vertices[-1]
                    dx, dy = x_armB - xp, y_armB - yp
                    dd = (dx * dx + dy * dy) ** .5

                d = dd - self.rad
                rounded = [(xp + d * dx / dd, yp + d * dy / dd),
                           (x_armB, y_armB)]

            if rounded:
                xp, yp = rounded[-1]
                dx, dy = x2 - xp, y2 - yp
                dd = (dx * dx + dy * dy) ** .5

                rounded.append((xp + self.rad * dx / dd,
                                yp + self.rad * dy / dd))
                vertices.extend(rounded)
                codes.extend([Path.LINETO,
                              Path.CURVE3,
                              Path.CURVE3])

            vertices.append((x2, y2))
            codes.append(Path.LINETO)

            return Path(vertices, codes) 
Example 59
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 4 votes vote down vote up
def connect(self, posA, posB):
            x1, y1 = posA
            x20, y20 = x2, y2 = posB

            x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2.

            theta1 = math.atan2(y2 - y1, x2 - x1)
            dx, dy = x2 - x1, y2 - y1
            dd = (dx * dx + dy * dy) ** .5
            ddx, ddy = dx / dd, dy / dd

            armA, armB = self.armA, self.armB

            if self.angle is not None:
                #angle = self.angle % 180.
                #if angle < 0. or angle > 180.:
                #    angle
                #theta0 = (self.angle%180.)/180.*math.pi
                theta0 = self.angle / 180. * math.pi
                #theta0 = (((self.angle+90)%180.)  - 90.)/180.*math.pi
                dtheta = theta1 - theta0
                dl = dd * math.sin(dtheta)

                dL = dd * math.cos(dtheta)

                #x2, y2 = x2 + dl*ddy, y2 - dl*ddx
                x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0)

                armB = armB - dl

                # update
                dx, dy = x2 - x1, y2 - y1
                dd2 = (dx * dx + dy * dy) ** .5
                ddx, ddy = dx / dd2, dy / dd2

            else:
                dl = 0.

            #if armA > armB:
            #    armB = armA + dl
            #else:
            #    armA = armB - dl

            arm = max(armA, armB)
            f = self.fraction * dd + arm
            #fB = self.fraction*dd + armB

            cx1, cy1 = x1 + f * ddy, y1 - f * ddx
            cx2, cy2 = x2 + f * ddy, y2 - f * ddx

            vertices = [(x1, y1),
                        (cx1, cy1),
                        (cx2, cy2),
                        (x20, y20)]
            codes = [Path.MOVETO,
                     Path.LINETO,
                     Path.LINETO,
                     Path.LINETO]

            return Path(vertices, codes) 
Example 60
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 4 votes vote down vote up
def _get_arrow_wedge(self, x0, y0, x1, y1,
                             head_dist, cos_t, sin_t, linewidth
                            ):
            """
            Return the paths for arrow heads. Since arrow lines are
            drawn with capstyle=projected, The arrow goes beyond the
            desired point. This method also returns the amount of the path
            to be shrunken so that it does not overshoot.
            """

            # arrow from x0, y0 to x1, y1
            dx, dy = x0 - x1, y0 - y1

            cp_distance = np.hypot(dx, dy)

            # pad_projected : amount of pad to account the
            # overshooting of the projection of the wedge
            pad_projected = (.5 * linewidth / sin_t)

            # Account for division by zero
            if cp_distance == 0:
                cp_distance = 1

            # apply pad for projected edge
            ddx = pad_projected * dx / cp_distance
            ddy = pad_projected * dy / cp_distance

            # offset for arrow wedge
            dx = dx / cp_distance * head_dist
            dy = dy / cp_distance * head_dist

            dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy
            dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy

            vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1),
                              (x1 + ddx, y1 + ddy),
                              (x1 + ddx + dx2, y1 + ddy + dy2)]
            codes_arrow = [Path.MOVETO,
                           Path.LINETO,
                           Path.LINETO]

            return vertices_arrow, codes_arrow, ddx, ddy 
Example 61
Project: LaserTOF   Author: kyleuckert   File: patches.py    MIT License 4 votes vote down vote up
def transmute(self, path, mutation_size, linewidth):

            x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)

            # divide the path into a head and a tail
            head_length = self.head_length * mutation_size
            in_f = inside_circle(x2, y2, head_length)
            arrow_path = [(x0, y0), (x1, y1), (x2, y2)]

            from .bezier import NonIntersectingPathException

            try:
                arrow_out, arrow_in = \
                      split_bezier_intersecting_with_closedpath(arrow_path,
                                                                in_f,
                                                                tolerence=0.01)
            except NonIntersectingPathException:
                # if this happens, make a straight line of the head_length
                # long.
                x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
                x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2)
                arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)]
                arrow_out = None

            # head
            head_width = self.head_width * mutation_size
            head_left, head_right = make_wedged_bezier2(arrow_in,
                                                        head_width / 2., wm=.5)

            # tail
            if arrow_out is not None:
                tail_width = self.tail_width * mutation_size
                tail_left, tail_right = get_parallels(arrow_out,
                                                      tail_width / 2.)

                patch_path = [(Path.MOVETO, tail_right[0]),
                              (Path.CURVE3, tail_right[1]),
                              (Path.CURVE3, tail_right[2]),
                              (Path.LINETO, head_right[0]),
                              (Path.CURVE3, head_right[1]),
                              (Path.CURVE3, head_right[2]),
                              (Path.CURVE3, head_left[1]),
                              (Path.CURVE3, head_left[0]),
                              (Path.LINETO, tail_left[2]),
                              (Path.CURVE3, tail_left[1]),
                              (Path.CURVE3, tail_left[0]),
                              (Path.LINETO, tail_right[0]),
                              (Path.CLOSEPOLY, tail_right[0]),
                              ]
            else:
                patch_path = [(Path.MOVETO, head_right[0]),
                              (Path.CURVE3, head_right[1]),
                              (Path.CURVE3, head_right[2]),
                              (Path.CURVE3, head_left[1]),
                              (Path.CURVE3, head_left[0]),
                              (Path.CLOSEPOLY, head_left[0]),
                              ]

            path = Path([p for c, p in patch_path], [c for c, p in patch_path])

            return path, True 
Example 62
Project: LaserTOF   Author: kyleuckert   File: sankey.py    MIT License 4 votes vote down vote up
def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
        """
        Return the codes and vertices for a rotated, scaled, and translated
        90 degree arc.

        Optional keyword arguments:

          ===============   ==========================================
          Keyword           Description
          ===============   ==========================================
          *quadrant*        uses 0-based indexing (0, 1, 2, or 3)
          *cw*              if True, clockwise
          *center*          (x, y) tuple of the arc's center
          ===============   ==========================================
        """
        # Note:  It would be possible to use matplotlib's transforms to rotate,
        # scale, and translate the arc, but since the angles are discrete,
        # it's just as easy and maybe more efficient to do it here.
        ARC_CODES = [Path.LINETO,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4]
        # Vertices of a cubic Bezier curve approximating a 90 deg arc
        # These can be determined by Path.arc(0,90).
        ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
                                 [1.00000000e+00, 2.65114773e-01],
                                 [8.94571235e-01, 5.19642327e-01],
                                 [7.07106781e-01, 7.07106781e-01],
                                 [5.19642327e-01, 8.94571235e-01],
                                 [2.65114773e-01, 1.00000000e+00],
                                 # Insignificant
                                 # [6.12303177e-17, 1.00000000e+00]])
                                 [0.00000000e+00, 1.00000000e+00]])
        if quadrant == 0 or quadrant == 2:
            if cw:
                vertices = ARC_VERTICES
            else:
                vertices = ARC_VERTICES[:, ::-1]  # Swap x and y.
        elif quadrant == 1 or quadrant == 3:
            # Negate x.
            if cw:
                # Swap x and y.
                vertices = np.column_stack((-ARC_VERTICES[:, 1],
                                             ARC_VERTICES[:, 0]))
            else:
                vertices = np.column_stack((-ARC_VERTICES[:, 0],
                                             ARC_VERTICES[:, 1]))
        if quadrant > 1:
            radius = -radius  # Rotate 180 deg.
        return list(zip(ARC_CODES, radius * vertices +
                        np.tile(center, (ARC_VERTICES.shape[0], 1)))) 
Example 63
Project: LaserTOF   Author: kyleuckert   File: sankey.py    MIT License 4 votes vote down vote up
def _add_input(self, path, angle, flow, length):
        """
        Add an input to a path and return its tip and label locations.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            dipdepth = (flow / 2) * self.pitch
            if angle == RIGHT:
                x -= length
                dip = [x + dipdepth, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x + self.gap, y + flow])])
                label_location = [dip[0] - self.offset, dip[1]]
            else:  # Vertical
                x -= self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                dip = [x - flow / 2, y - sign * (length - dipdepth)]
                if angle == DOWN:
                    quadrant = 2
                else:
                    quadrant = 1

                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x + self.radius,
                                                  y - sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y - sign * length]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x - flow, y - sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=flow + self.radius,
                                      center=(x + self.radius,
                                              y - sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [dip[0], dip[1] - sign * self.offset]

            return dip, label_location 
Example 64
Project: LaserTOF   Author: kyleuckert   File: sankey.py    MIT License 4 votes vote down vote up
def _add_output(self, path, angle, flow, length):
        """
        Append an output to a path and return its tip and label locations.

        .. note:: *flow* is negative for an output.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            tipheight = (self.shoulder - flow / 2) * self.pitch
            if angle == RIGHT:
                x += length
                tip = [x + tipheight, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, [x, y + self.shoulder]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x, y - self.shoulder + flow]),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x - self.gap, y + flow])])
                label_location = [tip[0] + self.offset, tip[1]]
            else:  # Vertical
                x += self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                tip = [x - flow / 2.0, y + sign * (length + tipheight)]
                if angle == UP:
                    quadrant = 3
                else:
                    quadrant = 0
                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x - self.radius,
                                                  y + sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y + sign * length]),
                             (Path.LINETO, [x - self.shoulder,
                                            y + sign * length]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x + self.shoulder - flow,
                                            y + sign * length]),
                             (Path.LINETO, [x - flow, y + sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=self.radius - flow,
                                      center=(x - self.radius,
                                              y + sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [tip[0], tip[1] + sign * self.offset]
            return tip, label_location 
Example 65
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: textpath.py    MIT License 4 votes vote down vote up
def get_glyphs_mathtext(self, prop, s, glyph_map=None,
                            return_new_glyphs_only=False):
        """
        Parse mathtext string *s* and convert it to a (vertices, codes) pair.
        """

        prop = prop.copy()
        prop.set_size(self.FONT_SCALE)

        width, height, descent, glyphs, rects = self.mathtext_parser.parse(
            s, self.DPI, prop)

        if not glyph_map:
            glyph_map = OrderedDict()

        if return_new_glyphs_only:
            glyph_map_new = OrderedDict()
        else:
            glyph_map_new = glyph_map

        xpositions = []
        ypositions = []
        glyph_ids = []
        sizes = []

        for font, fontsize, ccode, ox, oy in glyphs:
            char_id = self._get_char_id(font, ccode)
            if char_id not in glyph_map:
                font.clear()
                font.set_size(self.FONT_SCALE, self.DPI)
                glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
                glyph_map_new[char_id] = font.get_path()

            xpositions.append(ox)
            ypositions.append(oy)
            glyph_ids.append(char_id)
            size = fontsize / self.FONT_SCALE
            sizes.append(size)

        myrects = []
        for ox, oy, w, h in rects:
            vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h),
                     (ox + w, oy), (ox, oy), (0, 0)]
            code1 = [Path.MOVETO,
                     Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
                     Path.CLOSEPOLY]
            myrects.append((vert1, code1))

        return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
                glyph_map_new, myrects) 
Example 66
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: bezier.py    MIT License 4 votes vote down vote up
def split_path_inout(path, inside, tolerance=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 = next(path_iter)
    begin_inside = inside(ctl_points[-2:])  # true if begin point is inside

    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
    else:
        raise ValueError("The path does not intersect with the patch")

    bp = bezier_path.reshape((-1, 2))
    left, right = split_bezier_intersecting_with_closedpath(
        bp, inside, tolerance)
    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 AssertionError("This should never be reached")

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

    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 not begin_inside:
        path_in, path_out = path_out, path_in

    return path_in, path_out 
Example 67
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: sankey.py    MIT License 4 votes vote down vote up
def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
        """
        Return the codes and vertices for a rotated, scaled, and translated
        90 degree arc.

        Optional keyword arguments:

          ===============   ==========================================
          Keyword           Description
          ===============   ==========================================
          *quadrant*        uses 0-based indexing (0, 1, 2, or 3)
          *cw*              if True, clockwise
          *center*          (x, y) tuple of the arc's center
          ===============   ==========================================
        """
        # Note:  It would be possible to use matplotlib's transforms to rotate,
        # scale, and translate the arc, but since the angles are discrete,
        # it's just as easy and maybe more efficient to do it here.
        ARC_CODES = [Path.LINETO,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4]
        # Vertices of a cubic Bezier curve approximating a 90 deg arc
        # These can be determined by Path.arc(0,90).
        ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
                                 [1.00000000e+00, 2.65114773e-01],
                                 [8.94571235e-01, 5.19642327e-01],
                                 [7.07106781e-01, 7.07106781e-01],
                                 [5.19642327e-01, 8.94571235e-01],
                                 [2.65114773e-01, 1.00000000e+00],
                                 # Insignificant
                                 # [6.12303177e-17, 1.00000000e+00]])
                                 [0.00000000e+00, 1.00000000e+00]])
        if quadrant == 0 or quadrant == 2:
            if cw:
                vertices = ARC_VERTICES
            else:
                vertices = ARC_VERTICES[:, ::-1]  # Swap x and y.
        elif quadrant == 1 or quadrant == 3:
            # Negate x.
            if cw:
                # Swap x and y.
                vertices = np.column_stack((-ARC_VERTICES[:, 1],
                                             ARC_VERTICES[:, 0]))
            else:
                vertices = np.column_stack((-ARC_VERTICES[:, 0],
                                             ARC_VERTICES[:, 1]))
        if quadrant > 1:
            radius = -radius  # Rotate 180 deg.
        return list(zip(ARC_CODES, radius * vertices +
                        np.tile(center, (ARC_VERTICES.shape[0], 1)))) 
Example 68
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: sankey.py    MIT License 4 votes vote down vote up
def _add_input(self, path, angle, flow, length):
        """
        Add an input to a path and return its tip and label locations.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            dipdepth = (flow / 2) * self.pitch
            if angle == RIGHT:
                x -= length
                dip = [x + dipdepth, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x + self.gap, y + flow])])
                label_location = [dip[0] - self.offset, dip[1]]
            else:  # Vertical
                x -= self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                dip = [x - flow / 2, y - sign * (length - dipdepth)]
                if angle == DOWN:
                    quadrant = 2
                else:
                    quadrant = 1

                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x + self.radius,
                                                  y - sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y - sign * length]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x - flow, y - sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=flow + self.radius,
                                      center=(x + self.radius,
                                              y - sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [dip[0], dip[1] - sign * self.offset]

            return dip, label_location 
Example 69
Project: FX-RER-Value-Extraction   Author: tsKenneth   File: sankey.py    MIT License 4 votes vote down vote up
def _add_output(self, path, angle, flow, length):
        """
        Append an output to a path and return its tip and label locations.

        .. note:: *flow* is negative for an output.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            tipheight = (self.shoulder - flow / 2) * self.pitch
            if angle == RIGHT:
                x += length
                tip = [x + tipheight, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, [x, y + self.shoulder]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x, y - self.shoulder + flow]),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x - self.gap, y + flow])])
                label_location = [tip[0] + self.offset, tip[1]]
            else:  # Vertical
                x += self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                tip = [x - flow / 2.0, y + sign * (length + tipheight)]
                if angle == UP:
                    quadrant = 3
                else:
                    quadrant = 0
                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x - self.radius,
                                                  y + sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y + sign * length]),
                             (Path.LINETO, [x - self.shoulder,
                                            y + sign * length]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x + self.shoulder - flow,
                                            y + sign * length]),
                             (Path.LINETO, [x - flow, y + sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=self.radius - flow,
                                      center=(x - self.radius,
                                              y + sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [tip[0], tip[1] + sign * self.offset]
            return tip, label_location 
Example 70
Project: ble5-nrf52-mac   Author: tomasero   File: textpath.py    MIT License 4 votes vote down vote up
def get_glyphs_mathtext(self, prop, s, glyph_map=None,
                            return_new_glyphs_only=False):
        """
        convert the string *s* to vertices and codes by parsing it with
        mathtext.
        """

        prop = prop.copy()
        prop.set_size(self.FONT_SCALE)

        width, height, descent, glyphs, rects = self.mathtext_parser.parse(
            s, self.DPI, prop)

        if not glyph_map:
            glyph_map = OrderedDict()

        if return_new_glyphs_only:
            glyph_map_new = OrderedDict()
        else:
            glyph_map_new = glyph_map

        xpositions = []
        ypositions = []
        glyph_ids = []
        sizes = []

        currx, curry = 0, 0
        for font, fontsize, ccode, ox, oy in glyphs:
            char_id = self._get_char_id(font, ccode)
            if char_id not in glyph_map:
                font.clear()
                font.set_size(self.FONT_SCALE, self.DPI)
                glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
                glyph_map_new[char_id] = self.glyph_to_path(font)

            xpositions.append(ox)
            ypositions.append(oy)
            glyph_ids.append(char_id)
            size = fontsize / self.FONT_SCALE
            sizes.append(size)

        myrects = []
        for ox, oy, w, h in rects:
            vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h),
                     (ox + w, oy), (ox, oy), (0, 0)]
            code1 = [Path.MOVETO,
                     Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
                     Path.CLOSEPOLY]
            myrects.append((vert1, code1))

        return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
                glyph_map_new, myrects) 
Example 71
Project: ble5-nrf52-mac   Author: tomasero   File: bezier.py    MIT License 4 votes vote down vote up
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 = next(path_iter)
    begin_inside = inside(ctl_points[-2:])  # true if begin point is inside

    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
    else:
        raise ValueError("The path does not intersect with the patch")

    bp = bezier_path.reshape((-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 AssertionError("This should never be reached")

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

    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 is False:
        path_in, path_out = path_out, path_in

    return path_in, path_out 
Example 72
Project: ble5-nrf52-mac   Author: tomasero   File: sankey.py    MIT License 4 votes vote down vote up
def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
        """
        Return the codes and vertices for a rotated, scaled, and translated
        90 degree arc.

        Optional keyword arguments:

          ===============   ==========================================
          Keyword           Description
          ===============   ==========================================
          *quadrant*        uses 0-based indexing (0, 1, 2, or 3)
          *cw*              if True, clockwise
          *center*          (x, y) tuple of the arc's center
          ===============   ==========================================
        """
        # Note:  It would be possible to use matplotlib's transforms to rotate,
        # scale, and translate the arc, but since the angles are discrete,
        # it's just as easy and maybe more efficient to do it here.
        ARC_CODES = [Path.LINETO,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4]
        # Vertices of a cubic Bezier curve approximating a 90 deg arc
        # These can be determined by Path.arc(0,90).
        ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
                                 [1.00000000e+00, 2.65114773e-01],
                                 [8.94571235e-01, 5.19642327e-01],
                                 [7.07106781e-01, 7.07106781e-01],
                                 [5.19642327e-01, 8.94571235e-01],
                                 [2.65114773e-01, 1.00000000e+00],
                                 # Insignificant
                                 # [6.12303177e-17, 1.00000000e+00]])
                                 [0.00000000e+00, 1.00000000e+00]])
        if quadrant == 0 or quadrant == 2:
            if cw:
                vertices = ARC_VERTICES
            else:
                vertices = ARC_VERTICES[:, ::-1]  # Swap x and y.
        elif quadrant == 1 or quadrant == 3:
            # Negate x.
            if cw:
                # Swap x and y.
                vertices = np.column_stack((-ARC_VERTICES[:, 1],
                                             ARC_VERTICES[:, 0]))
            else:
                vertices = np.column_stack((-ARC_VERTICES[:, 0],
                                             ARC_VERTICES[:, 1]))
        if quadrant > 1:
            radius = -radius  # Rotate 180 deg.
        return list(zip(ARC_CODES, radius * vertices +
                        np.tile(center, (ARC_VERTICES.shape[0], 1)))) 
Example 73
Project: ble5-nrf52-mac   Author: tomasero   File: sankey.py    MIT License 4 votes vote down vote up
def _add_input(self, path, angle, flow, length):
        """
        Add an input to a path and return its tip and label locations.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            dipdepth = (flow / 2) * self.pitch
            if angle == RIGHT:
                x -= length
                dip = [x + dipdepth, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x + self.gap, y + flow])])
                label_location = [dip[0] - self.offset, dip[1]]
            else:  # Vertical
                x -= self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                dip = [x - flow / 2, y - sign * (length - dipdepth)]
                if angle == DOWN:
                    quadrant = 2
                else:
                    quadrant = 1

                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x + self.radius,
                                                  y - sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y - sign * length]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x - flow, y - sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=flow + self.radius,
                                      center=(x + self.radius,
                                              y - sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [dip[0], dip[1] - sign * self.offset]

            return dip, label_location 
Example 74
Project: ble5-nrf52-mac   Author: tomasero   File: sankey.py    MIT License 4 votes vote down vote up
def _add_output(self, path, angle, flow, length):
        """
        Append an output to a path and return its tip and label locations.

        .. note:: *flow* is negative for an output.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            tipheight = (self.shoulder - flow / 2) * self.pitch
            if angle == RIGHT:
                x += length
                tip = [x + tipheight, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, [x, y + self.shoulder]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x, y - self.shoulder + flow]),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x - self.gap, y + flow])])
                label_location = [tip[0] + self.offset, tip[1]]
            else:  # Vertical
                x += self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                tip = [x - flow / 2.0, y + sign * (length + tipheight)]
                if angle == UP:
                    quadrant = 3
                else:
                    quadrant = 0
                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x - self.radius,
                                                  y + sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y + sign * length]),
                             (Path.LINETO, [x - self.shoulder,
                                            y + sign * length]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x + self.shoulder - flow,
                                            y + sign * length]),
                             (Path.LINETO, [x - flow, y + sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=self.radius - flow,
                                      center=(x - self.radius,
                                              y + sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [tip[0], tip[1] + sign * self.offset]
            return tip, label_location 
Example 75
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 4 votes vote down vote up
def transmute(self, x0, y0, width, height, mutation_size):

            # padding
            pad = mutation_size * self.pad

            # size of the roudning corner
            if self.rounding_size:
                dr = mutation_size * self.rounding_size
            else:
                dr = pad

            width, height = width + 2. * pad, \
                            height + 2. * pad,

            x0, y0 = x0 - pad, y0 - pad,
            x1, y1 = x0 + width, y0 + height

            # Round corners are implemented as quadratic bezier. e.g.,
            # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
            cp = [(x0 + dr, y0),
                  (x1 - dr, y0),
                  (x1, y0), (x1, y0 + dr),
                  (x1, y1 - dr),
                  (x1, y1), (x1 - dr, y1),
                  (x0 + dr, y1),
                  (x0, y1), (x0, y1 - dr),
                  (x0, y0 + dr),
                  (x0, y0), (x0 + dr, y0),
                  (x0 + dr, y0)]

            com = [Path.MOVETO,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.LINETO,
                   Path.CURVE3, Path.CURVE3,
                   Path.CLOSEPOLY]

            path = Path(cp, com)

            return path 
Example 76
Project: Computable   Author: ktraunmueller   File: patches.py    MIT License 4 votes vote down vote up
def connect(self, posA, posB):
            x1, y1 = posA
            x20, y20 = x2, y2 = posB

            x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2.

            theta1 = math.atan2(y2 - y1, x2 - x1)
            dx, dy = x2 - x1, y2 - y1
            dd = (dx * dx + dy * dy) ** .5
            ddx, ddy = dx / dd, dy / dd

            armA, armB = self.armA, self.armB

            if self.angle is not None:
                #angle = self.angle % 180.
                #if angle < 0. or angle > 180.:
                #    angle
                #theta0 = (self.angle%180.)/180.*math.pi
                theta0 = self.angle / 180. * math.pi
                #theta0 = (((self.angle+90)%180.)  - 90.)/180.*math.pi
                dtheta = theta1 - theta0
                dl = dd * math.sin(dtheta)

                dL = dd * math.cos(dtheta)

                #x2, y2 = x2 + dl*ddy, y2 - dl*ddx
                x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0)

                armB = armB - dl

                # update
                dx, dy = x2 - x1, y2 - y1
                dd2 = (dx * dx + dy * dy) ** .5
                ddx, ddy = dx / dd2, dy / dd2

            else:
                dl = 0.

            #if armA > armB:
            #    armB = armA + dl
            #else:
            #    armA = armB - dl

            arm = max(armA, armB)
            f = self.fraction * dd + arm
            #fB = self.fraction*dd + armB

            cx1, cy1 = x1 + f * ddy, y1 - f * ddx
            cx2, cy2 = x2 + f * ddy, y2 - f * ddx

            vertices = [(x1, y1),
                        (cx1, cy1),
                        (cx2, cy2),
                        (x20, y20)]
            codes = [Path.MOVETO,
                     Path.LINETO,
                     Path.LINETO,
                     Path.LINETO]

            return Path(vertices, codes) 
Example 77
Project: Computable   Author: ktraunmueller   File: textpath.py    MIT License 4 votes vote down vote up
def get_glyphs_mathtext(self, prop, s, glyph_map=None,
                            return_new_glyphs_only=False):
        """
        convert the string *s* to vertices and codes by parsing it with
        mathtext.
        """

        prop = prop.copy()
        prop.set_size(self.FONT_SCALE)

        width, height, descent, glyphs, rects = self.mathtext_parser.parse(
            s, self.DPI, prop)

        if not glyph_map:
            glyph_map = dict()

        if return_new_glyphs_only:
            glyph_map_new = dict()
        else:
            glyph_map_new = glyph_map

        xpositions = []
        ypositions = []
        glyph_ids = []
        sizes = []

        currx, curry = 0, 0
        for font, fontsize, ccode, ox, oy in glyphs:
            char_id = self._get_char_id(font, ccode)
            if not char_id in glyph_map:
                font.clear()
                font.set_size(self.FONT_SCALE, self.DPI)
                glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
                glyph_map_new[char_id] = self.glyph_to_path(font)

            xpositions.append(ox)
            ypositions.append(oy)
            glyph_ids.append(char_id)
            size = fontsize / self.FONT_SCALE
            sizes.append(size)

        myrects = []
        for ox, oy, w, h in rects:
            vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h),
                     (ox + w, oy), (ox, oy), (0, 0)]
            code1 = [Path.MOVETO,
                     Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
                     Path.CLOSEPOLY]
            myrects.append((vert1, code1))

        return (zip(glyph_ids, xpositions, ypositions, sizes),
                glyph_map_new, myrects) 
Example 78
Project: Computable   Author: ktraunmueller   File: sankey.py    MIT License 4 votes vote down vote up
def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
        """
        Return the codes and vertices for a rotated, scaled, and translated
        90 degree arc.

        Optional keyword arguments:

          ===============   ==========================================
          Keyword           Description
          ===============   ==========================================
          *quadrant*        uses 0-based indexing (0, 1, 2, or 3)
          *cw*              if True, clockwise
          *center*          (x, y) tuple of the arc's center
          ===============   ==========================================
        """
        # Note:  It would be possible to use matplotlib's transforms to rotate,
        # scale, and translate the arc, but since the angles are discrete,
        # it's just as easy and maybe more efficient to do it here.
        ARC_CODES = [Path.LINETO,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4,
                     Path.CURVE4]
        # Vertices of a cubic Bezier curve approximating a 90 deg arc
        # These can be determined by Path.arc(0,90).
        ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
                                 [1.00000000e+00, 2.65114773e-01],
                                 [8.94571235e-01, 5.19642327e-01],
                                 [7.07106781e-01, 7.07106781e-01],
                                 [5.19642327e-01, 8.94571235e-01],
                                 [2.65114773e-01, 1.00000000e+00],
                                 # Insignificant
                                 #[6.12303177e-17, 1.00000000e+00]])
                                 [0.00000000e+00, 1.00000000e+00]])
        if quadrant == 0 or quadrant == 2:
            if cw:
                vertices = ARC_VERTICES
            else:
                vertices = ARC_VERTICES[:, ::-1]  # Swap x and y.
        elif quadrant == 1 or quadrant == 3:
            # Negate x.
            if cw:
                # Swap x and y.
                vertices = np.column_stack((-ARC_VERTICES[:, 1],
                                             ARC_VERTICES[:, 0]))
            else:
                vertices = np.column_stack((-ARC_VERTICES[:, 0],
                                             ARC_VERTICES[:, 1]))
        if quadrant > 1:
            radius = -radius  # Rotate 180 deg.
        return zip(ARC_CODES, radius * vertices +
                              np.tile(center, (ARC_VERTICES.shape[0], 1))) 
Example 79
Project: Computable   Author: ktraunmueller   File: sankey.py    MIT License 4 votes vote down vote up
def _add_input(self, path, angle, flow, length):
        """
        Add an input to a path and return its tip and label locations.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            dipdepth = (flow / 2) * self.pitch
            if angle == RIGHT:
                x -= length
                dip = [x + dipdepth, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x + self.gap, y + flow])])
                label_location = [dip[0] - self.offset, dip[1]]
            else:  # Vertical
                x -= self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                dip = [x - flow / 2, y - sign * (length - dipdepth)]
                if angle == DOWN:
                    quadrant = 2
                else:
                    quadrant = 1

                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x + self.radius,
                                                  y - sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y - sign * length]),
                             (Path.LINETO, dip),
                             (Path.LINETO, [x - flow, y - sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=flow + self.radius,
                                      center=(x + self.radius,
                                              y - sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [dip[0], dip[1] - sign * self.offset]

            return dip, label_location 
Example 80
Project: Computable   Author: ktraunmueller   File: sankey.py    MIT License 4 votes vote down vote up
def _add_output(self, path, angle, flow, length):
        """
        Append an output to a path and return its tip and label locations.

        .. note:: *flow* is negative for an output.
        """
        if angle is None:
            return [0, 0], [0, 0]
        else:
            x, y = path[-1][1]  # Use the last point as a reference.
            tipheight = (self.shoulder - flow / 2) * self.pitch
            if angle == RIGHT:
                x += length
                tip = [x + tipheight, y + flow / 2.0]
                path.extend([(Path.LINETO, [x, y]),
                             (Path.LINETO, [x, y + self.shoulder]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x, y - self.shoulder + flow]),
                             (Path.LINETO, [x, y + flow]),
                             (Path.LINETO, [x - self.gap, y + flow])])
                label_location = [tip[0] + self.offset, tip[1]]
            else:  # Vertical
                x += self.gap
                if angle == UP:
                    sign = 1
                else:
                    sign = -1

                tip = [x - flow / 2.0, y + sign * (length + tipheight)]
                if angle == UP:
                    quadrant = 3
                else:
                    quadrant = 0
                # Inner arc isn't needed if inner radius is zero
                if self.radius:
                    path.extend(self._arc(quadrant=quadrant,
                                          cw=angle == UP,
                                          radius=self.radius,
                                          center=(x - self.radius,
                                                  y + sign * self.radius)))
                else:
                    path.append((Path.LINETO, [x, y]))
                path.extend([(Path.LINETO, [x, y + sign * length]),
                             (Path.LINETO, [x - self.shoulder,
                                            y + sign * length]),
                             (Path.LINETO, tip),
                             (Path.LINETO, [x + self.shoulder - flow,
                                            y + sign * length]),
                             (Path.LINETO, [x - flow, y + sign * length])])
                path.extend(self._arc(quadrant=quadrant,
                                      cw=angle == DOWN,
                                      radius=self.radius - flow,
                                      center=(x - self.radius,
                                              y + sign * self.radius)))
                path.append((Path.LINETO, [x - flow, y + sign * flow]))
                label_location = [tip[0], tip[1] + sign * self.offset]
            return tip, label_location