예제 #1
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
예제 #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 to_excel(net, filename, include_empty_tables=False, include_results=True):
    """
    Saves a pandapower Network to an excel file.

    INPUT:
        **net** (dict) - The pandapower format network

        **filename** (string) - The absolute or relative path to the output file

    OPTIONAL:
        **include_empty_tables** (bool, False) - empty element tables are saved as excel sheet

        **include_results** (bool, True) - results are included in the excel sheet

    EXAMPLE:

        >>> pp.to_excel(net, os.path.join("C:", "example_folder", "example1.xlsx"))  # absolute path
        >>> pp.to_excel(net, "example2.xlsx")  # relative path

    """
    if not xlsxwriter_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "xlsxwriter")
    writer = pd.ExcelWriter(filename, engine='xlsxwriter')
    dict_net = io_utils.to_dict_of_dfs(
        net,
        include_results=include_results,
        include_empty_tables=include_empty_tables)
    for item, table in dict_net.items():
        table.to_excel(writer, sheet_name=item)
    writer.save()
예제 #4
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)
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    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"}
def plot_loading(net,
                 element="line",
                 boxcolor="b",
                 mediancolor="r",
                 whiskercolor="k",
                 ax=None,
                 index_subset=None):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    if ax is None:
        plt.figure(facecolor="white", dpi=80)
        ax = plt.gca()
    if index_subset is None:
        index_subset = net[element].index
    loadings = net["res_%s" % element].loading_percent.values[net[
        "res_%s" % element].index.isin(index_subset)]
    boxplot = ax.boxplot(loadings[~np.isnan(loadings)], whis=[0, 100])
    for l in list(boxplot.keys()):
        plt.setp(boxplot[l], lw=3)
        if l == "medians":
            plt.setp(boxplot[l], color=mediancolor)
        elif l == "boxes" or l == "whiskers":
            plt.setp(boxplot[l], color=boxcolor)
        else:
            plt.setp(boxplot[l], color=whiskercolor)
예제 #6
0
def get_plotly_color_palette(n):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib")
    if 'seaborn' in sys.modules:
        return _to_plotly_palette(seaborn.color_palette("hls", n))
    else:
        hsv = plt.get_cmap('hsv')
        return _to_plotly_palette(hsv(np.linspace(0, 1.0, n)))
예제 #7
0
def get_plotly_color(color_string):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib")
    try:
        converted = _to_plotly_color(mplc.to_rgba(color_string))
        return converted
    except ValueError:
        return color_string
예제 #8
0
def _branch_geometries_from_geodata(branch_geo, epsg=31467):
    missing_packages = array(["shapely", "geopandas"])[~array([
        shapely_INSTALLED, geopandas_INSTALLED])]
    if len(missing_packages):
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", missing_packages)
    geoms = GeoSeries([LineString(x) for x in branch_geo.coords.values], index=branch_geo.index,
                      crs=f"epsg:{epsg}")
    return GeoDataFrame(branch_geo, crs=f"epsg:{epsg}", geometry=geoms, index=branch_geo.index)
예제 #9
0
def plot_characteristic(characteristic, start, stop, num=20, xlabel=None, ylabel=None):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    x = np.linspace(start, stop, num)
    y = characteristic(x)
    plt.plot(x, y, marker='x')
    if xlabel is not None:
        plt.xlabel(xlabel)
    if ylabel is not None:
        plt.ylabel(ylabel)
예제 #10
0
def create_generic_coordinates(net,
                               mg=None,
                               library="igraph",
                               respect_switches=False,
                               geodata_table="bus_geodata",
                               buses=None,
                               overwrite=False):
    """
    This function will add arbitrary geo-coordinates for all buses based on an analysis of branches
    and rings. It will remove out of service buses/lines from the net. The coordinates will be
    created either by igraph or by using networkx library.

    :param net: pandapower network
    :type net: pandapowerNet
    :param mg: Existing networkx multigraph, if available. Convenience to save computation time.
    :type mg: networkx.Graph
    :param library: "igraph" to use igraph package or "networkx" to use networkx package
    :type library: str
    :param geodata_table: table to write the generic geodatas to
    :type geodata_table: str
    :param buses: buses for which generic geodata are created, all buses will be used by default
    :type buses: list
    :param overwrite: overwrite existing geodata
    :type overwrite: bool
    :return: net - pandapower network with added geo coordinates for the buses

    :Example:
        net = create_generic_coordinates(net)
    """

    _prepare_geodata_table(net, geodata_table, overwrite)
    if library == "igraph":
        if not IGRAPH_INSTALLED:
            soft_dependency_error("build_igraph_from_pp()", "python-igraph")
        graph, meshed, roots = build_igraph_from_pp(net,
                                                    respect_switches,
                                                    buses=buses)
        coords = coords_from_igraph(graph, roots, meshed)
    elif library == "networkx":
        if mg is None:
            nxg = top.create_nxgraph(net,
                                     respect_switches=respect_switches,
                                     include_out_of_service=True)
        else:
            nxg = copy.deepcopy(mg)
        coords = coords_from_nxgraph(nxg)
    else:
        raise ValueError("Unknown library %s - chose 'igraph' or 'networkx'" %
                         library)
    if len(coords):
        net[geodata_table].x = coords[1]
        net[geodata_table].y = coords[0]
        net[geodata_table].index = net.bus.index if buses is None else buses
    return net
