예제 #1
0
def gen_patches(node_coords, size, angles, **kwargs):
    """
    Creation function of patches for generators.

    :param node_coords: coordinates of the nodes that the generators belong to.
    :type node_coords: iterable
    :param size: size of the patch
    :type size: float
    :param angles: angles by which to rotate the patches (in radians)
    :type angles: iterable(float), float
    :param kwargs: additional keyword arguments (might contain parameters "offset",\
        "patch_edgecolor" and "patch_facecolor")
    :type kwargs:
    :return: Return values are: \
        - lines (list) - list of coordinates for lines leading to generator patches\
        - polys (list of RegularPolygon) - list containing the generator patches\
        - keywords (set) - set of keywords removed from kwargs
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    polys, lines = list(), list()
    offset = kwargs.get("offset", 2. * size)
    all_angles = get_angle_list(angles, len(node_coords))
    edgecolor = kwargs.get("patch_edgecolor", "k")
    facecolor = kwargs.get("patch_facecolor", (1, 0, 0, 0))
    edgecolors = get_color_list(edgecolor, len(node_coords))
    facecolors = get_color_list(facecolor, len(node_coords))
    for i, node_geo in enumerate(node_coords):
        p2 = node_geo + _rotate_dim2(np.array([0, size + offset]),
                                     all_angles[i])
        polys.append(Circle(p2, size, fc=facecolors[i], ec=edgecolors[i]))
        polys.append(
            Arc(p2 + np.array([-size / 6.2, -size / 2.6]),
                size / 2,
                size,
                theta1=65,
                theta2=120,
                ec=edgecolors[i]))
        polys.append(
            Arc(p2 + np.array([size / 6.2, size / 2.6]),
                size / 2,
                size,
                theta1=245,
                theta2=300,
                ec=edgecolors[i]))
        lines.append(
            (node_geo, p2 + _rotate_dim2(np.array([0, size]), -all_angles[i])))
    return lines, polys, {"offset", "patch_edgecolor", "patch_facecolor"}
예제 #2
0
def ellipse_patches(node_coords, width, height, angle=0, color=None, **kwargs):
    """
    Function to create a list of ellipse patches from node coordinates.

    :param node_coords: coordinates of the nodes to draw
    :type node_coords: iterable
    :param width: width of the ellipse (described by an exterior rectangle)
    :type width: float
    :param height: height of the ellipse (described by an exterior rectangle)
    :type height: float
    :param angle: angle by which to rotate the ellipse
    :type angle: float
    :param color: color or colors of the patches
    :type color: iterable, float
    :param kwargs: additional keyword arguments to pass to the Ellipse initialization
    :type kwargs: dict
    :return: patches - list of ellipse patches for the nodes
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    patches = list()
    angles = get_angle_list(angle, len(node_coords))
    if color is not None:
        colors = get_color_list(color, len(node_coords))
        for (x, y), col, ang in zip(node_coords, colors, angles):
            patches.append(
                Ellipse((x, y), width, height, angle=ang, color=col, **kwargs))
    else:
        for (x, y), ang in zip(node_coords, angles):
            patches.append(Ellipse((x, y), width, height, angle=ang, **kwargs))
    return patches
