From fc6c61dc8cb62913f59eeae7ad24e900d0955c70 Mon Sep 17 00:00:00 2001 From: jh777916 Date: Wed, 13 Sep 2023 16:34:34 +0200 Subject: [PATCH] Cleaning and adding some comments ... --- .../src/python/controller/PlotController.py | 1 - .../src/python/controller/utils.py.in | 1 + tools/CurvePlot/src/python/model/BarModel.py | 6 +- .../CurvePlot/src/python/model/CurveModel.py | 1 + tools/CurvePlot/src/python/model/Model.py | 13 ++- .../CurvePlot/src/python/model/PlotManager.py | 9 +- tools/CurvePlot/src/python/model/StemModel.py | 3 +- tools/CurvePlot/src/python/views/BarView.py | 7 +- tools/CurvePlot/src/python/views/CurveView.py | 1 + tools/CurvePlot/src/python/views/StemView.py | 9 -- tools/CurvePlot/src/python/views/XYView.py | 87 +++++-------------- 11 files changed, 42 insertions(+), 96 deletions(-) diff --git a/tools/CurvePlot/src/python/controller/PlotController.py b/tools/CurvePlot/src/python/controller/PlotController.py index 2812bc805..8f3ff17cb 100644 --- a/tools/CurvePlot/src/python/controller/PlotController.py +++ b/tools/CurvePlot/src/python/controller/PlotController.py @@ -824,7 +824,6 @@ class PlotController(object): cps.setTitle(cps_title) cps.addCurve(bm) - Logger.Debug(" --- model ID when adding the barplot : {}".format(bm.getID())) mp = self._curveTabsView.mapModId2ViewId() xyview_id = mp[cps.getID()] diff --git a/tools/CurvePlot/src/python/controller/utils.py.in b/tools/CurvePlot/src/python/controller/utils.py.in index ef70e904f..df6b1251d 100644 --- a/tools/CurvePlot/src/python/controller/utils.py.in +++ b/tools/CurvePlot/src/python/controller/utils.py.in @@ -98,6 +98,7 @@ def flatten(xs): """ Takes a container (list or tuple) that can contain other list/tuples and returns a list of all the element as flattened. Useful to obtain artists from matplotlib plotting methods. + @note Used in the onPick() slot method in XYView @return Flattened list containing all the elements (OR returns xs if xs is not iterable) """ if hasattr(xs, '__iter__'): diff --git a/tools/CurvePlot/src/python/model/BarModel.py b/tools/CurvePlot/src/python/model/BarModel.py index b62f603d5..148f658da 100644 --- a/tools/CurvePlot/src/python/model/BarModel.py +++ b/tools/CurvePlot/src/python/model/BarModel.py @@ -34,8 +34,7 @@ class BarModel(Model): self._xaxisIndex = 0 # By default the first column of the table is used for the X-s self._heightIndex = heightIndex # column index in the table, corresponding to the bar height self._widthIndex = widthIndex # column index in the table, corresponding to the bar width - # self._alignX = "center" if (isDirac) else "edge" # X alignment property, if not Dirac, - # alignment is set to the left edge + def clone(self): ret = BarModel(self._controller) @@ -105,6 +104,7 @@ class BarModel(Model): self._xaxisIndex = idx if not silent: self.notifyChange("XAxisIndexChange") - + + # Overloading to access the plotID instead of the Model ID def getID(self): return self._idPlot diff --git a/tools/CurvePlot/src/python/model/CurveModel.py b/tools/CurvePlot/src/python/model/CurveModel.py index 7db4e703f..56e4cb40a 100644 --- a/tools/CurvePlot/src/python/model/CurveModel.py +++ b/tools/CurvePlot/src/python/model/CurveModel.py @@ -84,6 +84,7 @@ class CurveModel(Model): if not silent: self.notifyChange("XAxisIndexChange") + # Overloading to access the plotID instead of the Model ID def getID(self): return self._idPlot \ No newline at end of file diff --git a/tools/CurvePlot/src/python/model/Model.py b/tools/CurvePlot/src/python/model/Model.py index d0012648c..201390444 100644 --- a/tools/CurvePlot/src/python/model/Model.py +++ b/tools/CurvePlot/src/python/model/Model.py @@ -31,14 +31,19 @@ class Model(object): def __init__( self, controller ): """Constructor""" - # Counting instances of classes (Model) and subclasses - for cls in self.__class__.__mro__: - self.COUNT_MODELS[cls.__name__] += 1 - self._name = None self._controller = controller self._id = self.__GenerateID() # A unique ID for this class of object + # This part is added to "hack" the initial ID and manage different kind of plot models + # An intermediary "PlotModel" class with its own kind of ID + # (between Model and Model classes) would be useful to use as an interface + # instead of using this kind of hack + + # Counting instances of classes (Model) and subclasses + for cls in self.__class__.__mro__: + self.COUNT_MODELS[cls.__name__] += 1 + # A unique ID for the traces (Curves, Bars and Stems), starting from 0 self._idPlot = self.COUNT_MODELS["CurveModel"] \ + self.COUNT_MODELS["BarModel"] \ diff --git a/tools/CurvePlot/src/python/model/PlotManager.py b/tools/CurvePlot/src/python/model/PlotManager.py index f2b474c90..eca716800 100644 --- a/tools/CurvePlot/src/python/model/PlotManager.py +++ b/tools/CurvePlot/src/python/model/PlotManager.py @@ -50,23 +50,18 @@ class PlotManager(Model): return ps return None - def setCurrentCurve(self, curveId, silent=False): # TAG CHECK : SILENT ajouté - Logger.Debug("PlotManager::setCurrentCurve() --> CALL") + def setCurrentCurve(self, curveId, silent=False): # Added the "silent" arg ps = self.getPlotSetContainingCurve(curveId) if ps is None and curveId != -1: raise ValueError("Invalid curve ID (%d)!" % curveId) - Logger.Debug("PlotManager::setCurrentCurve() --> CALL clearAllCurrentCurve()") self.clearAllCurrentCurve(silent=True) # silencing the CurrentCurveChange : 1 draw less - Logger.Debug("PlotManager::setCurrentCurve() --> DONE clearAllCurrentCurve()") if curveId == -1: return -1 ps_id = ps.getID() currPs = self.getCurrentPlotSet() if currPs is None or currPs.getID() != ps_id: self.setCurrentPlotSet(ps_id) - Logger.Debug("PlotManager::setCurrentCurve() --> CALL ps.setCurrentCurve()") ps.setCurrentCurve(curveId, silent=silent) # will actually notify CurrentCurveChange - Logger.Debug("PlotManager::setCurrentCurve() --> DONE") return ps_id def getCurrentCurve(self): @@ -77,7 +72,7 @@ class PlotManager(Model): def clearAllCurrentCurve(self, silent=False): for psID in self._plotSets: - self._plotSets[psID].setCurrentCurve(-1, silent=silent) # ajout du silent : 1 draw less + self._plotSets[psID].setCurrentCurve(-1, silent=silent) # passing the silent arg if not silent: self.notifyChange("CurrentCurveChange") diff --git a/tools/CurvePlot/src/python/model/StemModel.py b/tools/CurvePlot/src/python/model/StemModel.py index 4f9339e22..6cc19c6b0 100644 --- a/tools/CurvePlot/src/python/model/StemModel.py +++ b/tools/CurvePlot/src/python/model/StemModel.py @@ -83,7 +83,8 @@ class StemModel(Model): self._xaxisIndex = idx if not silent: self.notifyChange("XAxisIndexChange") - + + # Overloading to access the plotID instead of the Model ID def getID(self): return self._idPlot \ No newline at end of file diff --git a/tools/CurvePlot/src/python/views/BarView.py b/tools/CurvePlot/src/python/views/BarView.py index 1c4eb4e4a..8e65c4293 100644 --- a/tools/CurvePlot/src/python/views/BarView.py +++ b/tools/CurvePlot/src/python/views/BarView.py @@ -34,10 +34,7 @@ class BarView(View): self._initialOpacity = None self._initialZOrder = None self._parentXYView = parentXYView - - self._facecolor = None - self._opacity = None - + def setMPLAxes(self, axes): self._mplAxes = axes @@ -61,8 +58,6 @@ class BarView(View): self._initialOpacity = self._mplArtist[0].get_alpha() self._initialZOrder = self._mplArtist[0].get_zorder() - # print(f"TYPE ARTISTS BARS: {type(self._mplArtist)}") - # print(f"SIZE ARTISTS BARS: {len(self._mplArtist)}") def onCurveTitleChange(self): if self._mplArtist is None: diff --git a/tools/CurvePlot/src/python/views/CurveView.py b/tools/CurvePlot/src/python/views/CurveView.py index a7ead94ad..990b6ac81 100644 --- a/tools/CurvePlot/src/python/views/CurveView.py +++ b/tools/CurvePlot/src/python/views/CurveView.py @@ -34,6 +34,7 @@ class CurveView(View): self._initialZOrder = None self._parentXYView = parentXYView + # Some of these seems to be unused ... self._marker = None self._color = None self._lineStyle = None diff --git a/tools/CurvePlot/src/python/views/StemView.py b/tools/CurvePlot/src/python/views/StemView.py index 3007a64e9..5333c7205 100644 --- a/tools/CurvePlot/src/python/views/StemView.py +++ b/tools/CurvePlot/src/python/views/StemView.py @@ -34,11 +34,6 @@ class StemView(View): self._initialZOrder = None self._parentXYView = parentXYView - self._marker = None - self._color = None - self._lineStyle = None - self._opacity = None - def setMPLAxes(self, axes): self._mplAxes = axes @@ -68,10 +63,6 @@ class StemView(View): for lin in self._mplArtist[1]: lin.set_picker(self._PICKER_PRECISION) - Logger.Debug(f"** Init lw: {self._initialLineWidth}") - Logger.Debug(f"** Init opacity : {self._initialOpacity}") - Logger.Debug(f"** Init zorder : {self._initialZOrder}") - def onCurveTitleChange(self): if self._mplArtist is None: return diff --git a/tools/CurvePlot/src/python/views/XYView.py b/tools/CurvePlot/src/python/views/XYView.py index dcf016fef..01dbf539d 100644 --- a/tools/CurvePlot/src/python/views/XYView.py +++ b/tools/CurvePlot/src/python/views/XYView.py @@ -127,25 +127,20 @@ class XYView(View): newC.setMPLAxes(self._mplAxes) newC.draw() newC.setMarker(self.getMarker(go_next=True)) - Logger.Debug(" ** > appendCurve() crvID = {}".format(curveID)) self._curveViews[curveID] = newC def appendBarplot(self, curveID): - Logger.Debug(" > Appending a bar model") newB = BarView(self._controller, self) newB.setModel(self._model._curves[curveID]) newB.setMPLAxes(self._mplAxes) newB.draw() - Logger.Debug(" ** > appendBarplot() crvID = {}".format(curveID)) self._curveViews[curveID] = newB def appendStemplot(self, curveID): - Logger.Debug(" > Appending a stem model") newS = StemView(self._controller, self) newS.setModel(self._model._curves[curveID]) newS.setMPLAxes(self._mplAxes) newS.draw() - Logger.Debug(" ** > appendStemplot() crvID = {}".format(curveID)) self._curveViews[curveID] = newS def removeCurve(self, curveID): @@ -197,10 +192,7 @@ class XYView(View): def onPick(self, event): """ MPL callback when picking """ - Logger.Debug(" > Event onPick : {} ---> START EVENT".format(event)) - - if event.mouseevent.dblclick: - Logger.Debug(" > > > Double click !") + Logger.Debug(" > Event onPick() ---> Start") if (event.mouseevent.button == 1 and not event.mouseevent.dblclick): selected_id = -1 @@ -223,28 +215,25 @@ class XYView(View): break # Checks if the plot symbol legend has been clicked - for leg_idx,legHandler in enumerate(self._legend.legendHandles): - if legHandler is a : - # Gets the associated plot from the axes.legend handles - selected_plot = h[leg_idx] - # Gets the id from the curveViews - for crv_id, cv in list(self._curveViews.items()): - if selected_plot is cv._mplArtist: - selected_id = crv_id - break - - Logger.Debug("Legend {} selected".format(selected_id)) + if selected_id == -1: + for leg_idx,legHandler in enumerate(self._legend.legendHandles): + if legHandler is a : + # Gets the associated plot from the axes.legend handles + selected_plot = h[leg_idx] + # Gets the id from the curveViews + for crv_id, cv in list(self._curveViews.items()): + if selected_plot is cv._mplArtist: + selected_id = crv_id + break # Checks if an artist has been picked inside the plotting area - for crv_id, cv in list(self._curveViews.items()): - # Permits to get back to the intiial opacity of each Artists ... let's keep it in case we want that - # self._curveViews[crv_id].setAlpha(self._curveViews[crv_id].getInitialAlpha()) - + if selected_id == -1: + for crv_id, cv in list(self._curveViews.items()): # Checks if the picked artist is in the list of artists - if a in flatten(cv._mplArtist): - selected_id = crv_id - Logger.Debug("Curve/Barplot/Stemplot {} selected".format(selected_id)) - break + if a in flatten(cv._mplArtist): + selected_id = crv_id + Logger.Debug("Curve/Barplot/Stemplot {} selected".format(selected_id)) + break # Use the plotmanager to set the current curve so that other plot sets get their current reset: if self._currCrv is not None: @@ -252,23 +241,17 @@ class XYView(View): # Setting the current curve only if different if event.mouseevent.dblclick: # if double click (2nd onPick event on same artist) : set the _currCrv variable without notifying - Logger.Debug(" onPick::setCurrentCurve() SILENT TRUE ...") self._controller._plotManager.setCurrentCurve(selected_id, silent=True) - Logger.Debug(" onPick::setCurrentCurve() SILENT TRUE : DONE") else : # if NOT double click : set the _currCrv variable and notifying (repaint) - Logger.Debug(" onPick::setCurrentCurve() SILENT FALSE ...") self._controller._plotManager.setCurrentCurve(selected_id, silent=False) - Logger.Debug(" onPick::setCurrentCurve() SILENT FALSE : DONE") else : - Logger.Debug(" onPick::setCurrentCurve() SILENT FALSE ...") self._controller._plotManager.setCurrentCurve(selected_id, silent=False) - Logger.Debug(" onPick::setCurrentCurve() SILENT FALSE : DONE") else : #if event.mouseevent.dblclick: self.showOnlySelected() - Logger.Debug(" > Event onPick : {} ---> END EVENT".format(event)) + Logger.Debug(" > Event onPick() ---> End") def createAndAddLocalAction(self, icon_file, short_name): @@ -279,7 +262,7 @@ class XYView(View): self._mplCanvas = FigureCanvasQTAgg(self._mplFigure) self._mplCanvas.installEventFilter(self._eventHandler) self._mplCanvas.mpl_connect('pick_event', self.onPick) - + self._mplAxes = self._mplFigure.add_subplot(1, 1, 1) self._plotWidget = PlotWidget() self._toobarMPL = NavigationToolbar2QT(self._mplCanvas, None) @@ -378,7 +361,7 @@ class XYView(View): filters, trQ("DUMP_VIEW_FILE"), False ) - name = str(fileName[0]) # Modif portage + name = str(fileName[0]) # Correcting some bug here Logger.Debug(f" >> Save fig filename : {name}") if name != "": self._mplAxes.figure.savefig(name) @@ -730,37 +713,17 @@ class XYView(View): pass def onCurrentCurveChange(self): - Logger.Debug("XYView::onCurrentCurveChange() : CALL") curr_crv2 = self._model.getCurrentCurve() - - if self._currCrv is None : - id_debug1 = "None" - else : - id_debug1 = self._currCrv.getID() - - if curr_crv2 is None : - id_debug2 = "None" - else : - id_debug2 = curr_crv2.getID() - - Logger.Debug(f"XYView::onCurrentCurveChange() : Curr crv 1 ID : {id_debug1}") - Logger.Debug(f"XYView::onCurrentCurveChange() : Curr crv 2 ID : {id_debug2}") - if curr_crv2 != self._currCrv: - Logger.Debug("XYView::onCurrentCurveChange() : NEW CURVE SELECTED") if self._currCrv is not None: - Logger.Debug("XYView::onCurrentCurveChange() : Toggle -> False") view = self._curveViews[self._currCrv.getID()] view.toggleHighlight(False) if not curr_crv2 is None: - Logger.Debug("XYView::onCurrentCurveChange() : Toggle -> True") view = self._curveViews[curr_crv2.getID()] view.toggleHighlight(True) self._currCrv = curr_crv2 self.showHideLegend(repaint=False) # redo legend self.repaint() - Logger.Debug("XYView::onCurrentCurveChange() : REPAINT") - Logger.Debug("XYView::onCurrentCurveChange() : END") def changeFormatAxis(self) : if not self.__repaintOK(): @@ -792,25 +755,19 @@ class XYView(View): set_mod = set(self._model._curves.keys()) set_view = set(self._curveViews.keys()) - # Logger.Debug(" --- List of models ID: {}".format(set_mod)) - # Logger.Debug(" --- List of views ID: {}".format(set_view)) - # Deleted/Added curves: dels = set_view - set_mod added = set_mod - set_view - # Logger.Debug(" --- List of dels ID: {}".format(dels)) - # Logger.Debug(" --- List of added ID: {}".format(added)) - for d in dels: self.removeCurve(d) if not len(self._curveViews): # Reset color cycle - Logger.Debug(" ---- !! Resetting color cycle ...") self._mplAxes.set_prop_cycle(None) - for a in added: + # This would evolve if we introduce an intermediary class Model->"PlotModel"->BarModel/CurveModel/StemModel + for a in added: if ( self._model._curves[a]._name == "CurveModel" ) : self.appendCurve(a) elif ( self._model._curves[a]._name == "BarModel" ) : -- 2.39.2