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 dataset

  • The percentiles argument chooses which percentiles to plot for every algorithm. It must exist in the eaf data - so ensure that it is produced from get_eaf

  • The colorway, fill_border_colours and percentiles arguments can accept a 2d list, configuring each EAF seperately

    • The “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:

  1. A single value defining the type for all lines in the plot

  2. A list with same length as the number of different algorithms, setting the line type for each algorithm

  3. A 2d list, with each sub-list containg values for every trace within the algorithm

    1. 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 argument

  • legend_preset =["top_left", "Legend title text", "grey", black] list argument. Set an argument to None 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()