예제 #3
0
def valve_patches(coords, size, **kwargs):
    polys, lines = list(), list()
    edgecolor = kwargs.pop('patch_edgecolor')
    colors = get_color_list(edgecolor, len(coords))
    lw = kwargs.get("linewidths", 2.)
    filled = kwargs.pop("filled", np.full(len(coords), 0, dtype=np.bool))
    filled = get_filled_list(filled, len(coords))
    for geodata, col, filled_ind in zip(coords, colors, filled):
        p1, p2 = np.array(geodata[0]), np.array(geodata[-1])
        diff = p2 - p1
        angle = np.arctan2(*diff)
        vec_size = _rotate_dim2(np.array([0, size]), angle)
        centroid_tri1 = p1 + diff / 2 - vec_size
        centroid_tri2 = p1 + diff / 2 + vec_size
        face_col = "w" if not filled_ind else col
        polys.append(
            RegularPolygon(centroid_tri1,
                           numVertices=3,
                           radius=size,
                           orientation=-angle,
                           ec=col,
                           fc=face_col,
                           lw=lw))
        polys.append(
            RegularPolygon(centroid_tri2,
                           numVertices=3,
                           radius=size,
                           orientation=-angle + np.pi / 3,
                           ec=col,
                           fc=face_col,
                           lw=lw))
        lines.append([p1, p1 + diff / 2 - vec_size / 2 * 3])
        lines.append([p2, p1 + diff / 2 + vec_size / 2 * 3])
    return lines, polys, {"filled"}
