import numpy as np
from typing import List
[docs]class ReferencePoint(dict):
"""
Reference point for plotting. Should contain a parameter value and an
objective function value, may also contain a color and a legend.
Can be used like a dict.
Attributes
----------
x: ndarray
Reference parameters.
fval: float
Function value, fun(x), for reference parameters.
color: RGBA, optional
Color which should be used for reference point.
auto_color: boolean
flag indicating whether color for this reference point should be
assigned automatically or whether it was assigned by user
legend: str
legend text for reference point
"""
[docs] def __init__(self,
reference=None,
x=None,
fval=None,
color=None,
legend=None):
super().__init__()
if (reference is not None) and ((x is not None) or (fval is not None)):
raise ValueError("Please specify either an argument for reference "
"or for x and fval, but not both.")
# assign legend, may be None
self.legend = legend
if isinstance(reference, dict) or \
isinstance(reference, ReferencePoint):
# Handle case of dict or ReferencePoint
self.x = np.array(reference["x"])
self.fval = reference["fval"]
if "color" in reference.keys():
self.color = reference["color"]
if "auto_color" in reference.keys():
self.auto_color = reference["auto_color"]
else:
self.auto_color = False
else:
self.color = None
self.auto_color = True
if "legend" in reference.keys():
self.legend = reference["legend"]
else:
self.legend = None
elif isinstance(reference, tuple):
# Handle case of tuple
self.x = np.array(reference[0])
self.fval = reference[1]
if len(reference) > 2:
self.color = reference[2]
self.auto_color = False
else:
self.color = None
self.auto_color = True
if reference is None:
if x is not None:
self.x = np.array(x)
else:
raise ValueError('Parameter vector x not passed, but is a '
'mandatory input when creating a reference '
'point. Stopping.')
if fval is not None:
self.fval = fval
else:
raise ValueError('Objective value fval not passed, but is a '
'mandatory input when creating a reference '
'point. Stopping.')
if color is not None:
self.color = color
self.auto_color = False
else:
self.color = None
self.auto_color = True
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(key)
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
def assign_colors(ref):
"""
Assigns colors to reference points, depending on user settings
Parameters
----------
ref: list of ReferencePoint
Reference points, which need to get their color property filled
Returns
-------
ref: list of ReferencePoint
Reference points, which got their color property filled
"""
# loop over reference points
auto_color_count = 0
for i_ref in ref:
if i_ref['auto_color']:
auto_color_count += 1
auto_colors = [[0., 0.5 * (1. + i_auto / auto_color_count), 0., 0.9] for
i_auto in range(auto_color_count)]
# loop over reference points and assign auto_colors
auto_color_count = 0
for i_num, i_ref in enumerate(ref):
if i_ref['auto_color']:
i_ref['color'] = auto_colors[i_num]
auto_color_count += 1
return ref
[docs]def create_references(references=None, x=None, fval=None, color=None,
legend=None) -> List[ReferencePoint]:
"""
This function creates a list of reference point objects from user inputs
Parameters
----------
references: ReferencePoint or dict or list, optional
Will be converted into a list of RefPoints
x: ndarray, optional
Parameter vector which should be used for reference point
fval: float, optional
Objective function value which should be used for reference point
color: RGBA, optional
Color which should be used for reference point.
legend: str
legend text for reference point
Returns
-------
colors: list of RGBA
One for each element in 'vals'.
"""
# parse input (reference)
ref = []
if references is not None:
if isinstance(references, list):
for reference in references:
ref.append(ReferencePoint(reference))
else:
ref.append(ReferencePoint(references))
# parse input (x and fval)
if (x is not None) and (fval is not None):
ref.append(ReferencePoint(x=x, fval=fval, color=color, legend=legend))
# assign colors for reference points which have no user-specified colors
return assign_colors(ref)