def test_create_generic_coordinates_igraph_custom_table_index():
    net = nw.simple_four_bus_system()
    for buses in [[0, 1], [0, 2], [0, 1, 2]]:
        create_generic_coordinates(net,
                                   buses=buses,
                                   geodata_table="test",
                                   overwrite=True)
        assert np.all(net.test.index == buses)
Esempio n. 2
0
def pf_res_plotly(net, cmap="Jet", use_line_geodata=None, on_map=False, projection=None,
                  map_style='basic', figsize=1, aspectratio='auto', line_width=2, bus_size=10,
                  climits_volt=(0.9, 1.1), climits_load=(0, 100), cpos_volt=1.0, cpos_load=1.1,
                  filename="temp-plot.html", auto_open=True):
    """
        Plots a pandapower network in plotly

        using colormap for coloring lines according to line loading and buses according to voltage in p.u.
        If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial

        INPUT:
            **net** - The pandapower format network. If none is provided, mv_oberrhein() will be plotted as an example

        OPTIONAL:
            **respect_switches** (bool, False) - Respect switches when artificial geodata is created

            **cmap** (str, True) - name of the colormap

            **colors_dict** (dict, None) - by default 6 basic colors from default collor palette is used.
                                                Otherwise, user can define a dictionary in the form: voltage_kv : color

            **on_map** (bool, False) - enables using mapbox plot in plotly. If provided geodata are not
                                                    real geo-coordinates in lon/lat form, on_map will be set to False.

            **projection** (String, None) - defines a projection from which network geo-data will be transformed to
                                            lat-long. For each projection a string can be found at http://spatialreference.org/ref/epsg/

            **map_style** (str, 'basic') - enables using mapbox plot in plotly

            - 'streets'
            - 'bright'
            - 'light'
            - 'dark'
            - 'satellite'

            **figsize** (float, 1) - aspectratio is multiplied by it in order to get final image size

            **aspectratio** (tuple, 'auto') - when 'auto' it preserves original aspect ratio of the network geodata
                                                    any custom aspectration can be given as a tuple, e.g. (1.2, 1)

            **line_width** (float, 1.0) - width of lines

            **bus_size** (float, 10.0) -  size of buses to plot.

            **climits_volt** (tuple, (0.9, 1.0)) - limits of the colorbar for voltage

            **climits_load** (tuple, (0, 100)) - limits of the colorbar for line_loading

            **cpos_volt** (float, 1.0) - position of the bus voltage colorbar

            **cpos_load** (float, 1.1) - position of the loading percent colorbar

            **filename** (str, "temp-plot.html") - filename / path to plot to. Should end on `*.html`

            **auto_open** (bool, True) - automatically open plot in browser

        OUTPUT:
            **figure** (graph_objs._figure.Figure) figure object

    """

    version_check()
    if 'res_bus' not in net or net.get('res_bus').shape[0] == 0:
        logger.warning('There are no Power Flow results. A Newton-Raphson power flow will be executed.')
        runpp(net)

    # create geocoord if none are available
    if 'line_geodata' not in net:
        net.line_geodata = pd.DataFrame(columns=['coords'])
    if 'bus_geodata' not in net:
        net.bus_geodata = pd.DataFrame(columns=["x", "y"])
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
                       " This may take some time")
        create_generic_coordinates(net, respect_switches=True)
        if on_map:
            logger.warning("Map plots not available with artificial coordinates and will be disabled!")
            on_map = False
    for geo_type in ["bus_geodata", "line_geodata"]:
        dupl_geo_idx = pd.Series(net[geo_type].index)[pd.Series(
                net[geo_type].index).duplicated()]
        if len(dupl_geo_idx):
            if len(dupl_geo_idx) > 20:
                logger.warning("In net.%s are %i duplicated " % (geo_type, len(dupl_geo_idx)) +
                               "indices. That can cause troubles for draw_traces()")
            else:
                logger.warning("In net.%s are the following duplicated " % geo_type +
                               "indices. That can cause troubles for draw_traces(): " + str(
                               dupl_geo_idx))


    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
        geo_data_to_latlong(net, projection=projection)

    # ----- Buses ------
    # initializating bus trace
    # hoverinfo which contains name and pf results
    precision = 3
    hoverinfo = (
            net.bus.name.astype(str) + '<br />' +
            'V_m = ' + net.res_bus.vm_pu.round(precision).astype(str) + ' pu' + '<br />' +
            'V_m = ' + (net.res_bus.vm_pu * net.bus.vn_kv.round(2)).round(precision).astype(str) + ' kV' + '<br />' +
            'V_a = ' + net.res_bus.va_degree.round(precision).astype(str) + ' deg').tolist()
    hoverinfo = pd.Series(index=net.bus.index, data=hoverinfo)
    bus_trace = create_bus_trace(net, net.bus.index, size=bus_size, infofunc=hoverinfo, cmap=cmap,
                                 cbar_title='Bus Voltage [pu]', cmin=climits_volt[0], cmax=climits_volt[1],
                                 cpos=cpos_volt)

    # ----- Lines ------
    # if bus geodata is available, but no line geodata
    # if bus geodata is available, but no line geodata
    cmap_lines = 'jet' if cmap == 'Jet' else cmap
    if use_line_geodata is None:
        use_line_geodata = False if len(net.line_geodata) == 0 else True
    elif use_line_geodata and len(net.line_geodata) == 0:
        logger.warning("No or insufficient line geodata available --> only bus geodata will be used.")
        use_line_geodata = False
    # hoverinfo which contains name and pf results
    hoverinfo = (
            net.line.name.astype(str) + '<br />' +
            'I = ' + net.res_line.loading_percent.round(precision).astype(str) + ' %' + '<br />' +
            'I_from = ' + net.res_line.i_from_ka.round(precision).astype(str) + ' kA' + '<br />' +
            'I_to = ' + net.res_line.i_to_ka.round(precision).astype(str) + ' kA' + '<br />').tolist()
    hoverinfo = pd.Series(index=net.line.index, data=hoverinfo)
    line_traces = create_line_trace(net, use_line_geodata=use_line_geodata, respect_switches=True,
                                    width=line_width,
                                    infofunc=hoverinfo,
                                    cmap=cmap_lines,
                                    cmap_vals=net.res_line['loading_percent'].values,
                                    cmin=climits_load[0],
                                    cmax=climits_load[1],
                                    cbar_title='Line Loading [%]',
                                    cpos=cpos_load)

    # ----- Trafos ------
    # hoverinfo which contains name and pf results
    hoverinfo = (
            net.trafo.name.astype(str) + '<br />' +
            'I = ' + net.res_trafo.loading_percent.round(precision).astype(str) + ' %' + '<br />' +
            'I_hv = ' + net.res_trafo.i_hv_ka.round(precision).astype(str) + ' kA' + '<br />' +
            'I_lv = ' + net.res_trafo.i_lv_ka.round(precision).astype(str) + ' kA' + '<br />').tolist()
    hoverinfo = pd.Series(index=net.trafo.index, data=hoverinfo)
    trafo_traces = create_trafo_trace(net, width=line_width * 1.5, infofunc=hoverinfo,
                                      cmap=cmap_lines, cmin=0, cmax=100)

    # ----- Ext grid ------
    # get external grid from create_bus_trace
    marker_type = 'circle' if on_map else 'square'
    ext_grid_trace = create_bus_trace(net, buses=net.ext_grid.bus,
                                      color='grey', size=bus_size * 2, trace_name='external_grid',
                                      patch_type=marker_type)

    return draw_traces(line_traces + trafo_traces + ext_grid_trace + bus_trace,
                       showlegend=False, aspectratio=aspectratio, on_map=on_map,
                       map_style=map_style, figsize=figsize, filename=filename, auto_open=auto_open)