예제 #4
0
def rectangle_patches(node_coords, width, height, color=None, **kwargs):
    """
    Function to create a list of rectangle patches from node coordinates.

    :param node_coords: coordinates of the nodes to draw
    :type node_coords: iterable
    :param width: width of the rectangle
    :type width: float
    :param height: height of the rectangle
    :type height: float
    :param color: color or colors of the patches
    :type color: iterable, float
    :param kwargs: additional keyword arguments to pass to the Rectangle initialization
    :type kwargs: dict
    :return: patches - list of rectangle patches for the nodes
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    patches = list()
    if color is not None:
        colors = get_color_list(color, len(node_coords))
        for (x, y), col in zip(node_coords, colors):
            patches.append(
                Rectangle((x - width / 2, y - height / 2),
                          width,
                          height,
                          color=color,
                          **kwargs))
    else:
        for x, y in node_coords:
            patches.append(
                Rectangle((x - width / 2, y - height / 2), width, height,
                          **kwargs))
    return patches
예제 #5
0
def heat_exchanger_patches(coords, size, **kwargs):
    polys, lines = list(), list()
    facecolor = kwargs.pop('patch_facecolor')
    colors = get_color_list(facecolor, len(coords))
    lw = kwargs.get("linewidths", 2.)
    for geodata, col in zip(coords, colors):
        p1, p2 = np.array(geodata[0]), np.array(geodata[-1])
        diff = p2 - p1
        m = 3 * size / 4
        direc = diff / np.sqrt(diff[0]**2 + diff[1]**2)
        normal = np.array([-direc[1], direc[0]])
        path1 = (p1 + diff / 2 + direc * m / 2) + normal * (size * 9 / 8)
        path2 = p1 + diff / 2 + direc * m / 2
        path3 = p1 + diff / 2 + normal * size / 3
        path4 = p1 + diff / 2 - direc * m / 2
        path5 = (p1 + diff / 2 - direc * m / 2) + normal * (size * 9 / 8)
        path = [path1, path2, path3, path4, path5]
        radius = size  #np.sqrt(diff[0]**2+diff[1]**2)/15

        pa = Path(path)
        polys.append(
            Circle(p1 + diff / 2,
                   radius=radius,
                   edgecolor=col,
                   facecolor="w",
                   lw=lw))
        polys.append(PathPatch(pa, fill=False, lw=lw, edgecolor=col))
        lines.append([p1, p1 + diff / 2 - direc * radius])
        lines.append([p2, p1 + diff / 2 + direc * radius])
    return lines, polys, {}
예제 #6
0
def pump_patches(coords, size, **kwargs):
    polys, lines = list(), list()
    edgecolor = kwargs.pop('patch_edgecolor')
    colors = get_color_list(edgecolor, len(coords))
    lw = kwargs.get("linewidths", 2.)
    for geodata, col in zip(coords, colors):
        p1, p2 = np.array(geodata[0]), np.array(geodata[-1])
        diff = p2 - p1
        angle = np.arctan2(*diff)
        vec_size = _rotate_dim2(np.array([0, size]), angle)
        line1 = _rotate_dim2(np.array([0, size * np.sqrt(2)]),
                             angle - np.pi / 4)
        line2 = _rotate_dim2(np.array([0, size * np.sqrt(2)]),
                             angle + np.pi / 4)
        radius = size

        polys.append(
            Circle(p1 + diff / 2,
                   radius=radius,
                   edgecolor=col,
                   facecolor='w',
                   lw=lw))

        lines.append(
            [p1 + diff / 2 + vec_size, p1 + diff / 2 - vec_size + line1])
        lines.append(
            [p1 + diff / 2 + vec_size, p1 + diff / 2 - vec_size + line2])

        lines.append([p1, p1 + diff / 2 - vec_size])
        lines.append([p2, p1 + diff / 2 + vec_size])
    return lines, polys, {}
예제 #7
0
def polygon_patches(node_coords, radius, num_edges, color=None, **kwargs):
    """
    Function to create a list of polygon patches from node coordinates. The number of edges for the
    polygon can be defined.

    :param node_coords: coordinates of the nodes to draw
    :type node_coords: iterable
    :param radius: radius for the polygon (from centroid to edges)
    :type radius: float
    :param num_edges: number of edges of the polygon
    :type num_edges: int
    :param color: color or colors of the patches
    :type color: iterable, float
    :param kwargs: additional keyword arguments to pass to the Polygon initialization
    :type kwargs: dict
    :return: patches - list of rectangle patches for the nodes
    """
    patches = list()
    if color is not None:
        colors = get_color_list(color, len(node_coords))
        for (x, y), col in zip(node_coords, colors):
            patches.append(
                RegularPolygon([x, y],
                               numVertices=num_edges,
                               radius=radius,
                               color=color,
                               **kwargs))
    else:
        for x, y in node_coords:
            patches.append(
                RegularPolygon([x, y],
                               numVertices=num_edges,
                               radius=radius,
                               **kwargs))
    return patches
예제 #8
0
def rectangle_patches(node_coords, width, height, color=None, **kwargs):
    """
    Function to create a list of rectangle patches from node coordinates.

    :param node_coords: coordinates of the nodes to draw
    :type node_coords: iterable
    :param width: width of the rectangle
    :type width: float
    :param height: height of the rectangle
    :type height: float
    :param color: color or colors of the patches
    :type color: iterable, float
    :param kwargs: additional keyword arguments to pass to the Rectangle initialization
    :type kwargs: dict
    :return: patches - list of rectangle patches for the nodes
    """
    patches = list()
    if color is not None:
        colors = get_color_list(color, len(node_coords))
        for (x, y), col in zip(node_coords, colors):
            patches.append(
                Rectangle((x - width / 2, y - height / 2),
                          width,
                          height,
                          color=color,
                          **kwargs))
    else:
        for x, y in node_coords:
            patches.append(
                Rectangle((x - width / 2, y - height / 2), width, height,
                          **kwargs))
    return patches
예제 #9
0
def trafo_patches(coords, size, **kwargs):
    """
    Creates a list of patches and line coordinates representing transformers each connecting two
    nodes.

    :param coords: list of connecting node coordinates (usually should be \
        `[((x11, y11), (x12, y12)), ((x21, y21), (x22, y22)), ...]`)
    :type coords: (N, (2, 2)) shaped iterable
    :param size: size of the trafo patches
    :type size: float
    :param kwargs: additional keyword arguments (might contain parameters "patch_edgecolor" and\
        "patch_facecolor")
    :type kwargs:
    :return: Return values are: \
        - lines (list) - list of coordinates for lines connecting nodes and transformer patches\
        - circles (list of Circle) - list containing the transformer patches (rings)
    """
    edgecolor = kwargs.get("patch_edgecolor", "w")
    facecolor = kwargs.get("patch_facecolor", (1, 0, 0, 0))
    edgecolors = get_color_list(edgecolor, len(coords))
    facecolors = get_color_list(facecolor, len(coords))
    linewidths = kwargs.get("linewidths", 2.)
    linewidths = get_linewidth_list(linewidths, len(coords), name_entries="trafos")
    circles, lines = list(), list()
    for i, (p1, p2) in enumerate(coords):
        p1 = np.array(p1)
        p2 = np.array(p2)
        if np.all(p1 == p2):
            continue
        d = np.sqrt(np.sum((p1 - p2) ** 2))
        if size is None:
            size_this = np.sqrt(d) / 5
        else:
            size_this = size
        off = size_this * 0.35
        circ1 = (0.5 - off / d) * (p1 - p2) + p2
        circ2 = (0.5 + off / d) * (p1 - p2) + p2
        circles.append(Circle(circ1, size_this, fc=facecolors[i], ec=edgecolors[i],
                              lw=linewidths[i]))
        circles.append(Circle(circ2, size_this, fc=facecolors[i], ec=edgecolors[i],
                              lw=linewidths[i]))

        lp1 = (0.5 - off / d - size_this / d) * (p2 - p1) + p1
        lp2 = (0.5 - off / d - size_this / d) * (p1 - p2) + p2
        lines.append([p1, lp1])
        lines.append([p2, lp2])
    return lines, circles, {"patch_edgecolor", "patch_facecolor"}
예제 #10
0
def sgen_patches(node_coords, size, angles, **kwargs):
    """
    Creation function of patches for static generators.

    :param node_coords: coordinates of the nodes that the static generators belong to.
    :type node_coords: iterable
    :param size: size of the patch
    :type size: float
    :param angles: angles by which to rotate the patches (in radians)
    :type angles: iterable(float), float
    :param kwargs: additional keyword arguments (might contain parameters "offset", "r_triangle",\
        "patch_edgecolor" and "patch_facecolor")
    :type kwargs:
    :return: Return values are: \
        - lines (list) - list of coordinates for lines leading to static generator patches\
        - polys (list of RegularPolygon) - list containing the static generator patches\
        - keywords (set) - set of keywords removed from kwargs
    """
    polys, lines = list(), list()
    offset = kwargs.get("offset", 2 * size)
    r_triangle = kwargs.get("r_triangles", size * 0.4)
    edgecolor = kwargs.get("patch_edgecolor", "w")
    facecolor = kwargs.get("patch_facecolor", "w")
    edgecolors = get_color_list(edgecolor, len(node_coords))
    facecolors = get_color_list(facecolor, len(node_coords))
    for i, node_geo in enumerate(node_coords):
        mid_circ = node_geo + _rotate_dim2(np.array([0, offset + size]), angles[i])
        circ_edge = node_geo + _rotate_dim2(np.array([0, offset]), angles[i])
        mid_tri1 = mid_circ + _rotate_dim2(np.array([r_triangle, -r_triangle / 4]), angles[i])
        mid_tri2 = mid_circ + _rotate_dim2(np.array([-r_triangle, r_triangle / 4]), angles[i])
        # dropped perpendicular foot of triangle1
        perp_foot1 = mid_tri1 + _rotate_dim2(np.array([0, -r_triangle / 2]), angles[i])
        line_end1 = perp_foot1 + + _rotate_dim2(np.array([-2.5 * r_triangle, 0]), angles[i])
        perp_foot2 = mid_tri2 + _rotate_dim2(np.array([0, r_triangle / 2]), angles[i])
        line_end2 = perp_foot2 + + _rotate_dim2(np.array([2.5 * r_triangle, 0]), angles[i])
        polys.append(Circle(mid_circ, size, fc=facecolors[i], ec=edgecolors[i]))
        polys.append(RegularPolygon(mid_tri1, numVertices=3, radius=r_triangle,
                                    orientation=-angles[i], fc=facecolors[i], ec=edgecolors[i]))
        polys.append(RegularPolygon(mid_tri2, numVertices=3, radius=r_triangle,
                                    orientation=np.pi - angles[i], fc=facecolors[i],
                                    ec=edgecolors[i]))
        lines.append((node_geo, circ_edge))
        lines.append((perp_foot1, line_end1))
        lines.append((perp_foot2, line_end2))
    return lines, polys, {"offset", "r_triangle", "patch_edgecolor", "patch_facecolor"}
예제 #11
0
def load_patches(node_coords, size, angles, **kwargs):
    """
    Creation function of patches for loads.

    :param node_coords: coordinates of the nodes that the loads belong to.
    :type node_coords: iterable
    :param size: size of the patch
    :type size: float
    :param angles: angles by which to rotate the patches (in radians)
    :type angles: iterable(float), float
    :param kwargs: additional keyword arguments (might contain parameters "offset",\
        "patch_edgecolor" and "patch_facecolor")
    :type kwargs:
    :return: Return values are: \
        - lines (list) - list of coordinates for lines leading to load patches\
        - polys (list of RegularPolygon) - list containing the load patches\
        - keywords (set) - set of keywords removed from kwargs
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    offset = kwargs.get("offset", 1.2 * size)
    all_angles = get_angle_list(angles, len(node_coords))
    edgecolor = kwargs.get("patch_edgecolor", "w")
    facecolor = kwargs.get("patch_facecolor", "w")
    edgecolors = get_color_list(edgecolor, len(node_coords))
    facecolors = get_color_list(facecolor, len(node_coords))
    polys, lines = list(), list()
    for i, node_geo in enumerate(node_coords):
        p2 = node_geo + _rotate_dim2(np.array([0, offset + size]),
                                     all_angles[i])
        p3 = node_geo + _rotate_dim2(np.array([0, offset + size / 2]),
                                     all_angles[i])
        polys.append(
            RegularPolygon(p2,
                           numVertices=3,
                           radius=size,
                           orientation=-all_angles[i],
                           fc=facecolors[i],
                           ec=edgecolors[i]))
        lines.append((node_geo, p3))
    return lines, polys, {"offset", "patch_edgecolor", "patch_facecolor"}
