Preamble
from plotapi import ParetoFront
Introduction
Dominance relations can be clearly visualised when working in a two-objective space. Such visualisations can be useful for:
- Monitoring performance throughout the optimisation process.
- Understanding and exploring spatial relationships.
- Presentation to a decision maker.
- Progressive and interactive preference articulation throughout the optimisation process1.
We'll use the PlotAPI package which is available for Python, Rust, JavaScript, Ruby, Julia, and any language that supports HTTP requests. PlotAPI has a specialised multi-objective visualisation type for displaying Pareto and Non-Dominated fronts, named ParetoFront
.
Solutions in Objective Space
Let's do this with some arbitrary solutions.
solutions = [
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 40, "objv_2": 14},
{"order": 0, "objv_1": 40, "objv_2": 12},
{"order": 0, "objv_1": 45, "objv_2": 12},
{"order": 0, "objv_1": 45, "objv_2": 10},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 11},
{"order": 0, "objv_1": 50, "objv_2": 10},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 50, "objv_2": 12},
{"order": 0, "objv_1": 60, "objv_2": 8},
{"order": 0, "objv_1": 80, "objv_2": 3},
{"order": 0, "objv_1": 30, "objv_2": 20},
{"order": 0, "objv_1": 30, "objv_2": 20},
{"order": 0, "objv_1": 10, "objv_2": 20},
]
Here we can see our population defined as a list
of dictionary
items. Each dictionary
includes:
-
order
which determines with time period this item belongs to. This should be numerical, but can be formatted e.g. as dates. -
objv_1
the first objective value, e.g. "speed". -
objv_2
the second objective value, e.g. "cost".
Visualisation
A Simple and Static Visualisation
Let's demonstrate solutions plotted in two-objective space.
Here, we've disabled most of PlotAPI's features to replicate the visualisation from the Sections on Pareto Optimality and Dominance Relations and Non-Dominated Sorting.
ParetoFront(
solutions,
popup_enabled=False,
show_order=False,
zoomed=False,
current_order_highlight=False,
show_pareto_front=False,
transition_delay=0,
transition_duration=0,
label_font_size=0,
event_font_size=0,
x_label="Objective 1",
y_label="Objective 2",
optimisations=["max", "max"],
).show()
An Interactive Visualisation
Now let's leverage more of PlotAPI's features to visualise the same set.
Hovering over a solution will display a pop with more information, and highlight solutions of the same non-dominated rank. Clicking on the visualisation will switch the view scope between focussing on Pareto Front solutions and displaying all solutions.
ParetoFront(
solutions,
show_order=False,
current_order_highlight=False,
x_label="Objective 1",
y_label="Objective 2",
optimisations=["max", "max"],
title="Solutions in two-objective space"
).show()
An animated visualisation
Let's demonstrate the same visualisation applied to solutions over time.
solutions = [
{'order': 20200101, 'objv_1': 40, 'objv_2': 12},
{'order': 20200101, 'objv_1': 40, 'objv_2': 12},
{'order': 20200101, 'objv_1': 40, 'objv_2': 12},
{'order': 20200104, 'objv_1': 40, 'objv_2': 12},
{'order': 20200104, 'objv_1': 40, 'objv_2': 12},
{'order': 20200104, 'objv_1': 40, 'objv_2': 14},
{'order': 20200109, 'objv_1': 40, 'objv_2': 12},
{'order': 20200109, 'objv_1': 45, 'objv_2': 12},
{'order': 20200109, 'objv_1': 45, 'objv_2': 10},
{'order': 20200112, 'objv_1': 50, 'objv_2': 12},
{'order': 20200112, 'objv_1': 50, 'objv_2': 11},
{'order': 20200112, 'objv_1': 50, 'objv_2': 10},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200115, 'objv_1': 50, 'objv_2': 12},
{'order': 20200120, 'objv_1': 60, 'objv_2': 8},
{'order': 20200120, 'objv_1': 60, 'objv_2': 8},
{'order': 20200120, 'objv_1': 60, 'objv_2': 8},
{'order': 20200123, 'objv_1': 60, 'objv_2': 8},
{'order': 20200123, 'objv_1': 60, 'objv_2': 8},
{'order': 20200123, 'objv_1': 60, 'objv_2': 8},
{'order': 20200123, 'objv_1': 80, 'objv_2': 3},
{'order': 20200123, 'objv_1': 30, 'objv_2': 20},
{'order': 20200125, 'objv_1': 30, 'objv_2': 20},
{'order': 20200125, 'objv_1': 10, 'objv_2': 20},
{'order': 20200129, 'objv_1': 120, 'objv_2': 50},
{'order': 20200129, 'objv_1': 50, 'objv_2': 120},
{'order': 20200129, 'objv_1': 50, 'objv_2': 120},
{'order': 20200129, 'objv_1': 50, 'objv_2': 120},
{'order': 20200130, 'objv_1': 100, 'objv_2': 100},
]
In this case we will use it for monitoring exercise, however, it can be useful for illustrating and understanding the performance of solutions throughout the optimisation process.
events = [
{
"order": 20200101,
"event": "My first ever gym visit!"
},
{
"order": 20200109,
"event": "I went a little heavier today!"
},
{
"order": 20200120,
"event": "Three solid sets of 60 kg!"
},
{
"order": 20200129,
"event": "Broke some records today!"
}
]
We've made use of the events
feature in PlotAPI, which can highlight information throughout the visualisation. This can be useful to indicate algorithmic state changes.
ParetoFront(solutions,
events=events,
zoomed=False,
title="Barbell Bench Press",
objv_1_unit=" kg",
objv_2_unit=" reps",
x_label="Weight(kg)",
y_label="Reps").show()
The above visualisation will progress automatically from order to order (or generation to generation), or manually explored using the green arrow buttons.
Conclusion
Visualisations are an important part of the optimisation process, whether it's for the engineer during the optimisation process, or a decision maker at the end of one.
You can find more information on the specialised ParetoFront
visualisation type at PlotAPI.
-
S. Rostami, F. Neri, and M. Epitropakis. Progressive preference articulation for decision making in multi-objective optimisation problems, 24(4):315-335, 2017 ↩