Esempio n. 3
0
def simple_plot(net,
                respect_switches=False,
                line_width=1.0,
                bus_size=1.0,
                ext_grid_size=1.0,
                scale_size=True,
                bus_color="b",
                line_color='grey',
                trafo_color='k',
                ext_grid_color='y',
                library="igraph"):
    """
    Plots a pandapower network as simple as possible. If no geodata is available, artificial
    geodata is generated. For advanced plotting see the tutorial

    INPUT:
        **net** - The pandapower format network.

    OPTIONAL:
        **respect_switches** (bool, False) - Respect switches if artificial geodata is created

        **line_width** (float, 1.0) - width of lines

        **bus_size** (float, 1.0) - Relative size of buses to plot.

            The value bus_size is multiplied with mean_distance_between_buses, which equals the
            distance between
            the max geoocord and the min divided by 200.
            mean_distance_between_buses = sum((net['bus_geodata'].max()
                                          - net['bus_geodata'].min()) / 200)

        **ext_grid_size** (float, 1.0) - Relative size of ext_grids to plot.

            See bus sizes for details. Note: ext_grids are plottet as rectangles

        **scale_size** (bool, True) - Flag if bus_size and ext_grid_size will be scaled with
        respect to grid mean distances

        **bus_color** (String, colors[0]) - Bus Color. Init as first value of color palette.
        Usually colors[0] = "b".

        **line_color** (String, 'grey') - Line Color. Init is grey

        **trafo_color** (String, 'k') - Trafo Color. Init is black

        **ext_grid_color** (String, 'y') - External Grid Color. Init is yellow
    """
    # create geocoord if none are available
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning(
            "No or insufficient geodata available --> Creating artificial coordinates."
            + " This may take some time")
        create_generic_coordinates(net,
                                   respect_switches=respect_switches,
                                   library=library)

    if scale_size:
        # if scale_size -> calc size from distance between min and max geocoord
        mean_distance_between_buses = sum(
            (net['bus_geodata'].max() - net['bus_geodata'].min()) / 200)
        # set the bus / ext_grid sizes accordingly
        # Comment: This is implemented because if you would choose a fixed values
        # (e.g. bus_size = 0.2), the size
        # could be to small for large networks and vice versa
        bus_size *= mean_distance_between_buses
        ext_grid_size *= mean_distance_between_buses * 1.5

    # create bus collections ti plot
    bc = create_bus_collection(net,
                               net.bus.index,
                               size=bus_size,
                               color=bus_color,
                               zorder=10)

    # if bus geodata is available, but no line geodata
    use_bus_geodata = len(net.line_geodata) == 0
    in_service_lines = net.line[net.line.in_service].index
    nogolines = set(net.switch.element[(net.switch.et == "l") & (net.switch.closed == 0)]) \
        if respect_switches else set()
    plot_lines = in_service_lines.difference(nogolines)

    lc = create_line_collection(net,
                                plot_lines,
                                color=line_color,
                                linewidths=line_width,
                                use_bus_geodata=use_bus_geodata)
    collections = [bc, lc]
    eg_buses_with_geo_coordinates = set(net.ext_grid.bus.values) & set(
        net.bus_geodata.index)
    if len(eg_buses_with_geo_coordinates) > 0:
        sc = create_bus_collection(net,
                                   eg_buses_with_geo_coordinates,
                                   patch_type="rect",
                                   size=ext_grid_size,
                                   color=ext_grid_color,
                                   zorder=11)
        collections.append(sc)
    # create trafo collection if trafo is available

    trafo_buses_with_geo_coordinates = [
        t for t, trafo in net.trafo.iterrows()
        if trafo.hv_bus in net.bus_geodata.index
        and trafo.lv_bus in net.bus_geodata.index
    ]
    if len(trafo_buses_with_geo_coordinates) > 0:
        tc = create_trafo_symbol_collection(net,
                                            trafo_buses_with_geo_coordinates,
                                            color=trafo_color)
        collections.append(tc[0])
        collections.append(tc[1])

    draw_collections(collections)
    plt.show()
