Skip to content

Commit c948366

Browse files
author
Jon Vegard Venås
authored
Improve performance (#38)
* Added the option pre_plot_sub_components to the GUI-constructor to skip preplotting hidden sub components of an area (the option is by default alse). Also improved general performance. * Implement further optimizations and fix connect! accuracy * Added the field visible to EnergySystemDesign and Connection on which plots can directly rely on for visibility * Adjusted Base.show functionality and testing of color toggling. Also fixed edge cases for square_intersection.
1 parent 27238b6 commit c948366

25 files changed

Lines changed: 841 additions & 450 deletions

NEWS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Release notes
22

3+
## Unversioned updates
4+
5+
### Enhancements
6+
7+
* Added the option `pre_plot_sub_components` to the `GUI`-constructor to skip preplotting hidden sub components of an area (the option is by default `true`). The components of an `Area` are then plotted on demand (on the `open` functionality). This greatly enhances performance for large cases.
8+
* Improved general performance.
9+
10+
### Adjustments
11+
12+
* Adjusted the calculation of `Connection` plots.
13+
* Added the field `visible` to `EnergySystemDesign` and `Connection` on which plots can directly rely on for visibility
14+
* Adjust behaviour of `Base.show` on the types `EnergySystemDesign`, `Connection` and `AbstractSystem` to correspond to `Base.show` of their corresponding `AbstractElement`.
15+
* Change tests of toggling of colors to be based on a new case having more transmission modes (the case in the new `test/EMI_geography_2.jl` file).
16+
317
## Version 0.5.17 (2025-11-19)
418

519
### Bugfix

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "EnergyModelsGUI"
22
uuid = "737a7361-d3b7-40e9-b1ac-59bee4c5ea2d"
3-
version = "0.5.17"
3+
version = "0.5.18"
44
authors = ["Jon Vegard Venås <JonVegard.Venas@sintef.no>", "Magnus Askeland <Magnus.Askeland@sintef.no>", "Shweta Tiwari <Shweta.Tiwari@sintef.no>"]
55

66
[deps]

docs/src/figures/EMI_geography.png

3.98 KB
Loading
1.68 KB
Loading

examples/EMI_geography.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ gui = GUI(
2626
coarse_coast_lines = false,
2727
scale_tot_opex = true,
2828
scale_tot_capex = false,
29+
pre_plot_sub_components = false,
2930
)

examples/generate_examples.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,7 @@ technologies.
520520
The example is partly based on the provided example `network.jl` in `EnergyModelsGeography`.
521521
It will be repalced in the near future with a simplified example.
522522
"""
523-
524523
function generate_example_data_geo()
525-
@debug "Generate case data"
526524
@info "Generate data coded dummy model for now (Investment Model)"
527525

528526
# Retrieve the products

ext/EMGExt/EMGExt.jl

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,8 @@ using TimeStruct
44
using EnergyModelsBase
55
using EnergyModelsInvestments
66
using EnergyModelsGeography
7-
8-
# Use GLMakie to get the GridLayout type
9-
using GLMakie
10-
117
using EnergyModelsGUI
128

13-
using DataFrames
14-
159
const TS = TimeStruct
1610
const EMG = EnergyModelsGeography
1711
const EMB = EnergyModelsBase
@@ -38,7 +32,7 @@ EMG.get_transmissions(system::EMGUI.SystemGeo) = EMGUI.get_connections(system)
3832
Get all transmission modes of a `SystemGeo` `system`.
3933
"""
4034
function get_modes(system::EMGUI.SystemGeo)
41-
transmission_modes = Vector{TransmissionMode}()
35+
transmission_modes = TransmissionMode[]
4236
for t get_transmissions(system)
4337
append!(transmission_modes, modes(t))
4438
end
@@ -70,15 +64,14 @@ Initialize a `SystemGeo` from a `Case`.
7064
"""
7165
function EMGUI.SystemGeo(case::Case)
7266
areas = get_areas(case)
73-
ref_element = areas[1]
7467
return EMGUI.SystemGeo(
7568
get_time_struct(case),
7669
get_products(case),
7770
get_elements_vec(case),
7871
areas,
7972
get_transmissions(case),
8073
EMGUI.NothingElement(),
81-
ref_element,
74+
areas[1],
8275
)
8376
end
8477

src/datastructures.jl

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ energy system designs in Julia.
135135
- **`wall::Observable{Symbol}`** represents an aspect of the system's state, observed
136136
for changes and represented as a Symbol.
137137
- **`file::String`** is the filename or path associated with the `EnergySystemDesign`.
138-
- **`plots::Vector{Any}`** is a vector with all Makie object associated with this object.
139-
The value does not have to be provided.
140-
- **`invest_data::ProcInvData`** stores processed investment data.
138+
- **`visible::Observable{Bool}`** indicates whether the system is visible, observed for changes.
139+
- **`inv_data::ProcInvData`** stores processed investment data.
140+
- **`plots::Vector{Makie.AbstractPlot}`** is a vector with all Makie object associated with
141+
this object.
141142
"""
142143
mutable struct EnergySystemDesign <: AbstractGUIObj
143144
system::AbstractSystem
@@ -151,8 +152,9 @@ mutable struct EnergySystemDesign <: AbstractGUIObj
151152
color::Observable{RGBA{Float32}}
152153
wall::Observable{Symbol}
153154
file::String
155+
visible::Observable{Bool}
154156
inv_data::ProcInvData
155-
plots::Vector{Any}
157+
plots::Vector{Makie.AbstractPlot}
156158
end
157159
function EnergySystemDesign(
158160
system::AbstractSystem,
@@ -166,6 +168,7 @@ function EnergySystemDesign(
166168
color::Observable{RGBA{Float32}},
167169
wall::Observable{Symbol},
168170
file::String,
171+
visible::Observable{Bool},
169172
)
170173
return EnergySystemDesign(
171174
system,
@@ -179,6 +182,7 @@ function EnergySystemDesign(
179182
color,
180183
wall,
181184
file,
185+
visible,
182186
ProcInvData(),
183187
Any[],
184188
)
@@ -198,25 +202,29 @@ Mutable type for providing a flexible data structure for connections between
198202
linked to.
199203
- **`connection::AbstractElement`** is the EMX connection structure.
200204
- **`colors::Vector{RGBA{Float32}}`** is the associated colors of the connection.
201-
- **`plots::Vector{Any}`** is a vector with all Makie object associated with this object.
202-
- **`invest_data::ProcInvData`** stores processed investment data.
205+
- **`visible::Observable{Bool}`** indicates whether the system is visible, observed for changes.
206+
- **`inv_data::ProcInvData`** stores processed investment data.
207+
- **`plots::Vector{Makie.AbstractPlot}`** is a vector with all Makie object associated with
208+
this object.
203209
"""
204210
mutable struct Connection <: AbstractGUIObj
205211
from::EnergySystemDesign
206212
to::EnergySystemDesign
207213
connection::AbstractElement
208214
colors::Vector{RGBA{Float32}}
215+
visible::Observable{Bool}
209216
inv_data::ProcInvData
210-
plots::Vector{Any}
217+
plots::Vector{Makie.AbstractPlot}
211218
end
212219
function Connection(
213220
from::EnergySystemDesign,
214221
to::EnergySystemDesign,
215222
connection::AbstractElement,
216223
id_to_color_map::Dict{Any,Any},
224+
visible::Observable{Bool},
217225
)
218226
colors::Vector{RGBA{Float32}} = get_resource_colors(connection, id_to_color_map)
219-
return Connection(from, to, connection, colors, ProcInvData(), Any[])
227+
return Connection(from, to, connection, colors, visible, ProcInvData(), Any[])
220228
end
221229

222230
"""
@@ -308,10 +316,10 @@ const YELLOW = RGBA{Float32}(1.0, 1.0, 0.0, 1.0)
308316
const MAGENTA = RGBA{Float32}(1.0, 0.0, 1.0, 1.0)
309317
const CYAN = RGBA{Float32}(0.0, 1.0, 1.0, 1.0)
310318

311-
Base.show(io::IO, obj::AbstractGUIObj) = dump(io, obj; maxdepth = 1)
319+
Base.show(io::IO, obj::AbstractGUIObj) = Base.show(io, get_element(obj))
312320
Base.show(io::IO, ::NothingDesign) = print(io, "NothingDesign()")
313321
Base.show(io::IO, obj::ProcInvData) = dump(io, obj; maxdepth = 1)
314-
Base.show(io::IO, system::AbstractSystem) = dump(io, system; maxdepth = 1)
322+
Base.show(io::IO, system::AbstractSystem) = Base.show(io, get_element(system))
315323
Base.show(io::IO, gui::GUI) = dump(io, gui; maxdepth = 1)
316324
Base.show(io::IO, ::NothingElement) = print(io, "top_level")
317325

@@ -418,11 +426,11 @@ Returns the nodes of a `AbstractSystem` `system`.
418426
EMB.get_nodes(system::AbstractSystem) = get_children(system)
419427

420428
"""
421-
get_element(system::System)
429+
get_element(system::AbstractSystem)
422430
423-
Returns the `element` assosiated of a `System` `system`.
431+
Returns the `element` assosiated of a `AbstractSystem` `system`.
424432
"""
425-
get_element(system::System) = get_parent(system)
433+
get_element(system::AbstractSystem) = get_parent(system)
426434

427435
"""
428436
get_plotables(system::System)
@@ -600,6 +608,13 @@ Returns the `plots` field of a `AbstractGUIObj` `obj`.
600608
"""
601609
get_plots(obj::AbstractGUIObj) = obj.plots
602610

611+
"""
612+
get_visible(obj::AbstractGUIObj)
613+
614+
Returns the `visible` field of a `AbstractGUIObj` `obj`.
615+
"""
616+
get_visible(obj::AbstractGUIObj) = obj.visible
617+
603618
"""
604619
get_fig(gui::GUI)
605620

src/setup_GUI.jl

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ to the old EnergyModelsX `case` dictionary.
4242
hovering objects to show information.
4343
- **`use_geomakie::Bool=true`** toggles the use of GeoMakie for plotting geographical
4444
designs when the `case` contains geographical information.
45+
- **`pre_plot_sub_components::Bool=true`** toggles whether or not to pre-plot all
46+
sub-components of areas in the topology design. Setting this to `false` greatly
47+
enhances performance for large cases, as the components of an `Area` are then
48+
plotted on demand (on the `open` functionality).
4549
4650
!!! warning "Reading model results from CSV-files"
4751
Reading model results from a directory (*i.e.*, `model::String` implying that the results
@@ -72,6 +76,7 @@ function GUI(
7276
tol::Float64 = 1e-8,
7377
enable_data_inspector::Bool = true,
7478
use_geomakie::Bool = true,
79+
pre_plot_sub_components::Bool = true,
7580
)
7681
# Generate the system topology:
7782
@info raw"Setting up the topology design structure"
@@ -82,6 +87,11 @@ function GUI(
8287
@info raw"Setting up the GUI"
8388
design::EnergySystemDesign = root_design # variable to store current system (inkluding sub systems)
8489

90+
if expand_all && !pre_plot_sub_components
91+
expand_all = false
92+
@warn "Incompatible EMGUI settings: `expand_all` is set to true but " *
93+
"`pre_plot_sub_components` is set to false. Setting `expand_all` to false."
94+
end
8595
# Set variables
8696
vars::Dict{Symbol,Any} = Dict(
8797
:title => Observable("top_level"),
@@ -111,6 +121,7 @@ function GUI(
111121
:colormap => colormap,
112122
:tol => tol,
113123
:use_geomakie => use_geomakie,
124+
:pre_plot_sub_components => pre_plot_sub_components,
114125
:autolimits => Dict(
115126
:results_op => true,
116127
:results_sc => true,
@@ -137,7 +148,7 @@ function GUI(
137148
vars[:path_to_descriptive_names] = path_to_descriptive_names
138149
vars[:descriptive_names_dict] = descriptive_names_dict
139150

140-
vars[:plot_widths] = plot_widths
151+
vars[:plot_widths] = Vec{2,Int64}(plot_widths)
141152
vars[:hide_topo_ax_decorations] = hide_topo_ax_decorations
142153
vars[:expand_all] = expand_all
143154

@@ -149,30 +160,42 @@ function GUI(
149160

150161
# Create iterables for plotting objects in layers (z-direction) such that nodes are
151162
# neatly placed on top of each other and lines are beneath nodes
152-
vars[:z_translate_lines] = 10.0f0
153-
vars[:z_translate_components] = 50.0f0
163+
vars[:depth_shift_lines] = 0.006f0
164+
vars[:depth_shift_components] = 0.002f0
154165

155166
vars[:selected_systems] = []
156167

157168
# Default text for the text area
158-
vars[:default_text] = string(
159-
"Tips:\n",
160-
"Keyboard shortcuts:\n",
161-
"\tctrl+left-click: Select multiple nodes.\n",
162-
"\tright-click and drag: to pan\n",
163-
"\tscroll wheel: zoom in or out\n",
164-
"\tspace: Enter the selected system\n",
165-
"\tctrl+s: Save\n",
166-
"\tctrl+r: Reset view\n",
167-
"\tctrl+w: Close window\n",
168-
"\tEsc (or MouseButton4): Exit the current system and into the parent system\n",
169-
"\tholding x while scrolling over plots will zoom in/out in the x-direction.\n",
170-
"\tholding y while scrolling over plots will zoom in/out in the y-direction.\n\n",
171-
"Left-clicking a component will put information about this component here.\n\n",
172-
"Clicking a plot below enables you to pin this plot (hitting the `pin\n",
173-
"current plot` button) for comparison with other plots.\n",
174-
"Use the `Delete` button to unpin a selected plot.",
175-
)
169+
io = IOBuffer()
170+
println(io, "Tips:")
171+
println(io, "Keyboard shortcuts:")
172+
println(io, "\tctrl+left-click: Select multiple nodes.")
173+
println(io, "\tright-click and drag: to pan")
174+
println(io, "\tscroll wheel: zoom in or out")
175+
println(io, "\tspace: Enter the selected system")
176+
println(io, "\tctrl+s: Save")
177+
println(io, "\tctrl+r: Reset view")
178+
println(io, "\tctrl+w: Close window")
179+
println(
180+
io,
181+
"\tEsc (or MouseButton4): Exit the current system and into the parent system",
182+
)
183+
println(
184+
io,
185+
"\tholding x while scrolling over plots will zoom in/out in the x-direction.",
186+
)
187+
println(
188+
io,
189+
"\tholding y while scrolling over plots will zoom in/out in the y-direction.\n",
190+
)
191+
println(
192+
io,
193+
"Left-clicking a component will put information about this component here.\n",
194+
)
195+
println(io, "Clicking a plot below enables you to pin this plot (hitting the `pin")
196+
println(io, "current plot` button) for comparison with other plots.")
197+
print(io, "Use the `Delete` button to unpin a selected plot.")
198+
vars[:default_text] = String(take!(io))
176199
vars[:info_text] = Observable(vars[:default_text])
177200
vars[:summary_text] = Observable("No model results")
178201
vars[:dragging] = Ref(false)
@@ -219,7 +242,9 @@ function GUI(
219242
notify(axes[:topo].finallimits)
220243

221244
# make sure all graphics is adapted to the spawned figure sizes
222-
notify(get_toggle(gui, :expand_all).active)
245+
if get_var(gui, :expand_all)
246+
notify(get_toggle(gui, :expand_all).active)
247+
end
223248

224249
# Enable inspector (such that hovering objects shows information)
225250
# Linewidth set to zero as this boundary is slightly laggy on movement
@@ -305,7 +330,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
305330

306331
# Download the file if it doesn't exist in the temporary directory
307332
if !isfile(local_file_path)
308-
@debug "Trying to download file $url to $local_file_path"
309333
HTTP.download(url, local_file_path)
310334
end
311335

@@ -323,8 +347,9 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
323347
strokecolor = :gray50,
324348
strokewidth = 0.5,
325349
inspectable = false,
350+
depth_shift = 1.0f0 - 2.0f-5,
351+
stroke_depth_shift = 1.0f0 - 3.0f-5,
326352
)
327-
Makie.translate!(countries_plot, 0, 0, -1)
328353
ocean_coords = [(180, -90), (-180, -90), (-180, 90), (180, 90)]
329354
ocean = poly!(
330355
ax,
@@ -333,8 +358,9 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
333358
strokewidth = 0.5,
334359
strokecolor = :gray50,
335360
inspectable = false,
361+
depth_shift = 1.0f0,
362+
stroke_depth_shift = 1.0f0 - 1.0f-5,
336363
)
337-
Makie.translate!(ocean, 0, 0, -2)
338364
else # The design does not use the EnergyModelsGeography package: Create a simple Makie axis
339365
ax = Axis(
340366
gridlayout_topology_ax[1, 1];
@@ -411,7 +437,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
411437
labelsize = vars[:fontsize],
412438
titlesize = vars[:fontsize],
413439
)
414-
Makie.translate!(topo_legend.blockscene, 0, 0, vars[:z_translate_components] + 999)
415440

416441
# Initiate an axis for displaying information about the selected node
417442
ax_info::Makie.Axis = Axis(
@@ -638,11 +663,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
638663
:results => nothing, :topo => topo_legend,
639664
)
640665

641-
# Ensure that menus are on top
642-
for menu values(menus)
643-
translate!(menu.blockscene, 0.0f0, 0.0f0, vars[:z_translate_components] + 2000.0f0)
644-
end
645-
646666
# Collect all toggles into a dictionary
647667
toggles::Dict{Symbol,Makie.Toggle} = Dict(:expand_all => expand_all_toggle)
648668

@@ -652,18 +672,13 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
652672
)
653673

654674
# Update the title of the figure
655-
topo_title_obj = text!(
675+
text!(
656676
ax,
657677
vars[:topo_title_loc_x],
658678
vars[:topo_title_loc_y];
659679
text = vars[:title],
660680
fontsize = vars[:fontsize],
661-
)
662-
Makie.translate!(
663-
topo_title_obj,
664-
0.0f0,
665-
0.0f0,
666-
vars[:z_translate_components] + 999.0f0,
681+
depth_shift = -1.0f0,
667682
)
668683

669684
return fig, buttons, menus, toggles, axes, legends

0 commit comments

Comments
 (0)