예제 #11
0
def get_plotly_cmap(values, cmap_name='jet', cmin=None, cmax=None):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib")
    cmap = cm.get_cmap(cmap_name)
    if cmin is None:
        cmin = values.min()
    if cmax is None:
        cmax = values.max()
    norm = mplc.Normalize(vmin=cmin, vmax=cmax)
    bus_fill_colors_rgba = cmap(norm(values).data)[:, 0:3] * 255.
    return ['rgb({0},{1},{2})'.format(r, g, b) for r, g, b in bus_fill_colors_rgba]
예제 #12
0
def _to_plotly_color(scl, transparence=None):
    """
    converts a rgb color in format (0-1,0-1,0-1) to a plotly color 'rgb(0-255,0-255,0-255)'
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib")
    plotly_col = [255 * _c for _c in mplc.to_rgba(scl)] if len(scl) == 3 else [255 * _c for _c in
                                                                               mplc.to_rgb(scl)]
    if transparence is not None:
        assert 0. <= transparence <= 1.0
        plotly_col[3] = transparence
        return "rgba({:.0f}, {:.0f}, {:.0f}, {:.4f})".format(*plotly_col)
    else:
        return "rgb({:.0f}, {:.0f}, {:.0f})".format(*plotly_col[:3])
예제 #13
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"}
예제 #14
0
def _node_geometries_from_geodata(node_geo, epsg=31467):
    """
    Creates a geopandas geodataframe from a given dataframe of with node coordinates as x and y
    values.

    :param node_geo: The dataframe containing the node coordinates (x and y values)
    :type node_geo: pandas.dataframe
    :param epsg: The epsg projection of the node coordinates
    :type epsg: int, default 31467 (= Gauss-Krüger Zone 3)
    :return: node_geodata - a geodataframe containing the node_geo and Points in the geometry column
    """
    missing_packages = array(["shapely", "geopandas"])[~array([
        shapely_INSTALLED, geopandas_INSTALLED])]
    if len(missing_packages):
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", missing_packages)
    geoms = [Point(x, y) for x, y in node_geo[["x", "y"]].values]
    return GeoDataFrame(node_geo, crs=f"epsg:{epsg}", geometry=geoms, index=node_geo.index)
예제 #15
0
def decrypt_string(s, key):
    missing_packages = numpy.array([
        "cryptography", "hashlib", "base64"
    ])[~numpy.
       array([cryptography_INSTALLED, hashlib_INSTALLED, base64_INSTALLED])]
    if len(missing_packages):
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", missing_packages)
    key_base = hashlib.sha256(key.encode())
    key = base64.urlsafe_b64encode(key_base.digest())
    cipher_suite = Fernet(key)

    s = s.encode()
    s = cipher_suite.decrypt(s)
    if zlib_INSTALLED:
        s = zlib.decompress(s)
    s = s.decode()
    return s
예제 #16
0
def _to_plotly_palette(scl, transparence=None):
    """
    converts a rgb color palette in format (0-1,0-1,0-1) to a plotly color palette
    'rgb(0-255,0-255,0-255)'
    """
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "matplotlib")
    _out = []
    for color in scl:
        plotly_col = [255 * _c for _c in mplc.to_rgba(color)]
        if transparence:
            assert 0. <= transparence <= 1.0
            plotly_col[3] = transparence
            plotly_col = "rgba({:.0f}, {:.0f}, {:.0f}, {:.4f})".format(*plotly_col)
        else:
            plotly_col = "rgb({:.0f}, {:.0f}, {:.0f})".format(*plotly_col[:3])
        _out.append(plotly_col)
    return _out
예제 #17
0
def _convert_xy_epsg(x, y, epsg_in=4326, epsg_out=31467):
    """
    Converts the given x and y coordinates according to the defined epsg projections.

    :param x: x-values of coordinates
    :type x: iterable
    :param y: y-values of coordinates
    :type y: iterable
    :param epsg_in: current epsg projection
    :type epsg_in: int, default 4326 (= WGS84)
    :param epsg_out: epsg projection to be transformed to
    :type epsg_out: int, default 31467 (= Gauss-Krüger Zone 3)
    :return: transformed_coords - x and y values in new coordinate system
    """
    if not pyproj_INSTALLED:
        soft_dependency_error(str(sys._getframe().f_code.co_name)+"()", "pyproj")
    in_proj = Proj(init='epsg:%i' % epsg_in)
    out_proj = Proj(init='epsg:%i' % epsg_out)
    return transform(in_proj, out_proj, x, y)
예제 #18
0
def from_excel(filename, convert=True):
    """
    Load a pandapower network from an excel file

    INPUT:
        **filename** (string) - The absolute or relative path to the input file.

        **convert** (bool, True) - If True, converts the format of the net loaded from excel from
            the older version of pandapower to the newer version format

    OUTPUT:
        **net** (dict) - The pandapower format network

    EXAMPLE:

        >>> net1 = pp.from_excel(os.path.join("C:", "example_folder", "example1.xlsx"))
        >>> net2 = pp.from_excel("example2.xlsx") #relative path

    """

    if not os.path.isfile(filename):
        raise UserWarning("File %s does not exist!" % filename)
    pd_version = version.parse(pd.__version__)
    if pd_version < version.parse("0.21"):
        xls = pd.ExcelFile(filename).parse(sheetname=None)
    elif pd_version < version.parse("0.24"):
        xls = pd.ExcelFile(filename).parse(sheet_name=None)
    else:
        if not openpyxl_INSTALLED:
            soft_dependency_error(
                str(sys._getframe().f_code.co_name) + "()", "openpyxl")
        xls = pd.read_excel(filename,
                            sheet_name=None,
                            index_col=0,
                            engine="openpyxl")

    try:
        net = io_utils.from_dict_of_dfs(xls)
    except:
        net = _from_excel_old(xls)
    if convert:
        convert_format(net)
    return net
예제 #19
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"}
예제 #20
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
    """
    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(
                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
def plot_voltage_profile(net,
                         plot_transformers=True,
                         ax=None,
                         xlabel="Distance from Slack [km]",
                         ylabel="Voltage [pu]",
                         x0=0,
                         trafocolor="r",
                         bus_colors=None,
                         line_loading_weight=False,
                         voltage_column=None,
                         bus_size=3,
                         lines=None,
                         **kwargs):
    if not MATPLOTLIB_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "matplotlib")
    if ax is None:
        plt.figure(facecolor="white", dpi=120)
        ax = plt.gca()
    if not net.converged:
        raise ValueError("no results in this pandapower network")
    if voltage_column is None:
        voltage_column = net.res_bus.vm_pu
    if lines is None:
        lines = net.line.index
    for eg in net.ext_grid[net.ext_grid.in_service == True].bus:
        d = top.calc_distance_to_bus(net, eg)
        for lix, line in net.line[(net.line.in_service == True)
                                  & net.line.index.isin(lines)].iterrows():
            if line.from_bus not in d.index:
                continue
            if not ((net.switch.element == line.name) & ~net.switch.closed &
                    (net.switch.et == 'l')).any():
                from_bus = line.from_bus
                to_bus = line.to_bus
                x = [x0 + d.at[from_bus], x0 + d.at[to_bus]]
                try:
                    y = [
                        voltage_column.at[from_bus], voltage_column.at[to_bus]
                    ]
                except:
                    raise UserWarning
                if "linewidth" in kwargs or not line_loading_weight:
                    ax.plot(x, y, **kwargs)
                else:
                    ax.plot(x,
                            y,
                            linewidth=0.4 *
                            np.sqrt(net.res_line.loading_percent.at[lix]),
                            **kwargs)
                if bus_colors is not None:
                    for bus, x, y in zip((from_bus, to_bus), x, y):
                        if bus in bus_colors:
                            ax.plot(x,
                                    y,
                                    'or',
                                    color=bus_colors[bus],
                                    ms=bus_size)
                kwargs = {k: v for k, v in kwargs.items() if not k == "label"}
        # if plot_transformers:
        #     if hasattr(plot_transformers, "__iter__"):  # if is a list for example
        #         transformers = net.trafo.loc[list(plot_transformers)]
        #     else:
        #         transformers = net.trafo[net.trafo.in_service == True]
        #     for _, transformer in transformers.iterrows():
        #         if transformer.hv_bus not in d.index:
        #             continue
        #         ax.plot([x0 + d.loc[transformer.hv_bus],
        #                  x0 + d.loc[transformer.lv_bus]],
        #                 [voltage_column.loc[transformer.hv_bus],
        #                  voltage_column.loc[transformer.lv_bus]], color=trafocolor,
        #                 **{k: v for k, v in kwargs.items() if not k == "color"})

        # trafo geodata
        if plot_transformers:
            for trafo_table in ['trafo', 'trafo3w']:
                if trafo_table not in net.keys():
                    continue
                transformers = net[trafo_table].query('in_service')
                for tid, tr in transformers.iterrows():
                    t_buses = [
                        tr[b_col] for b_col in ('lv_bus', 'mv_bus', 'hv_bus')
                        if b_col in tr.index
                    ]
                    if any([
                            b not in d.index.values
                            or b not in net.res_bus.index.values
                            for b in t_buses
                    ]):
                        # logger.info('cannot add trafo %d to plot' % tid)
                        continue

                    for bi, bj in combinations(t_buses, 2):
                        tr_coords = ([x0 + d.loc[bi], x0 + d.loc[bj]], [
                            net.res_bus.at[bi, 'vm_pu'],
                            net.res_bus.at[bj, 'vm_pu']
                        ])
                        ax.plot(*tr_coords,
                                color=trafocolor,
                                **{
                                    k: v
                                    for k, v in kwargs.items()
                                    if not k == "color"
                                })

        if xlabel:
            ax.set_xlabel(xlabel, fontweight="bold", color=(.4, .4, .4))
        if ylabel:
            ax.set_ylabel(ylabel, fontweight="bold", color=(.4, .4, .4))
    return ax