Esempio n. 4
0
def simple_plot(net, respect_switches=False, line_width=1.0, bus_size=1.0, ext_grid_size=1.0,
                trafo_size=1.0, plot_loads=False, plot_sgens=False, load_size=1.0, sgen_size=1.0,
                switch_size=2.0, switch_distance=1.0, plot_line_switches=False, scale_size=True,
                bus_color="b", line_color='grey', trafo_color='k', ext_grid_color='y',
                switch_color='k', library="igraph", show_plot=True, ax=None):
    """
    Plots a pandapower network as simple as possible. If no geodata is available, artificial
    geodata is generated. For advanced plotting see the tutorial

    INPUT:
        **net** - The pandapower format network.

    OPTIONAL:
        **respect_switches** (bool, False) - Respect switches if artificial geodata is created.

                                            .. note::
                                                This Flag is ignored if plot_line_switches is True

        **line_width** (float, 1.0) - width of lines

        **bus_size** (float, 1.0) - Relative size of buses to plot.

            The value bus_size is multiplied with mean_distance_between_buses, which equals the
            distance between
            the max geoocord and the min divided by 200.
            mean_distance_between_buses = sum((net['bus_geodata'].max()
                                          - net['bus_geodata'].min()) / 200)

        **ext_grid_size** (float, 1.0) - Relative size of ext_grids to plot.

            See bus sizes for details. Note: ext_grids are plottet as rectangles

        **trafo_size** (float, 1.0) - Relative size of trafos to plot.

        **plot_loads** (bool, False) - Flag to decide whether load symbols should be drawn.

        **plot_sgens** (bool, False) - Flag to decide whether sgen symbols should be drawn.

        **load_size** (float, 1.0) - Relative size of loads to plot.

        **sgen_size** (float, 1.0) - Relative size of sgens to plot.

        **switch_size** (float, 2.0) - Relative size of switches to plot. See bus size for details

        **switch_distance** (float, 1.0) - Relative distance of the switch to its corresponding \
                                           bus. See bus size for details

        **plot_line_switches** (bool, False) - Flag if line switches are plotted

        **scale_size** (bool, True) - Flag if bus_size, ext_grid_size, bus_size- and distance \
                                      will be scaled with respect to grid mean distances

        **bus_color** (String, colors[0]) - Bus Color. Init as first value of color palette.
        Usually colors[0] = "b".

        **line_color** (String, 'grey') - Line Color. Init is grey

        **trafo_color** (String, 'k') - Trafo Color. Init is black

        **ext_grid_color** (String, 'y') - External Grid Color. Init is yellow

        **switch_color** (String, 'k') - Switch Color. Init is black

        **library** (String, "igraph") - library name to create generic coordinates (case of
            missing geodata). "igraph" to use igraph package or "networkx" to use networkx package.

        **show_plot** (bool, True) - Shows plot at the end of plotting

		**ax** (object, None) - matplotlib axis to plot to

    OUTPUT:
        **ax** - axes of figure
    """
    # don't hide lines if switches are plotted
    if plot_line_switches:
        respect_switches = False

    # create geocoord if none are available
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
                       " This may take some time")
        create_generic_coordinates(net, respect_switches=respect_switches, library=library)

    if scale_size:
        # if scale_size -> calc size from distance between min and max geocoord
        sizes = get_collection_sizes(net, bus_size, ext_grid_size, switch_size,
                                     switch_distance, load_size, sgen_size, trafo_size)
        bus_size = sizes["bus"]
        ext_grid_size = sizes["ext_grid"]
        trafo_size = sizes["trafo"]
        sgen_size = sizes["sgen"]
        load_size = sizes["load"]
        switch_size = sizes["switch"]
        switch_distance = sizes["switch_distance"]

    # create bus collections to plot
    bc = create_bus_collection(net, net.bus.index, size=bus_size, color=bus_color, zorder=10)

    # if bus geodata is available, but no line geodata
    use_bus_geodata = len(net.line_geodata) == 0
    in_service_lines = net.line[net.line.in_service].index
    nogolines = set(net.switch.element[(net.switch.et == "l") & (net.switch.closed == 0)]) \
        if respect_switches else set()
    plot_lines = in_service_lines.difference(nogolines)

    # create line collections
    lc = create_line_collection(net, plot_lines, color=line_color, linewidths=line_width,
                                use_bus_geodata=use_bus_geodata)
    collections = [bc, lc]

    # create ext_grid collections
    eg_buses_with_geo_coordinates = set(net.ext_grid.bus.values) & set(net.bus_geodata.index)
    if len(eg_buses_with_geo_coordinates) > 0:
        sc = create_bus_collection(net, eg_buses_with_geo_coordinates, patch_type="rect",
                                   size=ext_grid_size, color=ext_grid_color, zorder=11)
        collections.append(sc)

    # create trafo collection if trafo is available
    trafo_buses_with_geo_coordinates = [t for t, trafo in net.trafo.iterrows()
                                        if trafo.hv_bus in net.bus_geodata.index and
                                        trafo.lv_bus in net.bus_geodata.index]
    if len(trafo_buses_with_geo_coordinates) > 0:
        tc = create_trafo_collection(net, trafo_buses_with_geo_coordinates,
                                     color=trafo_color, size=trafo_size)
        collections.append(tc)

    # create trafo3w collection if trafo3w is available
    trafo3w_buses_with_geo_coordinates = [
        t for t, trafo3w in net.trafo3w.iterrows() if trafo3w.hv_bus in net.bus_geodata.index and
                                                      trafo3w.mv_bus in net.bus_geodata.index and trafo3w.lv_bus in net.bus_geodata.index]
    if len(trafo3w_buses_with_geo_coordinates) > 0:
        tc = create_trafo3w_collection(net, trafo3w_buses_with_geo_coordinates,
                                       color=trafo_color)
        collections.append(tc)

    if plot_line_switches and len(net.switch):
        sc = create_line_switch_collection(
            net, size=switch_size, distance_to_bus=switch_distance,
            use_line_geodata=not use_bus_geodata, zorder=12, color=switch_color)
        collections.append(sc)

    if plot_sgens and len(net.sgen):
        sgc = create_sgen_collection(net, size=sgen_size)
        collections.append(sgc)
    if plot_loads and len(net.load):
        lc = create_load_collection(net, size=load_size)
        collections.append(lc)

    if len(net.switch):
        bsc = create_bus_bus_switch_collection(net, size=switch_size)
        collections.append(bsc)

    ax = draw_collections(collections, ax=ax)
    if show_plot:
        plt.show()
    return ax
