from optimeed.core import delete_indices_from_list, Graphs, Data
[docs]class HowToPlotGraph:
def __init__(self, attribute_x, attribute_y, kwargs_graph=None, excluded=None, exclusively=None, check_if_plot_elem=None):
self.attribute_x = attribute_x
self.attribute_y = attribute_y
if excluded is None:
self.excluded = list()
else:
self.excluded = excluded
if exclusively is None:
self.exclusively = list()
else:
self.exclusively = exclusively
if kwargs_graph is None:
self.kwargs_graph = dict()
else:
self.kwargs_graph = kwargs_graph
self.check_if_plot_elem = check_if_plot_elem
[docs] def exclude_col(self, id_col):
"""Add id_col to exclude from the graph"""
self.excluded.append(id_col)
[docs] def exclusive_col(self, id_col):
"""Set id_col to have exclusivity on the graph"""
self.exclusively = list(id_col)
[docs] def __str__(self):
theStr = ''
theStr += "x: {} \t y: {}".format(self.attribute_x, self.attribute_y)
return theStr
[docs]class CollectionInfo:
def __init__(self, theCollection, kwargs, theID):
self.collection = theCollection
self.kwargs = kwargs
self.id = theID
[docs] def get_collection(self):
return self.collection
[docs] def get_kwargs(self):
return self.kwargs
[docs] def get_id(self):
return self.id
[docs]class LinkDataGraph:
[docs] class _collection_linker:
def __init__(self):
self.collectionsLinked = list()
[docs] def add_link(self, idSlave, idMaster):
self.collectionsLinked.append((idSlave, idMaster))
[docs] def get_collection_master(self, idToGet):
for slave, master in self.collectionsLinked:
if slave == idToGet:
return master
return None
[docs] def is_slave(self, idToCheck):
for slave, master in self.collectionsLinked:
if slave == idToCheck:
return True
return False
[docs] def set_same_master(self, idExistingSlave, idOtherSlave):
"""
:param idExistingSlave: id collection of the existing slave
:param idOtherSlave: id collection of the new slave that has to be linked to an existing master
"""
for slave, master in self.collectionsLinked:
if idExistingSlave == slave:
self.add_link(idOtherSlave, master)
break
def __init__(self):
self.theGraphs = Graphs()
self.collectionInfos = dict() # keys are unique ids of collection
self.HowToPlotGraphs = dict() # keys are ids of graph
self.mappingData = dict() # keys are ids of graph. mappingData[idGraph][idTrace] = idCollection used for trace
self.collectionLinks = self._collection_linker()
self.curr_id = 0
[docs] def add_collection(self, theCollection, kwargs=None):
theId = self.curr_id
if kwargs is None:
kwargs = dict()
theCollectionInfo = CollectionInfo(theCollection, kwargs, theId)
self.collectionInfos[theId] = theCollectionInfo
self.curr_id += 1
return theId
[docs] def add_graph(self, howToPlotGraph):
idGraph = self.theGraphs.add_graph()
self.HowToPlotGraphs[idGraph] = howToPlotGraph
self.mappingData[idGraph] = dict()
return idGraph
[docs] def createGraphs(self):
for idGraph in self.theGraphs.get_all_graphs_ids():
howToPlotGraph = self.get_howToPlotGraph(idGraph)
for collectionInfo in self.collectionInfos.values():
self.create_trace(collectionInfo, howToPlotGraph, idGraph)
return self.theGraphs
@staticmethod
[docs] def get_x_y_to_plot(theCollection, howToPlotGraph):
if howToPlotGraph.attribute_x is None:
x_data = []
else:
x_data = theCollection.get_list_attributes(howToPlotGraph.attribute_x)
y_data = theCollection.get_list_attributes(howToPlotGraph.attribute_y)
min_length = min(len(x_data), len(y_data))
return x_data[:min_length], y_data[:min_length] # Truncate if lengths are not the same
[docs] def get_howToPlotGraph(self, idGraph):
return self.HowToPlotGraphs[idGraph]
[docs] def get_collectionInfo(self, idCollectionInfo):
return self.collectionInfos[idCollectionInfo]
[docs] def create_trace(self, collectionInfo, howToPlotGraph, idGraph):
theCollection = collectionInfo.get_collection()
kwargs_collection = collectionInfo.get_kwargs()
kwargs_graph = howToPlotGraph.kwargs_graph
idCollection = collectionInfo.get_id()
if ((idCollection not in howToPlotGraph.excluded) and (not howToPlotGraph.exclusively)) or (idCollection in howToPlotGraph.exclusively):
x_data, y_data = self.get_x_y_to_plot(theCollection, howToPlotGraph)
kwargs = dict()
kwargs.update(kwargs_graph)
kwargs.update(kwargs_collection)
theData = Data(x_data, y_data, **kwargs)
idTrace = self.theGraphs.add_trace(idGraph, theData)
self.mappingData[idGraph][idTrace] = idCollection
[docs] def get_all_id_graphs(self):
return list(self.mappingData.keys())
[docs] def get_all_traces_id_graph(self, idGraph):
return list(self.get_mappingData_graph(idGraph).keys())
[docs] def update_graphs(self):
for idGraph in self.get_all_id_graphs():
howToPlotGraph = self.HowToPlotGraphs[idGraph]
for idTrace in self.get_all_traces_id_graph(idGraph):
idCollection = self.get_mappingData_trace(idGraph, idTrace)
theCollection = self.collectionInfos[idCollection].get_collection()
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
x, y = self.get_x_y_to_plot(theCollection, howToPlotGraph)
theData.set_data(x, y)
indices_to_plot = list()
if howToPlotGraph.check_if_plot_elem is not None:
for k, elem in enumerate(theCollection.get_data()):
if howToPlotGraph.check_if_plot_elem(elem) and k < len(x):
indices_to_plot.append(k)
theData.set_indices_points_to_plot(indices_to_plot)
[docs] def is_slave(self, idGraph, idTrace):
idColInGraph = self.get_mappingData_trace(idGraph, idTrace)
return self.collectionLinks.is_slave(idColInGraph)
[docs] def get_idCollection_from_graph(self, idGraph, idTrace, getMaster=True):
"""From indices in the graph, get index of corresponding collection"""
idColInGraph = self.get_mappingData_trace(idGraph, idTrace)
if self.collectionLinks.is_slave(idColInGraph) and getMaster:
return self.collectionLinks.get_collection_master(idColInGraph)
else:
return idColInGraph
[docs] def get_collection_from_graph(self, idGraph, idTrace, getMaster=True):
"""From indices in the graph, get corresponding collection"""
return self.collectionInfos[self.get_idCollection_from_graph(idGraph, idTrace, getMaster)].get_collection()
[docs] def get_dataObject_from_graph(self, idGraph, idTrace, idPoint):
theCol = self.get_collection_from_graph(idGraph, idTrace)
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
index_in_data = theData.get_dataIndex_from_graphIndex(idPoint)
return theCol.get_data()[index_in_data]
[docs] def get_dataObjects_from_graph(self, idGraph, idTrace, idPoint_list):
theCol = self.get_collection_from_graph(idGraph, idTrace)
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
indices_in_data = theData.get_dataIndices_from_graphIndices(idPoint_list)
return [theCol.get_data()[index_in_data] for index_in_data in indices_in_data]
[docs] def remove_element_from_graph(self, idGraph, idTrace, idPoint, deleteFromMaster=False):
"""Remove element from the graph, or the master collection"""
theCol = self.get_collection_from_graph(idGraph, idTrace, getMaster=deleteFromMaster)
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
index_in_data = theData.get_dataIndex_from_graphIndex(idPoint)
del theCol.get_data()[index_in_data]
[docs] def remove_elements_from_trace(self, idGraph, idTrace, idPoints, deleteFromMaster=False):
"""Performances optimisation when compared to :meth:`LinkDataGraph.remove_element_from_graph`"""
theCol = self.get_collection_from_graph(idGraph, idTrace, getMaster=deleteFromMaster)
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
indices_in_data = theData.get_dataIndices_from_graphIndices(idPoints)
delete_indices_from_list(indices_in_data, theCol.get_data())
[docs] def link_collection_to_graph_collection(self, id_collection_graph, id_collection_master):
"""
Link data
:param id_collection_graph:
:param id_collection_master:
:return:
"""
self.collectionLinks.add_link(id_collection_graph, id_collection_master)
[docs] def remove_trace(self, idGraph, idTrace):
self.theGraphs.remove_trace(idGraph, idTrace)
del self.mappingData[idGraph][idTrace]
[docs] def get_graph_and_trace_from_collection(self, idCollection):
"""Reverse search: from a collection, get the associated graph"""
res = list()
for idGraph in self.mappingData:
for idTrace in self.get_mappingData_graph(idGraph):
if self.get_mappingData_graph(idGraph)[idTrace] == idCollection:
res.append((idGraph, idTrace))
return res, self.get_collectionInfo(idCollection).get_collection()
[docs] def get_mappingData_graph(self, idGraph):
return self.mappingData[idGraph]
[docs] def get_mappingData_trace(self, idGraph, idTrace):
return self.get_mappingData_graph(idGraph)[idTrace]
[docs] def get_idcollection_from_collection(self, theCollection):
for collectionInfo in self.collectionInfos.values():
if collectionInfo.get_collection() == theCollection:
return collectionInfo.get_id()
[docs] def get_idPoints_from_indices_in_collection(self, idGraph, idTrace, indices_in_collection):
theData = self.theGraphs.get_graph(idGraph).get_trace(idTrace)
return theData.get_graphIndices_from_dataIndices(indices_in_collection)