예제 #22
0
def build_igraph_from_pp(net, respect_switches=False, buses=None):
    """
    This function uses the igraph library to create an igraph graph for a given pandapower network.
    Lines, transformers and switches are respected.
    Performance vs. networkx: https://graph-tool.skewed.de/performance

    :param net: pandapower network
    :type net: pandapowerNet
    :param respect_switches: if True, exclude edges for open switches (also lines that are \
        connected via line switches)
    :type respect_switches: bool, default False

    :Example:
        graph, meshed, roots = build_igraph_from_pp(net)
    """
    if not IGRAPH_INSTALLED:
        soft_dependency_error(
            str(sys._getframe().f_code.co_name) + "()", "python-igraph")
    g = igraph.Graph(directed=True)
    bus_index = net.bus.index if buses is None else np.array(buses)
    nr_buses = len(bus_index)
    g.add_vertices(nr_buses)
    # g.vs["label"] = [s.encode('unicode-escape') for s in net.bus.name.tolist()]
    g.vs["label"] = list(bus_index)
    pp_bus_mapping = dict(list(zip(bus_index, list(range(nr_buses)))))
    if respect_switches:
        open_switches = ~net.switch.closed.values.astype(bool)
    # add lines
    mask = _get_element_mask_from_nodes(net, "line", ["from_bus", "to_bus"],
                                        buses)
    if respect_switches:
        mask &= _get_switch_mask(net, "line", "l", open_switches)
    for line in net.line[mask].itertuples():
        g.add_edge(pp_bus_mapping[line.from_bus],
                   pp_bus_mapping[line.to_bus],
                   weight=line.length_km)

    # add trafos
    mask = _get_element_mask_from_nodes(net, "trafo", ["hv_bus", "lv_bus"],
                                        buses)
    if respect_switches:
        mask &= _get_switch_mask(net, "trafo", "t", open_switches)
    for trafo in net.trafo[mask].itertuples():
        g.add_edge(pp_bus_mapping[trafo.hv_bus],
                   pp_bus_mapping[trafo.lv_bus],
                   weight=0.01)

    # add trafo3w
    mask = _get_element_mask_from_nodes(net, "trafo3w",
                                        ["hv_bus", "mv_bus", "lv_bus"], buses)
    if respect_switches:
        mask &= _get_switch_mask(net, "trafo3w", "t3", open_switches)
    for trafo3w in net.trafo3w[mask].itertuples():
        g.add_edge(pp_bus_mapping[trafo3w.hv_bus],
                   pp_bus_mapping[trafo3w.lv_bus],
                   weight=0.01)
        g.add_edge(pp_bus_mapping[trafo3w.hv_bus],
                   pp_bus_mapping[trafo3w.mv_bus],
                   weight=0.01)

    # add switches
    mask = net.switch.et.values == "b"
    if respect_switches:
        mask &= ~open_switches
    bus_mask = _get_element_mask_from_nodes(net, "switch", ["element", "bus"],
                                            buses)
    for switch in net.switch[mask & bus_mask].itertuples():
        g.add_edge(pp_bus_mapping[switch.element],
                   pp_bus_mapping[switch.bus],
                   weight=0.001)

    meshed = _igraph_meshed(g)

    roots = [
        pp_bus_mapping[b] for b in net.ext_grid.bus.values if b in bus_index
    ]
    return g, meshed, roots  # g, (not g.is_dag())
예제 #23
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
    """
    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)
    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"
    }