Esempio n. 5
0
def pf_res_plotly(net, cmap='Jet', use_line_geodata = None, on_map=False, projection=None,
                  map_style='basic', figsize=1, aspectratio='auto', line_width=2, bus_size=10):
    """
    Plots a pandapower network in plotly
    using colormap for coloring lines according to line loading and buses according to voltage in p.u.
    If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial

    INPUT:
        **net** - The pandapower format network. If none is provided, mv_oberrhein() will be
        plotted as an example

    OPTIONAL:
        **respect_switches** (bool, False) - Respect switches when artificial geodata is created

        *cmap** (str, True) - name of the colormap

        *colors_dict** (dict, None) - by default 6 basic colors from default collor palette is used.
        Otherwise, user can define a dictionary in the form: voltage_kv : color

        **on_map** (bool, False) - enables using mapbox plot in plotly
        If provided geodata are not real geo-coordinates in lon/lat form, on_map will be set to False.

        **projection** (String, None) - defines a projection from which network geo-data will be transformed to 
        lat-long. For each projection a string can be found at http://spatialreference.org/ref/epsg/

        **map_style** (str, 'basic') - enables using mapbox plot in plotly
        
            - 'streets'
            - 'bright'
            - 'light'
            - 'dark'
            - 'satellite'

        **figsize** (float, 1) - aspectratio is multiplied by it in order to get final image size

        **aspectratio** (tuple, 'auto') - when 'auto' it preserves original aspect ratio of the network geodata
        any custom aspectration can be given as a tuple, e.g. (1.2, 1)

        **line_width** (float, 1.0) - width of lines

        **bus_size** (float, 10.0) -  size of buses to plot.

    """


    if 'res_bus' not in net or net.get('res_bus').shape[0] == 0:
        logger.warning('There are no Power Flow results. A Newton-Raphson power flow will be executed.')
        runpp(net)

    # create geocoord if none are available
    if 'line_geodata' not in net:
        net.line_geodata = pd.DataFrame(columns=['coords'])
    if 'bus_geodata' not in net:
        net.bus_geodata = pd.DataFrame(columns=["x", "y"])
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
                       " This may take some time")
        create_generic_coordinates(net, respect_switches=True)
        if on_map == True:
            logger.warning("Map plots not available with artificial coordinates and will be disabled!")
            on_map = False

    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
            geo_data_to_latlong(net, projection=projection)

    # ----- Buses ------
    # initializating bus trace
    idx = net.line.index
    # hoverinfo which contains name and pf results
    hoverinfo = (net.bus['name'] + '<br>' +
                 'U = ' + net.res_bus.loc[idx, 'vm_pu'].astype(str) + ' pu' + '<br>' +
                 'U = ' + (net.res_bus.loc[idx, 'vm_pu'] * net.bus.vn_kv).astype(str) + ' kV' + '<br>' +
                 'ang = ' + net.res_bus.loc[idx, 'va_degree'].astype(str) + ' deg'
                 ).tolist()
    bus_trace = create_bus_trace(net, net.bus.index, size=bus_size, infofunc=hoverinfo, cmap=cmap,
                                 cbar_title='Bus Voltage [pu]', cmin=0.9, cmax=1.1)

    # ----- Lines ------
    # if bus geodata is available, but no line geodata
    # if bus geodata is available, but no line geodata
    cmap_lines = 'jet' if cmap is 'Jet' else cmap
    if use_line_geodata is None:
        use_line_geodata = False if len(net.line_geodata) == 0 else True
    elif use_line_geodata and len(net.line_geodata) == 0:
        logger.warning("No or insufficient line geodata available --> only bus geodata will be used.")
        use_line_geodata = False
    idx = net.line.index
    # hoverinfo which contains name and pf results
    hoverinfo = (net.line['name'] + '<br>' +
                 'I = ' + net.res_line.loc[idx, 'loading_percent'].astype(str) + ' %' + '<br>' +
                 'I_from = ' + net.res_line.loc[idx, 'i_from_ka'].astype(str) + ' kA' + '<br>' +
                 'I_to = ' + net.res_line.loc[idx, 'i_to_ka'].astype(str) + ' kA' + '<br>'
                 ).tolist()
    line_traces = []
    line_traces = create_line_trace(net, use_line_geodata=use_line_geodata, respect_switches=True,
                                    width=line_width,
                                    infofunc=hoverinfo,
                                    cmap=cmap_lines,
                                    cmap_vals=net.res_line.loc[:, 'loading_percent'].values,
                                    cmin=0,
                                    cmax=100,
                                    cbar_title='Line Loading [%]')

    # ----- Trafos ------
    idx = net.trafo.index
    # hoverinfo which contains name and pf results
    hoverinfo = (net.trafo['name'] + '<br>' +
                 'I = ' + net.res_trafo.loc[idx, 'loading_percent'].astype(str) + ' %' + '<br>' +
                 'I_hv = ' + net.res_trafo.loc[idx, 'i_hv_ka'].astype(str) + ' kA' + '<br>'  +
                 'I_lv = ' + net.res_trafo.loc[idx, 'i_lv_ka'].astype(str) + ' kA' + '<br>'
                 ).tolist()
    trafo_traces = create_trafo_trace(net, width=line_width * 1.5, infofunc=hoverinfo,
                                      cmap=cmap_lines, cmin=0, cmax=100)

    # ----- Ext grid ------
    # get external grid from create_bus_trace
    marker_type = 'circle' if on_map else 'square'
    ext_grid_trace = create_bus_trace(net, buses=net.ext_grid.bus,
                                      color='grey', size=bus_size * 2, trace_name='external_grid',
                                      patch_type=marker_type)

    draw_traces(line_traces + trafo_traces + ext_grid_trace + bus_trace,
                showlegend=False, aspectratio=aspectratio, on_map=on_map, map_style=map_style, figsize=figsize)