예제 #12
0
def source_patches(node_coords, size, angles, **kwargs):
    """
    Creation function of patches for sources.

    :param node_coords: coordinates of the nodes that the sources belong to.
    :type node_coords: iterable
    :param size: size of the patch
    :type size: float
    :param angles: angles by which to rotate the patches (in radians)
    :type angles: iterable(float), float
    :param kwargs: additional keyword arguments (might contain parameter "offset")
    :type kwargs:
    :return: Return values are: \
        - lines (list) - list of coordinates for lines leading to source patches and diagonals\
        - polys (list of RegularPolygon) - list containing the load patches\
        - keywords (set) - set of keywords removed from kwargs
    """
    offset = kwargs.get("offset", size * 2)
    all_angles = get_angle_list(angles, len(node_coords))
    facecolor = kwargs.get("patch_faceolor", "w")
    edgecolor = kwargs.get("patch_edgecolor", "k")
    facecolors = get_color_list(facecolor, len(node_coords))
    edgecolors = get_color_list(edgecolor, len(node_coords))
    polys, lines = list(), list()
    for i, node_geo in enumerate(node_coords):
        p2 = node_geo + _rotate_dim2(np.array([0, offset]), all_angles[i])
        p_edge_left = p2 + _rotate_dim2(np.array([size, size]), all_angles[i])
        p_edge_right = p2 + _rotate_dim2(np.array([-size, size]),
                                         all_angles[i])
        p_ll = p2 + _rotate_dim2(np.array([-size, 0]), all_angles[i])
        polys.append(
            Rectangle(p_ll,
                      2 * size,
                      2 * size,
                      angle=(-all_angles[i] / np.pi * 180),
                      fc=facecolors[i],
                      ec=edgecolors[i]))
        lines.append((node_geo, p2))
        lines.append((p2, p_edge_left))
        lines.append((p2, p_edge_right))
    return lines, polys, {"offset"}