-
Julian Stürmer authoredJulian Stürmer authored
PlotUtils.jl 7.39 KiB
#* 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"
),
"area_offset" => 0.4,
"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(
"cmap_range" => "full", # or "relative"
"x_pf_type" => "MVA-loading", # or "MW-loading", "Mvar-loading"
"y_pf_type" => "MVA-loading", # or "MW-loading", "Mvar-loading"
"size" => 15,
"cmap" => "coolwarm", # or "seismic", "cividis_r", ...
"ec" => "k",
"lw" => .1,
"alpha" => 1.,
"xlabel" => "",
"ylabel" => ""
)
elseif func == :plot_pg_pf_diff
defaults = Dict(
"Branches" => Dict(
"pf_type" => "MVA-loading",
"ref_pf_type" => "MVA-loading",
"cmap" => "coolwarm",
"cmap_range" => "full", # or "relative"
"cbar_label" => L"Line loading difference $(S^{\mathrm{new}}_{ij}-S^{\mathrm{old}}_{ij})/C_{ij}$"
)
)
defaults = _recursive_merge(_default_settings(:plot_pg), defaults)
else
throw(ArgumentError("Unknown function $func."))
end
return defaults
end