Esempio n. 6
0
def simple_plotly(net,
                  respect_switches=True,
                  use_line_geodata=None,
                  on_map=False,
                  projection=None,
                  map_style='basic',
                  figsize=1,
                  aspectratio='auto',
                  line_width=1,
                  bus_size=10,
                  ext_grid_size=20.0,
                  bus_color="blue",
                  line_color='grey',
                  trafo_color='green',
                  ext_grid_color="yellow"):
    """
    Plots a pandapower network as simple as possible in plotly.
    If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial

    INPUT:
        **net** - The pandapower format network. If none is provided, mv_oberrhein() will be
            plotted as an example

    OPTIONAL:
        **respect_switches** (bool, True) - Respect switches when artificial geodata is created

        *use_line_geodata** (bool, True) - defines if lines patches are based on net.line_geodata of the lines (True)
            or on net.bus_geodata of the connected buses (False)

        **on_map** (bool, False) - enables using mapbox plot in plotly.
            If provided geodata are not real geo-coordinates in lon/lat form, on_map will be set to False.

        **projection** (String, None) - defines a projection from which network geo-data will be transformed to
            lat-long. For each projection a string can be found at http://spatialreference.org/ref/epsg/


        **map_style** (str, 'basic') - enables using mapbox plot in plotly

            - 'streets'
            - 'bright'
            - 'light'
            - 'dark'
            - 'satellite'

        **figsize** (float, 1) - aspectratio is multiplied by it in order to get final image size

        **aspectratio** (tuple, 'auto') - when 'auto' it preserves original aspect ratio of the network geodata;
            any custom aspectration can be given as a tuple, e.g. (1.2, 1)

        **line_width** (float, 1.0) - width of lines

        **bus_size** (float, 10.0) -  size of buses to plot.

        **ext_grid_size** (float, 20.0) - size of ext_grids to plot.

            See bus sizes for details. Note: ext_grids are plotted as rectangles

        **bus_color** (String, "blue") - Bus Color. Init as first value of color palette.

        **line_color** (String, 'grey') - Line Color. Init is grey

        **trafo_color** (String, 'green') - Trafo Color. Init is green

        **ext_grid_color** (String, 'yellow') - External Grid Color. Init is yellow

    OUTPUT:
        **figure** (graph_objs._figure.Figure) figure object
    """
    version_check()
    # create geocoord if none are available
    if 'line_geodata' not in net:
        net.line_geodata = pd.DataFrame(columns=['coords'])
    if 'bus_geodata' not in net:
        net.bus_geodata = pd.DataFrame(columns=["x", "y"])
    if len(net.bus_geodata) == 0:
        logger.warning(
            "No or insufficient geodata available --> Creating artificial coordinates."
            + " This may take some time...")
        create_generic_coordinates(net,
                                   respect_separation_points=respect_switches)
        if on_map:
            logger.warning(
                "Map plots not available with artificial coordinates and will be disabled!"
            )
            on_map = False

    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
        geo_data_to_latlong(net, projection=projection)

    # ----- Buses ------
    # initializating bus trace
    hoverinfo = get_hoverinfo(net, element="bus")
    bus_trace = create_bus_trace(net,
                                 net.bus.index,
                                 size=bus_size,
                                 color=bus_color,
                                 infofunc=hoverinfo)

    # ----- Lines ------
    # if bus geodata is available, but no line geodata
    if use_line_geodata is None:
        use_line_geodata = False if len(net.line_geodata) == 0 else True
    elif use_line_geodata and len(net.line_geodata) == 0:
        logger.warning(
            "No or insufficient line geodata available --> only bus geodata will be used."
        )
        use_line_geodata = False

    hoverinfo = get_hoverinfo(net, element="line")
    line_traces = create_line_trace(net,
                                    net.line.index,
                                    respect_switches=respect_switches,
                                    color=line_color,
                                    width=line_width,
                                    use_line_geodata=use_line_geodata,
                                    infofunc=hoverinfo)

    # ----- Trafos ------
    hoverinfo = get_hoverinfo(net, element="trafo")
    trafo_trace = create_trafo_trace(net,
                                     color=trafo_color,
                                     width=line_width * 5,
                                     infofunc=hoverinfo,
                                     use_line_geodata=use_line_geodata)

    # ----- Ext grid ------
    # get external grid from create_bus_trace
    marker_type = 'circle' if on_map else 'square'  # workaround because doesn't appear on mapbox if square
    hoverinfo = get_hoverinfo(net, element="ext_grid")
    ext_grid_trace = create_bus_trace(net,
                                      buses=net.ext_grid.bus,
                                      color=ext_grid_color,
                                      size=ext_grid_size,
                                      patch_type=marker_type,
                                      trace_name='external_grid',
                                      infofunc=hoverinfo)

    return draw_traces(line_traces + trafo_trace + ext_grid_trace + bus_trace,
                       aspectratio=aspectratio,
                       figsize=figsize,
                       on_map=on_map,
                       map_style=map_style)
