Skip to content
Snippets Groups Projects
PlotUtils.jl 7.13 KiB
Newer Older
#* Utility functions for various plotting functions
#*------------------------------------------------------------------------------

#=
Returns the minimal and maximal values of bus longitude and latitude coordinates contained a dictionary. An offset can be used to arbitrarily increase the area.
=#
function _get_pg_area(pos::Dict{Int64,Tuple{Float64,Float64}}, offset=0.)
    locs = collect(values(pos))
    lon_min = minimum(p -> p[1], locs) - offset
    lon_max = maximum(p -> p[1], locs) + offset
    lat_min = minimum(p -> p[2], locs) - offset
    lat_max = maximum(p -> p[2], locs) + offset
    return lon_min, lon_max, lat_min, lat_max
end

function _get_pg_area(network_data::Dict{String,<:Any}, offset=0.)
    pos = Dict(
        b["index"] => (b["bus_lon"], b["bus_lat"]) 
        for b in collect(values(network_data["bus"]))
    ) # geographic bus locations

    return _get_pg_area(pos, offset)
end

#*------------------------------------------------------------------------------

#=
Returns isolated buses that are not connected to any active branch.
=#
function _get_isolated_buses(network_data::Dict{String,<:Any})
    ### Find buses connected to active branches
    connected_buses = vcat(
        [br["f_bus"] for br in values(network_data["branch"]) if 
        br["br_status"] == 1],
        [br["t_bus"] for br in values(network_data["branch"]) if 
        br["br_status"] == 1]
    )

    ### Find isolated buses
    isolated_buses = [
        b["bus_i"] for b in values(network_data["bus"]) if 
        b["bus_i"]  connected_buses
    ]

    return unique(isolated_buses)
end

#*------------------------------------------------------------------------------

#= 
Function for recursively merging two dictionaries (used for updating the dictionary containing plot settings).
=#
_recursive_merge(x::AbstractDict,y::AbstractDict) = merge(_recursive_merge,x,y)
_recursive_merge(x,y) = y

#=
Returns a dictionary of default plot settings for various plotting functions.
=#
function _default_settings(func::Symbol)
    if func == :plot_pg
        defaults = Dict(
            ### Settings for _draw_buses!
            "Buses" => Dict(
                "Generator" => Dict(
                    "marker" => "s",
                    "size" => 30,
                    "color" => "darkorange",
                    "alpha" => 1,
                    "label" => "Generators",
                    "show" => true
                ),
                "Load and generator" => Dict(
                    "marker" => "s",
                    "size" => 30,
                    "color" => "darkorange",
                    "alpha" => 1,
                    "label" => "nolabel",
                    "show" => true
                ),
                "Slack" => Dict(
                    "marker" => "s",
                    "size" => 70,
                    "color" => "red",
                    "alpha" => 0.6,
                    "label" => "Slack",
                    "show" => true
                ),
                "Load" => Dict(
                    "marker" => "o",
                    "size" => 15,
                    "color" => "limegreen",
                    "alpha" => 0.7,
                    "label" => "Loads",
                    "show" => true
                ),
                "Empty bus" => Dict(
                    "marker" => "o",
                    "size" => 2,
                    "color" => "black",
                    "alpha" => 0.3,
                    "label" => "Empty buses",
                    "show" => true,
                    "show_isolated" => false
                )
            ),
            ### Settings for _draw_branches!
            "Branches" => Dict(
                "br_status" => "active", # plot only "active", "inactive" or "all" branches
                "br_coloring" => "equal", # how to color branches (can be set to "equal", "voltage", "MW-loading", "Mvar-loading" or "MVA-loading")
                "br_color" => "k", # default color for "equal" coloring
                "br_lw" => 2,
                "br_alpha" => 1
            ),
            "Wind" => Dict(
                "levels" => 200,
                "cmap" => "Purples",
                "alpha" => 1,
                "cbar_label" => L"\mathrm{wind\, speed\, in\,} m/s"
            ),
            "draw_ticks" => [true, true, true, true], # whether to show ticks
            "draw_legend" => true, # whether to draw a legend
            "xlabel" => L"Longitude in $°$",
            "ylabel" => L"Latitude in $°$"
        )
    elseif func == :plot_pg_overhead_tl_segments
        defaults = Dict(
            ### Settings for _draw_buses!
            "Buses" => Dict(
                "Generator" => Dict(
                    "marker" => "s",
                    "size" => 30,
                    "color" => "darkorange",
                    "alpha" => 1,
                    "label" => "Generators",
                    "show" => true
                ),
                "Load and generator" => Dict(
                    "marker" => "s",
                    "size" => 30,
                    "color" => "darkorange",
                    "alpha" => 1,
                    "label" => "nolabel",
                    "show" => true
                ),
                "Slack" => Dict(
                    "marker" => "s",
                    "size" => 70,
                    "color" => "red",
                    "alpha" => 0.6,
                    "label" => "Slack",
                    "show" => true
                ),
                "Load" => Dict(
                    "marker" => "o",
                    "size" => 15,
                    "color" => "limegreen",
                    "alpha" => 0.7,
                    "label" => "Loads",
                    "show" => true
                ),
                "Empty bus" => Dict(
                    "marker" => "o",
                    "size" => 2,
                    "color" => "black",
                    "alpha" => 0.3,
                    "label" => "Empty buses",
                    "show" => true
                )
            ),
            "d_twrs" => 161.0,
            "node_size" => .0005,
            "alpha" => 1,
            "draw_ticks" => [true, true, true, true], # whether to show ticks
            "draw_legend" => true, # whether to draw a legend
            "xlabel" => L"Longitude in $°$",
            "ylabel" => L"Latitude in $°$",
        )
    elseif func == :scatter_branchloads
        defaults = Dict(
            "x_pf_type" => "MVA-loading",
            "y_pf_type" => "MVA-loading",
            "size" => 15,
            "cmap" => "seismic", # "coolwarm", # cividis_r
            "ec" => "k",
            "lw" => .1,
            "alpha" => 1.,
            "xlabel" => "",
            "ylabel" => ""
        )
    elseif func == :plot_pg_pf_diff
        defaults = Dict(
            "Branches" => Dict(
                "pf_type" => "MVA-loading",
                "cmap" => "coolwarm",
                "cbar_label" => L"Line loading difference $(F^{\mathrm{new}}_{ij}-F^{\mathrm{}}_{ij})/C_{ij}$"
            )
        )
        defaults = _recursive_merge(_default_settings(:plot_pg), defaults)
    else
        throw(ArgumentError("Unknown function $func."))
    end

    return defaults
end