Empirical attainment function plot#
Plot a 2d EAF surface#
The empirical attainment function can used to visualise the spread of solutions when looking at a multi-objective optimisation problem. This can be especially usefuly when comparing two different algorithms, or different parameters of the same algorithm.
When plotting a single algorithm,the plot_eaf
function requires a numpy array of EAF points, such as is created by the get_eaf
function.
import eafpy as eaf
dat = eaf.read_datasets("input1.dat")
eafs = eaf.get_eaf(dat, percentiles = [25, 50, 75, 100])
fig = eaf.plot_eaf(eafs)
fig.show()
Plot multiple algorithms on the same graph#
To plot multiple EAF data on the same graph, such as comparing the median result of two algorithms, the dataset
argument should be a dictionary. The type
argument can be any of lines
, fill
or points
.
import eafpy as eaf
# Generate random non-dominated data points for demonstration
data_points1 = eaf.rand_non_dominated_sets(num_points= 100, num_sets=10)
data_points2 = eaf.rand_non_dominated_sets(num_points= 100, num_sets=10)
eaf1 = eaf.get_eaf(data_points1,percentiles=[0,25,50, 75, 100] )
eaf2 = eaf.get_eaf(data_points2, percentiles=[0,25, 50, 75, 100])
fig = eaf.plot_eaf({'NSGA-II' : eaf1, 'MOEA/D ' : eaf2}, type ="lines", percentiles=[50])
fig.show()
Customising EAF plots - Combining different types and styling#
In this example, the median value (50th percentile) of algorithm 2 is compared to the filled EAF plot of algorithm 1.
The
type
argument can be a list defining the plot type of each datasetThe
percentiles
argument chooses which percentiles to plot for every algorithm. It must exist in the eaf data - so ensure that it is produced fromget_eaf
The
colorway
,fill_border_colours
andpercentiles
arguments can accept a 2d list, configuring each EAF seperatelyThe “colorway” argument configures the colours of the traces. See more about colorway
The
fill_border_colours
argument defines the colour of the percentile boundary lines in a fill plot. It can be set to"rgba(0,0,0,0)"
(invisible) to remove them.
The
trace_names
argument can over-ride the default figure names. The default is: “{Dictonary key name} - {percentile}”Plotly layout named arguments can be used such as
legend_title_text
. See style plots page
import eafpy as eaf
# Generate random non-dominated data points
data_points1 = eaf.rand_non_dominated_sets(num_points= 50, num_sets=10)
data_points2 = eaf.rand_non_dominated_sets(num_points= 50, num_sets=10)
eaf1 = eaf.get_eaf(data_points1,percentiles=[0,25,50, 75, 100] )
eaf2 = eaf.get_eaf(data_points2, percentiles=[0,25, 50, 75, 100])
colorway1 = ["darkgrey", "grey", "black"]
fig = eaf.plot_eaf({'NSGA-II' : eaf1, 'MOEA/D ' : eaf2},
type =["fill", "line"],
percentiles=[[0,50,100], [50]],
colorway= [colorway1, "darkblue"],
fill_border_colours = "rgba(0,0,0,0)",
trace_names=["Algorithm 1 Best", "Algorithm 1 Median", "Algorithm 1 Worst", "Algorithm 2 Median"],
legend_title_text="Cool legend title"
)
fig.show()
Emphasize algorithms using line_dashes
and line_width
#
Using the properties line_dashes
and line_width
you certain lines/ algorithms can be be emphasized.
For example in this plot, the “Monkey King” algorithm is emphasized by making its best and worst lines thicker than others, and by making it’s line_dashes
argument different to the other algorithms.
line_dashes
Defines whether lines are solid, dashed, dotted etc, It can be one of: ‘solid’, ‘dot’, ‘dash’, ‘longdash’, ‘dashdot’, ‘longdashdot’. It can be accept one of:
A single value defining the type for all lines in the plot
A list with same length as the number of different algorithms, setting the line type for each algorithm
A 2d list, with each sub-list containg values for every trace within the algorithm
A combination of argument types (2 and 3) eg a single value and list is also accepted (see example below)
line_width
changes the line thickness. It’s can also be a single value, list or 2d list as with line_dashes
import eafpy as eaf
# Generate sets of random non-dominated data points
data_points = [eaf.rand_non_dominated_sets(num_points= 50, num_sets=10) for i in range(3)]
eafs = [eaf.get_eaf(dataset, percentiles=[0,50,100]) for dataset in data_points]
fig = eaf.plot_eaf({'Firefly ' : eafs[0], 'Monkey King' : eafs[1], 'Particle Swarm' : eafs[2]},
type= "lines",
percentiles=[0,100],
colorway= ["black", "blue", "darkgreen"],
line_dashes=["dot", ["solid", "dash"], "dot"],
line_width=[1,3,1] # Emphasize second algorithm by making the lines thicker
)
fig.show()
Customise the legend#
The legend_preset
argument of plot_eaf
can be used to configure the legends position to one of the presets, or to set the title text, background colour and border colour of the legend.
legend_preset
can be a string setting the legend position preset. The preset positions available are: "outside_top_right"
, "outside_top_left"
, "top_right"
, "bottom_right"
, "top_left"
, "bottom_left"
,"centre_top_right"
, "centre_top_left"
,"centre_bottom_right"
, "centre_bottom_left"
. The default value is "centre_top_right"
legend_preset
can also be a list or dictionary describing the legend position, title text, background colour and border colour:
legend_preset = dict(position = "top_right", text="Legend title text", colour = "black", border_colour="darkblue")
# Dictionary argumentlegend_preset =["top_left", "Legend title text", "grey", black]
list argument. Set an argument toNone
if you don’t want to change something. You can set the text argument to “” to make the legend title disappear, or set the colour a “invisible” to remove the legend background or border.
For any more complex legend requirements, see the plotly legend documentation
Legend example - Position and background colour#
Here the legend is set to be outside the plot, the legend title is removed, and it’s background is set to a transparent blue colour
import eafpy as eaf
dat = eaf.read_datasets("input1.dat")
eafs = eaf.get_eaf(dat, percentiles=[0,50,100])
fig = eaf.plot_eaf(eafs, legend_preset=["outside_top_right", "", "rgba(50,192,192, 0.5)", None], trace_names=["Worst", "Median", "Best"])
fig.show()
Legend example - Border colour#
In this example the dictionary interface is used. The legend position and legend border colour is updated
import eafpy as eaf
dat = eaf.rand_non_dominated_sets(60)
eafs = eaf.get_eaf(dat, percentiles=[0,33,66,100])
colorway = eaf.colour.discrete_colour_gradient("lightblue", "darkblue",4)
fig = eaf.plot_eaf(eafs, type="lines", colorway = colorway, line_width =4, legend_preset=dict(position="top_right", border_colour="darkblue"))
fig.show()