Esempio n. 7
0
def vlevel_plotly(net, respect_switches=True, use_line_geodata=None, colors_dict=None, on_map=False,
                  projection=None, map_style='basic', figsize=1, aspectratio='auto', line_width=2,
                  bus_size=10):
    """
    Plots a pandapower network in plotly
    using lines/buses colors according to the voltage level they belong to.
    If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial

    INPUT:
        **net** - The pandapower format network. If none is provided, mv_oberrhein() will be
        plotted as an example

    OPTIONAL:
        **respect_switches** (bool, True) - Respect switches when artificial geodata is created

        **use_line_geodata** (bool, True) - defines if lines patches are based on net.line_geodata of the lines (True)
        or on net.bus_geodata of the connected buses (False)

        *colors_dict** (dict, None) - dictionary for customization of colors for each voltage level in the form:
        voltage_kv : color

        **on_map** (bool, False) - enables using mapbox plot in plotly If provided geodata are not real
        geo-coordinates in lon/lat form, on_map will be set to False.

        **projection** (String, None) - defines a projection from which network geo-data will be transformed to
        lat-long. For each projection a string can be found at http://spatialreference.org/ref/epsg/

        **map_style** (str, 'basic') - enables using mapbox plot in plotly

            - 'streets'
            - 'bright'
            - 'light'
            - 'dark'
            - 'satellite'

        **figsize** (float, 1) - aspectratio is multiplied by it in order to get final image size

        **aspectratio** (tuple, 'auto') - when 'auto' it preserves original aspect ratio of the network geodata
        any custom aspectration can be given as a tuple, e.g. (1.2, 1)

        **line_width** (float, 1.0) - width of lines

        **bus_size** (float, 10.0) -  size of buses to plot.

    """
    version_check()
    # create geocoord if none are available
    if 'line_geodata' not in net:
        net.line_geodata = pd.DataFrame(columns=['coords'])
    if 'bus_geodata' not in net:
        net.bus_geodata = pd.DataFrame(columns=["x", "y"])
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
                       " This may take some time")
        create_generic_coordinates(net, respect_switches=respect_switches)
        if on_map:
            logger.warning("Map plots not available with artificial coordinates and will be disabled!")
            on_map = False

    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
        geo_data_to_latlong(net, projection=projection)

    # if bus geodata is available, but no line geodata
    if use_line_geodata is None:
        use_line_geodata = False if len(net.line_geodata) == 0 else True
    elif use_line_geodata and len(net.line_geodata) == 0:
        logger.warning("No or insufficient line geodata available --> only bus geodata will be used.")
        use_line_geodata = False

    # getting connected componenets without consideration of trafos
    graph = create_nxgraph(net, include_trafos=False)
    vlev_buses = connected_components(graph)
    # getting unique sets of buses for each voltage level
    vlev_bus_dict = {}
    for vl_buses in vlev_buses:
        if net.bus.loc[vl_buses, 'vn_kv'].unique().shape[0] > 1:
            logger.warning('buses from the same voltage level does not have the same vn_kv !?')
        vn_kv = net.bus.loc[vl_buses, 'vn_kv'].unique()[0]
        if vlev_bus_dict.get(vn_kv):
            vlev_bus_dict[vn_kv].update(vl_buses)
        else:
            vlev_bus_dict[vn_kv] = vl_buses

    # create a default colormap for voltage levels
    nvlevs = len(vlev_bus_dict)
    colors = get_plotly_color_palette(nvlevs)
    colors_dict = dict(zip(vlev_bus_dict.keys(), colors))

    # creating traces for buses and lines for each voltage level
    bus_traces = []
    line_traces = []
    for vn_kv, buses_vl in vlev_bus_dict.items():

        vlev_color = colors_dict[vn_kv]
        bus_trace_vlev = create_bus_trace(net, buses=buses_vl, size=bus_size, legendgroup=str(vn_kv),
                                          color=vlev_color, trace_name='buses {0} kV'.format(vn_kv))
        if bus_trace_vlev is not None:
            bus_traces += bus_trace_vlev

        vlev_lines = net.line[net.line.from_bus.isin(buses_vl) & net.line.to_bus.isin(buses_vl)].index.tolist()
        line_trace_vlev = create_line_trace(net, lines=vlev_lines, use_line_geodata=use_line_geodata,
                                            respect_switches=respect_switches, legendgroup=str(vn_kv),
                                            color=vlev_color, width=line_width, trace_name='lines {0} kV'.format(vn_kv))
        if line_trace_vlev is not None:
            line_traces += line_trace_vlev

    trafo_traces = create_trafo_trace(net, color='gray', width=line_width * 2)

    draw_traces(line_traces + trafo_traces + bus_traces, showlegend=True,
                aspectratio=aspectratio, on_map=on_map, map_style=map_style, figsize=figsize)
