          toplevel.tk.call(
              'wm',
              'iconphoto',
              toplevel._w, get_images().icons["favicon"])  # pylint:disable=protected-access
          position = self.data_popup_get_position()
          height = int(900 * scaling_factor)
          width = int(480 * scaling_factor)
          toplevel.geometry("{}x{}+{}+{}".format(str(height),
                                                 str(width),
                                                 str(position[0]),
 
</s> remove         toplevel = SessionPopUp(self.session.modeldir,
                                self.session.modelname,
                                self.selected_id.get(),
                                datapoints)
        toplevel.title(self.data_popup_title())
 </s> add         toplevel = SessionPopUp(self._selected_id.get(),
                                data_points)
        toplevel.title(self._data_popup_title()) </s> remove         for item in data:
            dataset = list(filter(lambda x: x is not None, item))
            if not dataset:
                continue
            ymin.append(min(dataset) * 1000)
            ymax.append(max(dataset) * 1000)
 </s> add         for item in data:  # TODO Handle as array not loop
            ymin.append(np.nanmin(item) * 1000)
            ymax.append(np.nanmax(item) * 1000) </s> remove         if datapoints <= (self.args["avg_samples"] * 2):
 </s> add         if datapoints <= (self._args["avg_samples"] * 2): </s> remove         avgs = list()
        presample = ceil(self.args["avg_samples"] / 2)
        postsample = self.args["avg_samples"] - presample
        datapoints = len(data)
 </s> add         window = self._args["avg_samples"]
        pad = ceil(window / 2)
        datapoints = data.shape[0] </s> remove     def calc_smoothed(self, data):
        """ Smooth the data """
        last = data[0]  # First value in the plot (first time step)
        weight = self.args["smooth_amount"]
        smoothed = list()
        for point in data:
            smoothed_val = last * weight + (1 - weight) * point  # Calculate smoothed value
            smoothed.append(smoothed_val)                        # Save it
            last = smoothed_val                                  # Anchor the last smoothed value

        return smoothed

    @staticmethod
    def calc_trend(data):
        """ Compile trend data """
 </s> add     def _calc_smoothed(self, data):
        """ Smooth the data.

        Parameters
        ----------
        data: :class:`numpy.ndarray`
            The data to smoothen

        Returns
        -------
        :class:`numpy.ndarray`
            The smoothed data
        """
        return ExponentialMovingAverage(data, self._args["smooth_amount"])()

    @classmethod
    def _calc_trend(cls, data):
        """ Calculate polynomial trend of the given data.

        Parameters
        ----------
        data: :class:`numpy.ndarray`
            The data to calculate the trend for

        Returns
        -------
        :class:`numpy.ndarray`
            The trend for the given data
        """
        position = self._data_popup_get_position()
          toplevel.tk.call(
              'wm',
              'iconphoto',
              toplevel._w, get_images().icons["favicon"])  # pylint:disable=protected-access
        position = self._data_popup_get_position()
          height = int(900 * scaling_factor)
          width = int(480 * scaling_factor)
          toplevel.geometry("{}x{}+{}+{}".format(str(height),
                                                 str(width),
                                                 str(position[0]),
keep keep keep keep 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