          except tk.TclError:
              # Catch non-existent tree view when rebuilding the GUI
              pass
  
      def select_item(self, event):
          """ Update the session summary info with
              the selected item or launch graph """
          region = self.tree.identify("region", event.x, event.y)
          selection = self.tree.focus()
          values = self.tree.item(selection, "values")
          if values:
              logger.debug("Selected values: %s", values)
              self.selected_id.set(values[0])
              if region == "tree" and self.check_valid_data(values):
                  datapoints = int(values[self.columns.index("iterations")])
 
</s> remove             self.selected_id.set(values[0])
            if region == "tree" and self.check_valid_data(values):
                datapoints = int(values[self.columns.index("iterations")])
                self.data_popup(datapoints)

    def check_valid_data(self, values):
        """ Check there is valid data available for popping up a graph """
        col_indices = [self.columns.index("batch"), self.columns.index("iterations")]
 </s> add             self._selected_id.set(values[0])
            if region == "tree" and self._check_valid_data(values):
                data_points = int(values[self._columns.index("iterations")])
                self._data_popup(data_points)

    def _check_valid_data(self, values):
        """ Check there is valid data available for popping up a graph.

        Parameters
        ----------
        values: list
            The values that exist for a single session that are to be validated
        """
        col_indices = [self._columns.index("batch"), self._columns.index("iterations")] </s> remove             self.tree.delete(* self.tree.get_children())
            self.tree.configure(height=1)
 </s> add             self._tree.delete(* self._tree.get_children())
            self._tree.configure(height=1) </s> remove             graph.calcs.args["smooth_amount"] = smooth_amount
 </s> add             graph.calcs.set_smooth_amount(smooth_amount)

    def _iteration_limit_callback(self, *args):
        """ Limit the amount of data displayed in the live graph on a iteration slider
        variable change. """
        try:
            limit = self.vars["display_iterations"].get()
        except tk.TclError:
            # Don't update when there is no value in the variable
            return
        logger.debug("Updating graph iteration limit: (new_value: %s, args: %s)",
                     limit, args)
        for graph in self.subnotebook.children.values():
            graph.calcs.set_iterations_limit(limit)

    def _display_data_callback(self, line, variable):
        """ Update the displayed graph lines based on option check button selection.

        Parameters
        ----------
        line: str
            The line to hide or display
        variable: :class:`tkinter.BooleanVar`
            The tkinter variable containing the ``True`` or ``False`` data for this display item
        """
        var = variable.get()
        logger.debug("Updating display %s to %s", line, var)
        for graph in self.subnotebook.children.values():
            graph.calcs.update_selections(line, var) </s> remove         Returns
        -------
        dict
            The loss name as key with list of loss values as value
 </s> add         Parameters
        ----------
        amount: float
            The amount of smoothing to apply to smoothed graph
        """
        update = max(min(amount, 0.999), 0.001)
        logger.debug("Setting smooth amount to: %s (provided value: %s)", update, amount)
        self._args["smooth_amount"] = update

    def update_selections(self, selection, option):
        """ Update the type of selected data.

        Parameters
        ----------
        selection: str
            The selection to update (as can exist in :attr:`_selections`)
        option: bool
            ``True`` if the selection should be included, ``False`` if it should be removed
        """
        # TODO Somewhat hacky, to ensure values are inserted in the correct order. Fine for
        # now as this is only called from Live Graph and selections can only be "raw" and
        # smoothed.
        if option:
            if selection not in self._selections:
                if selection == "raw":
                    self._selections.insert(0, selection)
                else:
                    self._selections.append(selection)
        else:
            if selection in self._selections:
                self._selections.remove(selection)

    def set_iterations_limit(self, limit):
        """ Set the number of iterations to display in the calculations.

        If a value greater than 0 is passed, then the latest iterations up to the given
        limit will be calculated.

        Parameters
        ----------
        limit: int
            The number of iterations to calculate data for. `0` to calculate for all data </s> remove             self.tree.insert("", "end", **kwargs)
 </s> add             self._tree.insert("", "end", **kwargs)
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
          except tk.TclError:
              # Catch non-existent tree view when rebuilding the GUI
              pass
  
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
    def _select_item(self, event):
        """ Update the session summary info with the selected item or launch graph.

        If the mouse is clicked on the graph icon, then the session summary pop-up graph is
        launched. Otherwise the selected ID is stored.

        Parameters
        ----------
        event: :class:`tkinter.Event`
            The tkinter mouse button release event
        """
        region = self._tree.identify("region", event.x, event.y)
        selection = self._tree.focus()
        values = self._tree.item(selection, "values")
          if values:
              logger.debug("Selected values: %s", values)
              self.selected_id.set(values[0])
              if region == "tree" and self.check_valid_data(values):
                  datapoints = int(values[self.columns.index("iterations")])
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 GUI - Stats optimization (#1067)

* Faster stat loading + caching

* Compress data in cache

* Optimize some calculations

* Vectorize smoothing

* stats.Calculations optimized

* Load latest training data from live iterator

* Add options to training graph 
lib/gui/display_analysis.py