diff --git a/src/mlpro/bf/math/properties.py b/src/mlpro/bf/math/properties.py index 9dd58a510..1053a70ed 100644 --- a/src/mlpro/bf/math/properties.py +++ b/src/mlpro/bf/math/properties.py @@ -12,10 +12,11 @@ ## -- numpy arrays ## -- 2024-05-04 0.4.0 DA Introduction of type aliases ## -- 2024-05-05 0.5.0 DA Redesign: alignment with Python's managed attributes +## -- 2024-05-06 0.6.0 DA Completion of plot functionality ## ------------------------------------------------------------------------------------------------- """ -Ver. 0.5.0 (2024-05-05) +Ver. 0.6.0 (2024-05-06) This module provides a systematics for enriched managed properties. MLPro's enriched properties store any data like class attributes and they can be used like class attributes. They extend the @@ -220,12 +221,12 @@ def __init__( self ): def add_property( self, p_name : PropertyName, p_derivative_order_max : DerivativeOrderMax = 0, - p_cls : PropertyClass = Property ): + p_cls : PropertyClass = Property, + p_visualize : bool = False ): """ - Defines a new property by it's name. Optionally, auto-derivation can be added for numeric - properties (scalar or vectorial). The property itself is returned and also stored in the - protected dictionary self._properties. Furthermore, a new attribute with the same name is - added to the object and can be accessed via self.[p_name]. + Adds a new managed property as an attribute to the own class. Optionally, auto-derivation can + be added for numeric properties (scalar or vectorial). The property is stored in the protected + dictionary self._properties and can be accessed directly via self.[p_name]. Parameters ---------- @@ -235,17 +236,35 @@ def add_property( self, Maximum order of auto-generated derivatives. Default = 0 (no auto-derivation). p_cls : PropertyClass Optional property class to be used. Default = Property. + p_visualize : bool + Boolean switch for visualisation. Default = False. """ - prop_obj = p_cls( p_derivative_order_max = p_derivative_order_max ) + prop_obj = p_cls( p_derivative_order_max = p_derivative_order_max, p_visualize = p_visualize ) self._properties[p_name] = prop_obj setattr(self.__class__, p_name, prop_obj ) ## ------------------------------------------------------------------------------------------------- - def add_properties(self, p_property_definitions : PropertyDefinitions ): + def add_properties( self, + p_property_definitions : PropertyDefinitions, + p_visualize : bool = False ): + """ + Adds new managed properties to the own class. See method add_property() for further details. + + Parameters + ---------- + p_property_definitions : PropertyDefinitions + List of property definitions. + p_visualize : bool + Boolean switch for visualisation. Default = False. + """ + for p in p_property_definitions: - self.add_property( p_name = p[0], p_derivative_order_max = p[1], p_cls = p[2] ) + self.add_property( p_name = p[0], + p_derivative_order_max = p[1], + p_cls = p[2], + p_visualize = p_visualize ) ## ------------------------------------------------------------------------------------------------- diff --git a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/basics.py b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/basics.py index f702fa669..b331382bb 100644 --- a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/basics.py +++ b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/basics.py @@ -31,10 +31,11 @@ ## -- 2024-04-30 1.1.0 DA Class Cluster: new parent class Renormalizable ## -- 2024-05-02 1.2.0 DA/SK Class Cluster: first definition of concrete properties ## -- 2024-05-04 1.3.0 DA Class Cluster: generic property systematics +## -- 2024-05-06 1.4.0 DA Plot functionality ## ------------------------------------------------------------------------------------------------- """ -Ver. 1.3.0 (2024-05-04) +Ver. 1.4.0 (2024-05-06) This module provides templates for clusters to be used in cluster analyzer algorithms. """ @@ -86,7 +87,10 @@ def __init__( self, Properties.__init__( self ) for p in p_properties: - self.add_property( p_name=p[0], p_derivative_order_max=p[1], p_cls=p[2] ) + self.add_property( p_name = p[0], + p_derivative_order_max = p[1], + p_cls = p[2], + p_visualize = p_visualize ) ## ------------------------------------------------------------------------------------------------- @@ -106,4 +110,27 @@ def get_membership(self, p_inst : Instance ) -> float: A value 0 means that the given instance is not a member of the cluster. """ - raise NotImplementedError \ No newline at end of file + raise NotImplementedError + + +## ------------------------------------------------------------------------------------------------- + def init_plot(self, p_figure: Figure = None, p_plot_settings: PlotSettings = None): + + if not self.get_visualization(): return + + Plottable.init_plot( self, p_figure=p_figure, p_plot_settings=p_plot_settings) + + for prop in self.get_properties().values(): + prop.init_plot(p_figure=p_figure, p_plot_settings = p_plot_settings) + + +## ------------------------------------------------------------------------------------------------- + def update_plot( self, + p_inst_new: List[Instance] = None, + p_inst_del: List[Instance] = None, + **p_kwargs ): + + if not self.get_visualization(): return + + for prop in self.get_properties().values(): + prop.update_plot(p_inst_new = p_inst_new, p_inst_del = p_inst_del, **p_kwargs) diff --git a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/centroid.py b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/centroid.py index 4be13be2e..89e251c75 100644 --- a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/centroid.py +++ b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/centroid.py @@ -79,14 +79,19 @@ class ClusterCentroid (Cluster): def __init__(self, p_id=None, p_properties: List[Tuple[str, int, type]] = ..., p_visualize: bool = False): super().__init__( p_id=p_id, p_properties=p_properties, p_visualize=p_visualize ) - self.add_properties( [ cprop_centroid ] ) + self.add_properties( p_property_definitions = [ cprop_centroid ], p_visualize = p_visualize ) + self.centroid.set_id( p_id = self.get_id() ) self._centroid_elem : Element = None # ## ------------------------------------------------------------------------------------------------- -# def get_centroid(self) -> Point: -# return self._centroid - + def set_id(self, p_id=None): + super().set_id( p_id = p_id ) + try: + self.centroid.set_id( p_id = p_id ) + except: + pass + ## ------------------------------------------------------------------------------------------------- def get_membership(self, p_inst: Instance) -> float: diff --git a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/properties/centroid.py b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/properties/centroid.py index c629dfcef..c6f5ea4af 100644 --- a/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/properties/centroid.py +++ b/src/mlpro/oa/streams/tasks/clusteranalyzers/clusters/properties/centroid.py @@ -22,12 +22,9 @@ from mlpro.bf.various import * from mlpro.bf.plot import * from mlpro.bf.streams import * -#from mlpro.bf.math.normalizers import Normalizer -#from mlpro.bf.math.geometry import Point -#from typing import List - +from mlpro.bf.various import Id from mlpro.bf.math.geometry import Point -from mlpro.bf.math.properties import PropertyDefinition +from mlpro.bf.math.properties import * from mlpro.oa.streams.tasks.clusteranalyzers.clusters import Cluster @@ -35,12 +32,38 @@ ## ------------------------------------------------------------------------------------------------- ## ------------------------------------------------------------------------------------------------- -class Centroid (Point): +class Centroid (Point, Id): + """ + This managed property provides full centroid functionality including + - managing its position + - optionally its velocity and acceleration as auto-derivatives + - plot functionality + - renormalization + + Hint: please assign the id of the cluster to the centroid as well to get a proper visualization. + + Parameters + ---------- + p_derivative_order_max : DerivativeOrderMax + Maximum order of auto-generated derivatives (numeric properties only). + p_visualize : bool + Boolean switch for visualisation. Default = False. + """ + + C_PLOT_ACTIVE = True + C_PLOT_STANDALONE = False + C_PLOT_VALID_VIEWS = [ PlotSettings.C_VIEW_2D, + PlotSettings.C_VIEW_3D, + PlotSettings.C_VIEW_ND ] + C_PLOT_DEFAULT_VIEW = PlotSettings.C_VIEW_ND -# ## ------------------------------------------------------------------------------------------------- -# def init_plot(self, p_figure: Figure = None, p_plot_settings: PlotSettings = None, **p_kwargs): -# super().init_plot(p_figure, p_plot_settings, **p_kwargs) -# self._centroid.init_plot( p_figure=p_figure, p_plot_settings=p_plot_settings) +## ------------------------------------------------------------------------------------------------- + def __init__( self, + p_derivative_order_max : DerivativeOrderMax = 0, + p_visualize : bool = False ): + + Point.__init__( self, p_derivative_order_max=p_derivative_order_max, p_visualize=p_visualize ) + Id.__init__( self, p_id = 0 ) ## -------------------------------------------------------------------------------------------------