Esempio n. 8
0
def _simple_plotly_generic(net,
                           respect_separators,
                           use_branch_geodata,
                           on_map,
                           projection,
                           map_style,
                           figsize,
                           aspectratio,
                           branch_width,
                           node_size,
                           ext_grid_size,
                           node_color,
                           branch_color,
                           trafo_color,
                           trafo3w_color,
                           ext_grid_color,
                           node_element,
                           branch_element,
                           trans_element,
                           trans3w_element,
                           separator_element,
                           branch_trace_func,
                           node_trace_func,
                           hoverinfo_func,
                           filename='temp-plot.html',
                           auto_open=True):
    version_check()
    # create geocoord if none are available
    branch_geodata = branch_element + "_geodata"
    node_geodata = node_element + "_geodata"

    if branch_geodata not in net:
        net[branch_geodata] = pd.DataFrame(columns=['coords'])
    if node_geodata not in net:
        net[node_geodata] = pd.DataFrame(columns=["x", "y"])
    if len(net[node_geodata]) == 0:
        logger.warning(
            "No or insufficient geodata available --> Creating artificial coordinates."
            + " This may take some time...")
        create_generic_coordinates(net, respect_switches=respect_separators)
        if on_map:
            logger.warning(
                "Map plots not available with artificial coordinates and will be disabled!"
            )
            on_map = False
    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
        geo_data_to_latlong(net, projection=projection)
    # ----- Nodes (Buses) ------
    # initializating node trace
    hoverinfo = hoverinfo_func(net, element=node_element)
    node_trace = node_trace_func(net,
                                 net[node_element].index,
                                 size=node_size,
                                 color=node_color,
                                 infofunc=hoverinfo)
    # ----- branches (Lines) ------
    # if node geodata is available, but no branch geodata
    if use_branch_geodata is None:
        use_branch_geodata = False if len(net[branch_geodata]) == 0 else True
    elif use_branch_geodata and len(net[branch_geodata]) == 0:
        logger.warning(
            "No or insufficient line geodata available --> only bus geodata will be used."
        )
        use_branch_geodata = False
    hoverinfo = hoverinfo_func(net, element=branch_element)
    branch_traces = branch_trace_func(net,
                                      net[branch_element].index,
                                      use_branch_geodata,
                                      respect_separators,
                                      color=branch_color,
                                      width=branch_width,
                                      infofunc=hoverinfo)
    trans_trace = []
    # ----- Trafos ------
    if 'trafo' in net:
        hoverinfo = hoverinfo_func(net, element=trans_element)
        trans_trace += create_trafo_trace(net,
                                          color=trafo_color,
                                          width=branch_width * 5,
                                          infofunc=hoverinfo,
                                          use_line_geodata=use_branch_geodata)
    # ----- 3W Trafos ------
    if 'trafo3w' in net:
        hoverinfo = hoverinfo_func(net, element=trans3w_element)
        trans_trace += create_trafo_trace(net,
                                          color=trafo3w_color,
                                          trafotype='3W',
                                          width=branch_width * 5,
                                          trace_name='3w_trafos',
                                          infofunc=hoverinfo,
                                          use_line_geodata=use_branch_geodata)
    # ----- Ext grid ------
    # get external grid from _create_node_trace
    marker_type = 'circle' if on_map else 'square'  # workaround because doesn't appear on mapbox if square
    hoverinfo = hoverinfo_func(net, element="ext_grid")
    ext_grid_trace = _create_node_trace(net,
                                        nodes=net.ext_grid[node_element],
                                        size=ext_grid_size,
                                        patch_type=marker_type,
                                        color=ext_grid_color,
                                        infofunc=hoverinfo,
                                        trace_name='external_grid',
                                        node_element=node_element,
                                        branch_element=branch_element)
    return draw_traces(branch_traces + trans_trace + ext_grid_trace +
                       node_trace,
                       aspectratio=aspectratio,
                       figsize=figsize,
                       on_map=on_map,
                       map_style=map_style,
                       filename=filename,
                       auto_open=auto_open)
def test_create_generic_coordinates_nx():
    net = create_test_network()
    net.bus_geodata.drop(net.bus_geodata.index, inplace=True)
    create_generic_coordinates(net, library="networkx")
    assert len(net.bus_geodata) == len(net.bus)
Esempio n. 10
0
def test_create_generic_coordinates_igraph(net_in):
    net = copy.deepcopy(net_in)
    net.bus_geodata.drop(net.bus_geodata.index, inplace=True)
    create_generic_coordinates(net, library="igraph")
    assert len(net.bus_geodata) == len(net.bus)
Esempio n. 11
0
def _draw_colored_bus_groups_plotly(
    net, bus_groups, respect_switches=True, use_line_geodata=None,
    on_map=False, projection=None, map_style='basic', figsize=1, aspectratio='auto', line_width=2,
    bus_size=10, filename="temp-plot.html", auto_open=True):
    """
    Internal function of vlevel_plotly()

    **bus_groups** - list of tuples consisting of set of bus indices, color, legendgroup
    """
    version_check()

    # create geocoord if none are available
    if 'line_geodata' not in net:
        net.line_geodata = pd.DataFrame(columns=['coords'])
    if 'bus_geodata' not in net:
        net.bus_geodata = pd.DataFrame(columns=["x", "y"])
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning("No or insufficient geodata available --> Creating artificial coordinates." +
                       " This may take some time")
        create_generic_coordinates(net, respect_switches=respect_switches)
        if on_map:
            logger.warning(
                "Map plots not available with artificial coordinates and will be disabled!")
            on_map = False

    # check if geodata are real geographycal lat/lon coordinates using geopy
    if on_map and projection is not None:
        geo_data_to_latlong(net, projection=projection)

    # if bus geodata is available, but no line geodata
    if use_line_geodata is None:
        use_line_geodata = False if len(net.line_geodata) == 0 else True
    elif use_line_geodata and len(net.line_geodata) == 0:
        logger.warning(
            "No or insufficient line geodata available --> only bus geodata will be used.")
        use_line_geodata = False

    # creating traces for buses and lines for each voltage level
    bus_traces = []
    line_traces = []
    traced_lines = set()
    for bus_group_legend in bus_groups:
        buses_vl, vlev_color, legend_group = bus_group_legend

        bus_trace_vlev = create_bus_trace(
            net, buses=buses_vl, size=bus_size, legendgroup=legend_group, color=vlev_color,
            trace_name=f'buses {legend_group}')
        if bus_trace_vlev is not None:
            bus_traces += bus_trace_vlev

        vlev_lines = net.line[net.line.from_bus.isin(buses_vl) &
                              net.line.to_bus.isin(buses_vl)].index.tolist()
        traced_lines |= set(vlev_lines)
        line_trace_vlev = create_line_trace(
            net, lines=vlev_lines, use_line_geodata=use_line_geodata,
            respect_switches=respect_switches, legendgroup=legend_group, color=vlev_color,
            width=line_width, trace_name=f'lines {legend_group}')
        if line_trace_vlev is not None:
            line_traces += line_trace_vlev

    # creating traces for other lines
    line_trace_other = create_line_trace(
        net, lines=net.line.index.difference(traced_lines).tolist(),
        use_line_geodata=use_line_geodata, respect_switches=respect_switches,
        color="grey", width=line_width)
    if line_trace_vlev is not None:
        line_traces += line_trace_other

    trafo_traces = create_trafo_trace(net, color='gray', width=line_width * 2)

    return draw_traces(line_traces + trafo_traces + bus_traces, showlegend=True,
                       aspectratio=aspectratio, on_map=on_map, map_style=map_style, figsize=figsize,
                       filename=filename, auto_open=auto_open)
Esempio n. 12
0
def simple_plot(net=None,
                respect_switches=False,
                line_width=1.0,
                bus_size=1.0,
                ext_grid_size=1.0,
                bus_color=colors[0],
                line_color='grey',
                trafo_color='g',
                ext_grid_color='y'):
    """
        Plots a pandapower network as simple as possible. If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial

        INPUT:
            **net** - The pandapower format network. If none is provided, mv_oberrhein() will be plotted as an example

        OPTIONAL:
            **respect_switches** (bool, False) - Respect switches when artificial geodata is created

            **line_width** (float, 1.0) - width of lines

            **bus_size** (float, 1.0) - Relative size of buses to plot.

                The value bus_size is multiplied with mean_distance_between_buses, which equals the distance between
                the max geoocord and the min divided by 200.
                mean_distance_between_buses = sum((net['bus_geodata'].max() - net['bus_geodata'].min()) / 200)

            **ext_grid_size** (float, 1.0) - Relative size of ext_grids to plot.

                See bus sizes for details. Note: ext_grids are plottet as rectangles

            **bus_color** (String, colors[0]) - Bus Color. Init as first value of color palette. Usually colors[0] = "b".

            **line_color** (String, 'grey') - Line Color. Init is grey

            **trafo_color** (String, 'g') - Trafo Color. Init is green

            **ext_grid_color** (String, 'y') - External Grid Color. Init is yellow

        """
    if net is None:
        import pandapower.networks as nw
        logger.warning(
            "No pandapower network provided -> Plotting mv_oberrhein")
        net = nw.mv_oberrhein()

    # create geocoord if none are available
    if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0:
        logger.warning(
            "No or insufficient geodata available --> Creating artificial coordinates."
            + " This may take some time")
        create_generic_coordinates(net, respect_switches=respect_switches)

    if bus_size or ext_grid_size is None:
        # if either bus_size or ext_grid size is None -> calc size from distance between min and
        # max geocoord
        mean_distance_between_buses = sum(
            (net['bus_geodata'].max() - net['bus_geodata'].min()) / 200)
        # set the bus / ext_grid sizes accordingly
        # Comment: This is implemented because if you would choose a fixed values
        # (e.g. bus_size = 0.2), the size
        # could be to small for large networks and vice versa
        bus_size *= mean_distance_between_buses
        ext_grid_size *= mean_distance_between_buses * 1.5

    # if bus geodata is available, but no line geodata
    use_line_geodata = False if len(net.line_geodata) == 0 else True

    # create bus collections ti plot
    bc = create_bus_collection(net,
                               net.bus.index,
                               size=bus_size,
                               color=bus_color,
                               zorder=10)
    lc = create_line_collection(net,
                                net.line.index,
                                color=line_color,
                                linewidths=line_width,
                                use_line_geodata=use_line_geodata)
    collections = [bc, lc]
    eg_buses_with_geocoordinates = set(net.ext_grid.bus.values) & set(
        net.bus_geodata.index)
    if len(eg_buses_with_geocoordinates) > 0:
        sc = create_bus_collection(net,
                                   eg_buses_with_geocoordinates,
                                   patch_type="rect",
                                   size=ext_grid_size,
                                   color=ext_grid_color,
                                   zorder=11)
        collections.append(sc)
    # create trafo collection if trafo is available

    trafo_buses_with_geocoordinates = [t for t, trafo in net.trafo.iterrows() \
                                       if trafo.hv_bus in net.bus_geodata.index \
                                       and trafo.lv_bus in net.bus_geodata.index]
    if len(trafo_buses_with_geocoordinates) > 0:
        tc = create_trafo_collection(net,
                                     trafo_buses_with_geocoordinates,
                                     color=trafo_color)
        collections.append(tc)

    draw_collections(collections)
    plt.show()