Example #1
0
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):
        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episodes_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
Example #2
0
class AnalyzeRewardDistribution(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):
        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episodes_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)

    def build_control_frame(self, control_frame: tk.Frame):
        self._episodes_control.add_to_control_frame()

    def add_plots(self):
        if not self.all_episodes:
            return

        gs = GridSpec(1, 3)
        axes_left: Axes = self.graph_figure.add_subplot(gs[0, 0])
        axes_middle: Axes = self.graph_figure.add_subplot(gs[0, 1])
        axes_right: Axes = self.graph_figure.add_subplot(gs[0, 2])

        self.plot_data(axes_left, get_plot_data_for_total_reward,
                       "Total Reward per Episode")
        self.plot_data(axes_middle, get_plot_data_for_average_reward,
                       "Average Reward per Episode")
        self.plot_data(axes_right, get_plot_data_for_reward_per_step,
                       "Reward per Step")

    def plot_data(self, axes: Axes, get_data_method, title):
        show_filtered = self.filtered_episodes and self._episodes_control.show_filtered(
        )
        show_all = self.all_episodes and self._episodes_control.show_all()

        if show_all and show_filtered:
            (plot_data_all) = get_data_method(self.all_episodes)
            (plot_data_filtered) = get_data_method(self.filtered_episodes)
            axes.hist([plot_data_all, plot_data_filtered],
                      density=True,
                      label=["All", "Filtered"],
                      color=["C1", "C2"])
        elif show_all:
            (plot_data_all) = get_data_method(self.all_episodes)
            axes.hist(plot_data_all, label="All", color="C1")
        elif show_filtered:
            (plot_data_filtered) = get_data_method(self.filtered_episodes)
            axes.hist(plot_data_filtered, label="Filtered", color="C2")

        # Format the plot
        axes.set_title(title)
        axes.set_xlabel("Reward")
        axes.get_yaxis().set_ticklabels([])

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)
Example #3
0
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg, control_frame: tk.Frame,
                 episode_selector: EpisodeSelector):
        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episodes_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
        self._more_filters_control = MoreFiltersControl(
            guru_parent_redraw, control_frame, True)
        self._group_control = ActionGroupControl(guru_parent_redraw,
                                                 control_frame)
        self._episode_selector = episode_selector
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self.episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
        self.correlation_control = CorrelationControl(guru_parent_redraw,
                                                      control_frame, False)
        self.format_control = GraphFormatControl(guru_parent_redraw,
                                                 control_frame)
        self._line_fitting_control = GraphLineFittingControl(
            guru_parent_redraw, control_frame)
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self.episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame, True)
        self._stats_control = StatsControl(guru_parent_redraw, control_frame)
        self._scale_control = GraphScaleControl(guru_parent_redraw,
                                                control_frame)
        self._line_fitting_control = GraphLineFittingControl(
            guru_parent_redraw, control_frame)
        self._evaluation_pairs_control = EvaluationPairsControl(
            guru_parent_redraw, control_frame)
class AnalyzeRewardsPerWaypoint(GraphAnalyzer):

    def __init__(self, guru_parent_redraw, matplotlib_canvas: FigureCanvasTkAgg, control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episodes_control = EpisodeCheckButtonControl(guru_parent_redraw, control_frame)
        self._stats_control = StatsControl(guru_parent_redraw, control_frame)

    def build_control_frame(self, control_frame):
        self._episodes_control.add_to_control_frame()
        self._stats_control.add_to_control_frame()

    def add_plots(self):
        if self.all_episodes:
            axes: Axes = self.graph_figure.add_subplot()
            self.plot_rewards_per_waypoint(axes)

    def plot_rewards_per_waypoint(self, axes: Axes):
        # Plot data

        num_waypoints = self.current_track.get_number_of_waypoints()

        if self.all_episodes and self._episodes_control.show_all():
            if self._stats_control.show_median():
                add_plot_for_rewards_per_waypoint(axes, "All - Median", self.all_episodes, np.median, "C5", num_waypoints)
            if self._stats_control.show_mean():
                add_plot_for_rewards_per_waypoint(axes, "All - Mean", self.all_episodes, np.mean, "C6", num_waypoints)
            if self._stats_control.show_best():
                add_plot_for_rewards_per_waypoint(axes, "All - Best", self.all_episodes, np.max, "C7", num_waypoints)
            if self._stats_control.show_worst():
                add_plot_for_rewards_per_waypoint(axes, "All - Worst", self.all_episodes, np.min, "C8", num_waypoints)
        if self.filtered_episodes and self._episodes_control.show_filtered():
            if self._stats_control.show_median():
                add_plot_for_rewards_per_waypoint(axes, "Filtered - Median", self.filtered_episodes, np.median, "C1", num_waypoints)
            if self._stats_control.show_mean():
                add_plot_for_rewards_per_waypoint(axes, "Filtered - Mean", self.filtered_episodes, np.mean, "C2", num_waypoints)
            if self._stats_control.show_best():
                add_plot_for_rewards_per_waypoint(axes, "Filtered - Best", self.filtered_episodes, np.max, "C3", num_waypoints)
            if self._stats_control.show_worst():
                add_plot_for_rewards_per_waypoint(axes, "Filtered - Worst", self.filtered_episodes, np.min, "C4", num_waypoints)

        # Format the plot
        axes.set_title("Rewards per Waypoint")
        axes.set_xlabel("Waypoint")

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)
Example #7
0
class AnalyzeCompleteLapPercentage(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame, True)

    def build_control_frame(self, control_frame):
        self._episode_control.add_to_control_frame()

    def add_plots(self):
        if not self.all_episodes:
            return

        axes: Axes = self.graph_figure.add_subplot()

        # Plot data

        if self._episode_control.show_all():
            self._add_plot_for_episodes(axes, "All Episodes",
                                        self.all_episodes, "C1")

        if self.filtered_episodes and self._episode_control.show_filtered():
            self._add_plot_for_episodes(axes, "Filtered Episodes",
                                        self.filtered_episodes, "C2")

        if self._episode_control.show_evaluations():
            add_plot_for_evaluations(axes, "Evaluations",
                                     self.evaluation_phases, "C3")

        # Format the plot
        axes.set_title("Complete Lap Percentage")
        axes.set_xlabel("Training Iteration")

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)

    def _add_plot_for_episodes(self, axes: Axes, label, episodes, colour):
        (plot_x, plot_y) = get_plot_data_for_episodes(episodes)
        axes.plot(plot_x, plot_y, colour, label=label)
        self._plot_solo_items(axes, plot_x, plot_y, colour)
class AnalyzeSectorTimeCorrelations(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self.episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
        self.correlation_control = CorrelationControl(guru_parent_redraw,
                                                      control_frame, False)
        self.format_control = GraphFormatControl(guru_parent_redraw,
                                                 control_frame)
        self._line_fitting_control = GraphLineFittingControl(
            guru_parent_redraw, control_frame)

    def build_control_frame(self, control_frame):
        self.episode_control.add_to_control_frame()
        self.correlation_control.add_to_control_frame()
        self.format_control.add_to_control_frame()
        self._line_fitting_control.add_to_control_frame()

    def add_plots(self):
        if not self.sector_filter:
            return

        axes: Axes = self.graph_figure.add_subplot()

        if self.episode_control.show_all():
            self.plot_episodes(axes, self.all_episodes, "C1", "All", "o")

        if self.episode_control.show_filtered():
            self.plot_episodes(axes, self.filtered_episodes, "C2", "Filtered",
                               "o")

        self.format_axes(axes)

    def plot_episodes(self, axes: Axes, episodes: list, colour, label, shape):

        if not episodes:
            return

        episode_info = self._get_episode_info(episodes)

        plot_x = self._get_plot_data_sector_times(episode_info)

        if self.correlation_control.correlate_complete_lap_time():
            plot_y = self._get_plot_data_lap_times(episode_info)
        elif self.correlation_control.correlate_total_distance():
            plot_y = self._get_plot_data_total_distance(episode_info)
        elif self.correlation_control.correlate_training_iteration():
            plot_y = self._get_plot_data_training_iteration(episode_info)
        elif self.correlation_control.correlate_total_reward():
            plot_y = self._get_plot_data_total_reward(episode_info)
        elif self.correlation_control.correlate_average_reward():
            plot_y = self._get_plot_data_average_reward(episode_info)
        elif self.correlation_control.correlate_peak_track_speed():
            plot_y = self._get_plot_data_peak_track_speed(episode_info)
        elif self.correlation_control.correlate_peak_progress_speed():
            plot_y = self._get_plot_data_peak_progress_speed(episode_info)
        elif self.correlation_control.correlate_max_slide():
            plot_y = self._get_plot_data_max_slide(episode_info)
        elif self.correlation_control.correlate_smoothness():
            plot_y = self._get_plot_data_smoothness(episode_info)
        else:
            return

        # Calculate linear regression line through the points, if requested
        (smoothed_x, smoothed_y, r_label) = (None, None, None)
        if self._line_fitting_control.linear_fitting():
            (smoothed_x, smoothed_y, r) = get_linear_regression(plot_x, plot_y)
            r_label = "R = " + str(round(r, 2))
        elif self._line_fitting_control.quadratic_fitting():
            (smoothed_x,
             smoothed_y) = get_polynomial_quadratic_regression(plot_x, plot_y)
            r_label = "Quadratic"

        # Finally plot the data we have gathered
        if self.format_control.swap_axes():
            axes.plot(plot_y, plot_x, shape, color=colour, label=label)
            if smoothed_y is not None:
                axes.plot(smoothed_y, smoothed_x, color=colour, label=r_label)
        else:
            axes.plot(plot_x, plot_y, shape, color=colour, label=label)
            if smoothed_y is not None:
                axes.plot(smoothed_x, smoothed_y, color=colour, label=r_label)

    def format_axes(self, axes: Axes):

        general_title = "???"
        axis_label = "???"

        if self.correlation_control.correlate_total_distance():
            general_title = "Total Distance"
            axis_label = "Distance / metres"
        if self.correlation_control.correlate_peak_track_speed():
            general_title = "Peak Track Speed"
            axis_label = "Peak Speed / metres per second"
        if self.correlation_control.correlate_peak_progress_speed():
            general_title = "Peak Progress Speed"
            axis_label = "Peak Speed / metres per second"
        if self.correlation_control.correlate_average_reward():
            general_title = "Average Reward Per Step"
            axis_label = general_title
        if self.correlation_control.correlate_total_reward():
            general_title = "Total Reward"
            axis_label = general_title
        if self.correlation_control.correlate_smoothness():
            general_title = "Smoothness"
            axis_label = "Repeat Action Percent"
        if self.correlation_control.correlate_training_iteration():
            general_title = "Training Iteration"
            axis_label = general_title
        if self.correlation_control.correlate_max_slide():
            general_title = "Maximum Slide"
            axis_label = general_title
        if self.correlation_control.correlate_complete_lap_time():
            general_title = "Complete Lap Time"
            axis_label = general_title

        axes.set_title("Sector " + self.sector_filter +
                       " Time Correlated With " + general_title)

        if self.format_control.swap_axes():
            axes.set_ylabel("Sector Time / Seconds")
            axes.set_xlabel(axis_label)
        else:
            axes.set_xlabel("Sector Time / Seconds")
            axes.set_ylabel(axis_label)

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)

    def _get_episode_info(self, episodes: list):
        info = []

        complete_laps_only = self.correlation_control.correlate_complete_lap_time(
        )
        (start, finish) = self.current_track.get_sector_start_and_finish(
            self.sector_filter)

        e: Episode
        for e in episodes:
            if e.lap_complete or not complete_laps_only:
                events = e.get_section_start_and_finish_events(
                    start, finish, self.current_track)
                if events:
                    (start_event, finish_event) = events
                    info.append((e, start_event, finish_event))

        return info

    @staticmethod
    def _get_plot_data_sector_times(episode_info: list):
        times = []
        for info in episode_info:
            episode: Episode
            (episode, start_event, finish_event) = info
            times.append(finish_event.time - start_event.time)
        return np.array(times)

    @staticmethod
    def _get_plot_data_lap_times(episode_info: list):
        times = []
        for info in episode_info:
            episode: Episode
            (episode, start_event, finish_event) = info
            times.append(episode.time_taken)
        return np.array(times)

    @staticmethod
    def _get_plot_data_training_iteration(episode_info: list):
        iterations = []
        for info in episode_info:
            episode: Episode
            (episode, start_event, finish_event) = info
            iterations.append(episode.iteration)
        return np.array(iterations)

    @staticmethod
    def _get_plot_data_total_distance(episode_info: list):
        distances = []
        for info in episode_info:
            start_event: Event
            finish_event: Event
            (_, start_event, finish_event) = info
            distances.append(finish_event.total_distance_travelled -
                             start_event.total_distance_travelled)
        return np.array(distances)

    @staticmethod
    def _get_plot_data_total_reward(episode_info: list):
        rewards = []
        for info in episode_info:
            start_event: Event
            finish_event: Event
            (_, start_event, finish_event) = info
            rewards.append(finish_event.reward_total -
                           start_event.reward_total)
        return np.array(rewards)

    @staticmethod
    def _get_plot_data_average_reward(episode_info: list):
        distances = []
        for info in episode_info:
            start_event: Event
            finish_event: Event
            (_, start_event, finish_event) = info
            reward_gain = finish_event.reward_total - start_event.reward_total
            steps = finish_event.step - start_event.step
            distances.append(reward_gain / steps)
        return np.array(distances)

    @staticmethod
    def _get_plot_data_peak_track_speed(episode_info: list):
        peak_speeds = []
        for info in episode_info:
            episode: Episode
            start_event: Event
            finish_event: Event
            (episode, start_event, finish_event) = info
            peak = start_event.track_speed
            event: Event
            for event in episode.get_events_in_range(start_event,
                                                     finish_event):
                peak = max(peak, event.track_speed)
            peak_speeds.append(peak)
        return np.array(peak_speeds)

    @staticmethod
    def _get_plot_data_peak_progress_speed(episode_info: list):
        peak_speeds = []
        for info in episode_info:
            episode: Episode
            start_event: Event
            finish_event: Event
            (episode, start_event, finish_event) = info
            peak = start_event.progress_speed
            event: Event
            for event in episode.get_events_in_range(start_event,
                                                     finish_event):
                peak = max(peak, event.progress_speed)
            peak_speeds.append(peak)
        return np.array(peak_speeds)

    @staticmethod
    def _get_plot_data_max_slide(episode_info: list):
        max_slides = []
        for info in episode_info:
            episode: Episode
            start_event: Event
            finish_event: Event
            (episode, start_event, finish_event) = info
            peak = abs(start_event.slide)
            event: Event
            for event in episode.get_events_in_range(start_event,
                                                     finish_event):
                peak = max(peak, abs(event.slide))
            max_slides.append(peak)
        return np.array(max_slides)

    @staticmethod
    def _get_plot_data_smoothness(episode_info: list):
        repeated_percents = []
        for info in episode_info:
            episode: Episode
            start_event: Event
            finish_event: Event
            (episode, start_event, finish_event) = info
            events = episode.get_events_in_range(start_event, finish_event)
            repeated_percents.append(
                episode.get_repeated_action_percent(events))
        return np.array(repeated_percents)
Example #9
0
class AnalyzeEpisodeActionDistribution(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg, control_frame: tk.Frame,
                 episode_selector: EpisodeSelector):
        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self._episodes_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
        self._more_filters_control = MoreFiltersControl(
            guru_parent_redraw, control_frame, True)
        self._group_control = ActionGroupControl(guru_parent_redraw,
                                                 control_frame)
        self._episode_selector = episode_selector

    def build_control_frame(self, control_frame: tk.Frame):
        self._episodes_control.add_to_control_frame()
        self._more_filters_control.add_to_control_frame()
        self._group_control.add_to_control_frame()

        self._episode_selector.add_to_control_frame(control_frame,
                                                    self.guru_parent_redraw)

    def add_plots(self):
        if not self.all_episodes:
            return

        episode = self._episode_selector.get_selected_episode()
        if not episode:
            return

        action_mapping = self._get_action_mapping()
        action_names = [name for name in action_mapping.keys()]

        this_episode_data = self._map_frequencies(
            np.array(episode.action_frequency), action_mapping)

        show_filtered = self._episodes_control.show_filtered()
        show_all = self._episodes_control.show_all()

        x_ticks = np.arange(len(action_names))

        axes: Axes = self.graph_figure.add_subplot()
        axes.bar(x_ticks, this_episode_data, 0.9, label='This Episode')

        if show_filtered and show_all:
            filtered_episodes_data = self._get_mapped_data_for_episodes(
                self.filtered_episodes, action_mapping)
            all_episodes_data = self._get_mapped_data_for_episodes(
                self.all_episodes, action_mapping)
            axes.bar(x_ticks - 0.1,
                     filtered_episodes_data,
                     0.2,
                     label='Filtered')
            axes.bar(x_ticks + 0.1, all_episodes_data, 0.2, label='All')
        elif show_filtered:
            filtered_episodes_data = self._get_mapped_data_for_episodes(
                self.filtered_episodes, action_mapping)
            axes.bar(x_ticks - 0,
                     filtered_episodes_data,
                     0.3,
                     label='Filtered')
        elif show_all:
            all_episodes_data = self._get_mapped_data_for_episodes(
                self.all_episodes, action_mapping)
            axes.bar(x_ticks - 0, all_episodes_data, 0.3, label='All')

        axes.set_xticks(x_ticks)
        axes.set_xticklabels(action_names)
        axes.yaxis.set_major_formatter(PercentFormatter())

        if len(action_names) >= 5:
            axes.set_ybound(0, 50)
        else:
            axes.set_ybound(0, 100)

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)

    def _get_mapped_data_for_episodes(self, episodes, action_mapping: dict):
        data = np.array(episodes[0].action_frequency)
        episode: Episode
        for episode in episodes[1:]:
            data = np.add(data, episode.action_frequency)

        return self._map_frequencies(data, action_mapping)

    def _map_frequencies(self, frequencies: np.ndarray, action_mapping: dict):
        mapped_frequencies = []
        for mapping in action_mapping.values():
            freq = 0
            for i in mapping:
                freq += frequencies[i]
            mapped_frequencies.append(freq)
        return self._get_counts_as_percentage(np.array(mapped_frequencies))

    @staticmethod
    def _get_counts_as_percentage(counts: np.ndarray):
        total_count = sum(counts)
        return counts * 100 / total_count

    def _get_action_mapping(self):
        show_all_actions = not self._more_filters_control.filter_actions()
        group_by_steering = self._group_control.group_by_steering()
        group_by_speed = self._group_control.group_by_speed()
        assert not (group_by_steering and group_by_speed)

        mapping = {}
        action: Action
        for action in self.action_space.get_all_actions():
            if show_all_actions or self.action_space_filter.should_show_action(
                    action.get_index()):
                if group_by_speed:
                    action_name = action.get_speed_group_name()
                elif group_by_steering:
                    action_name = action.get_steering_group_name()
                else:
                    action_name = action.get_readable_for_x_axis()
                if action_name in mapping:
                    mapping[action_name].append(action.get_index())
                else:
                    mapping[action_name] = [action.get_index()]

        return mapping
class AnalyzeTrainingProgress(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self.episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame, True)
        self._stats_control = StatsControl(guru_parent_redraw, control_frame)
        self._scale_control = GraphScaleControl(guru_parent_redraw,
                                                control_frame)
        self._line_fitting_control = GraphLineFittingControl(
            guru_parent_redraw, control_frame)
        self._evaluation_pairs_control = EvaluationPairsControl(
            guru_parent_redraw, control_frame)

    def build_control_frame(self, control_frame):
        self.episode_control.add_to_control_frame()
        self._stats_control.add_to_control_frame()
        self._scale_control.add_to_control_frame()
        self._line_fitting_control.add_to_control_frame()
        self._evaluation_pairs_control.add_to_control_frame()

    def add_plots(self):
        if not self.all_episodes:
            return

        gs = GridSpec(1, 2)
        axes_left: Axes = self.graph_figure.add_subplot(gs[0, 0])
        axes_right: Axes = self.graph_figure.add_subplot(gs[0, 1])

        self.create_plot_iteration_vs_total_reward(axes_left)
        self.create_plot_iteration_vs_percent_complete(axes_right)

    def create_plot_iteration_vs_total_reward(self, axes):
        # Plot data

        if self.all_episodes and self.episode_control.show_all():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_total_reward(
                    axes, "All - Median", self.all_episodes, np.median, "C5")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_total_reward(
                    axes, "All - Mean", self.all_episodes, np.mean, "C6")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_total_reward(
                    axes, "All - Best", self.all_episodes, np.max, "C7")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_total_reward(
                    axes, "All - Worst", self.all_episodes, np.min, "C8")

        if self.filtered_episodes and self.episode_control.show_filtered():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_total_reward(
                    axes, "Filtered - Median", self.filtered_episodes,
                    np.median, "C1")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_total_reward(
                    axes, "Filtered - Mean", self.filtered_episodes, np.mean,
                    "C2")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_total_reward(
                    axes, "Filtered - Best", self.filtered_episodes, np.max,
                    "C3")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_total_reward(
                    axes, "Filtered - Worst", self.filtered_episodes, np.min,
                    "C4")

        if self.episode_control.show_evaluations():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_evaluation_total_reward(
                    axes, "Evaluations - Median", self.evaluation_phases,
                    np.median, "C9")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_evaluation_total_reward(
                    axes, "Evaluations - Mean", self.evaluation_phases,
                    np.mean, "C10")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_evaluation_total_reward(
                    axes, "Evaluations - Best", self.evaluation_phases, np.max,
                    "C11")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_evaluation_total_reward(
                    axes, "Evaluations - Worst", self.evaluation_phases,
                    np.min, "C12")

        # Format the plot
        axes.set_title("Total Reward")
        axes.set_xlabel("Training Iteration")

        if self.log_meta and self.is_fixed_scale():
            best = self.log_meta.episode_stats.best_reward
            worst = self.log_meta.episode_stats.worst_reward
            if best != worst:
                border = 0.02 * (best - worst)
                axes.set_ybound(worst - border, best + border)

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)

    def create_plot_iteration_vs_percent_complete(self, axes):

        # Plot data
        if self.episode_control.show_all():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "All - Median", self.all_episodes, np.median, "C5")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "All - Mean", self.all_episodes, np.mean, "C6")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "All - Best", self.all_episodes, np.max, "C7")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "All - Worst", self.all_episodes, np.min, "C8")

        if self.filtered_episodes and self.episode_control.show_filtered():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "Filtered - Median", self.filtered_episodes,
                    np.median, "C1")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "Filtered - Mean", self.filtered_episodes, np.mean,
                    "C2")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "Filtered - Best", self.filtered_episodes, np.max,
                    "C3")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_percent_complete(
                    axes, "Filtered - Worst", self.filtered_episodes, np.min,
                    "C4")

        if self.episode_control.show_evaluations():
            if self._stats_control.show_median():
                self.add_plot_iteration_vs_evaluation_percent_complete(
                    axes, "Evaluations - Median", self.evaluation_phases,
                    np.median, "C9")
            if self._stats_control.show_mean():
                self.add_plot_iteration_vs_evaluation_percent_complete(
                    axes, "Evaluations - Mean", self.evaluation_phases,
                    np.mean, "C10")
            if self._stats_control.show_best():
                self.add_plot_iteration_vs_evaluation_percent_complete(
                    axes, "Evaluations - Best", self.evaluation_phases, np.max,
                    "C11")
            if self._stats_control.show_worst():
                self.add_plot_iteration_vs_evaluation_percent_complete(
                    axes, "Evaluations - Worst", self.evaluation_phases,
                    np.min, "C12")

        # Format the plot
        axes.set_title("Track Completion")
        axes.set_xlabel("Training Iteration")
        axes.yaxis.set_major_formatter(PercentFormatter())

        if self.is_fixed_scale():
            axes.set_ybound(0, 105)

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)

    def is_fixed_scale(self):
        return self._scale_control.fixed_scale()

    def add_plot_iteration_vs_total_reward(self, axes: Axes, label, episodes,
                                           stat_method, colour):
        (plot_x, plot_y) = get_plot_data_iteration_vs_total_reward(
            episodes, stat_method)
        self.plot_data_or_smooth_it(axes, label, plot_x, plot_y, colour)

    def add_plot_iteration_vs_evaluation_total_reward(self, axes: Axes, label,
                                                      evaluation_phases,
                                                      stat_method, colour):
        (plot_x,
         plot_y) = self.get_plot_data_iteration_vs_evaluation_total_reward(
             evaluation_phases, stat_method)
        self.plot_data_or_smooth_it(axes, label, plot_x, plot_y, colour)

    def add_plot_iteration_vs_percent_complete(self, axes: Axes, label,
                                               episodes, stat_method, colour):
        (plot_x, plot_y) = get_plot_data_iteration_vs_percent_complete(
            episodes, stat_method)
        self.plot_data_or_smooth_it(axes, label, plot_x, plot_y, colour)

    def add_plot_iteration_vs_evaluation_percent_complete(
            self, axes: Axes, label, evaluation_phases, stat_method, colour):
        (plot_x,
         plot_y) = self.get_plot_data_iteration_vs_evaluation_percent_complete(
             evaluation_phases, stat_method)
        self.plot_data_or_smooth_it(axes, label, plot_x, plot_y, colour)

    def plot_data_or_smooth_it(self, axes: Axes, label: str,
                               plot_x: np.ndarray, plot_y: np.ndarray,
                               colour: str):
        if self._line_fitting_control.linear_fitting():
            (x_values, y_values, r) = get_linear_regression(plot_x, plot_y)
        elif self._line_fitting_control.quadratic_fitting():
            (x_values,
             y_values) = get_polynomial_quadratic_regression(plot_x, plot_y)
        else:
            x_values = plot_x
            y_values = plot_y

        axes.plot(x_values, y_values, colour, label=label)
        self._plot_solo_items(axes, x_values, y_values, colour)

    def get_plot_data_iteration_vs_evaluation_total_reward(
            self, evaluation_phases, stat_method):
        plot_iteration = []
        plot_data = []

        previous_eval = None
        for i, this_eval in enumerate(evaluation_phases):
            if self._evaluation_pairs_control.show_combined() and i % 2 == 1:
                plot_value = stat_method(
                    np.concatenate((this_eval.rewards, previous_eval.rewards)))
                plot_data.append(plot_value)
                plot_iteration.append(i - 0.5)
            elif ((self._evaluation_pairs_control.show_odd() and i % 2 == 1) or
                  (self._evaluation_pairs_control.show_even() and i % 2 == 0)
                  or self._evaluation_pairs_control.show_separate()):

                plot_data.append(stat_method(this_eval.rewards))
                plot_iteration.append(i)

            previous_eval = this_eval

        return np.array(plot_iteration), np.array(plot_data)

    def get_plot_data_iteration_vs_evaluation_percent_complete(
            self, evaluation_phases, stat_method):
        plot_iteration = []
        plot_data = []

        previous_eval = None
        for i, this_eval in enumerate(evaluation_phases):
            if self._evaluation_pairs_control.show_combined() and i % 2 == 1:
                plot_value = stat_method(
                    np.concatenate(
                        (this_eval.progresses, previous_eval.progresses)))
                plot_data.append(plot_value)
                plot_iteration.append(i - 0.5)
            elif ((self._evaluation_pairs_control.show_odd() and i % 2 == 1) or
                  (self._evaluation_pairs_control.show_even() and i % 2 == 0)
                  or self._evaluation_pairs_control.show_separate()):

                plot_data.append(stat_method(this_eval.progresses))
                plot_iteration.append(i)

            previous_eval = this_eval

        return np.array(plot_iteration), np.array(plot_data)
Example #11
0
class AnalyzeLapTimeCorrelations(GraphAnalyzer):
    def __init__(self, guru_parent_redraw,
                 matplotlib_canvas: FigureCanvasTkAgg,
                 control_frame: tk.Frame):

        super().__init__(guru_parent_redraw, matplotlib_canvas, control_frame)

        self.episode_control = EpisodeCheckButtonControl(
            guru_parent_redraw, control_frame)
        self.predictions_control = PredictionsControl(guru_parent_redraw,
                                                      control_frame)
        self.correlation_control = CorrelationControl(guru_parent_redraw,
                                                      control_frame, True)
        self.format_control = GraphFormatControl(guru_parent_redraw,
                                                 control_frame)
        self._line_fitting_control = GraphLineFittingControl(
            guru_parent_redraw, control_frame)

    def build_control_frame(self, control_frame):
        self.episode_control.add_to_control_frame()
        self.predictions_control.add_to_control_frame()
        self.correlation_control.add_to_control_frame()
        self.format_control.add_to_control_frame()
        self._line_fitting_control.add_to_control_frame()

    def add_plots(self):
        axes: Axes = self.graph_figure.add_subplot()

        if self.episode_control.show_all():
            self.plot_episodes(axes, self.all_episodes, False, "C1", "All",
                               "o")
            if self.predictions_control.show_predictions():
                self.plot_episodes(axes, self.all_episodes, True, "C3",
                                   "All - Predicted", ".")

        if self.episode_control.show_filtered():
            self.plot_episodes(axes, self.filtered_episodes, False, "C2",
                               "Filtered", "o")
            if self.predictions_control.show_predictions():
                self.plot_episodes(axes, self.filtered_episodes, True, "C4",
                                   "Filtered - Predicted", ".")

        self.format_axes(axes)

    def plot_episodes(self, axes: Axes, episodes: list, make_predictions: bool,
                      colour, label, shape):

        if not episodes:
            return

        if make_predictions:
            if self.correlation_control.correlate_total_reward():
                plot_y = get_plot_data_total_rewards_predicted(episodes)
            elif self.correlation_control.correlate_starting_point():
                plot_y = get_plot_data_starting_points_predicted(episodes)
            elif self.correlation_control.correlate_average_reward():
                plot_y = get_plot_data_average_rewards_predicted(episodes)
            elif self.correlation_control.correlate_training_iteration():
                plot_y = get_plot_data_iterations_predicted(episodes)
            else:
                return
        else:
            if self.correlation_control.correlate_total_distance():
                plot_y = get_plot_data_distances(episodes)
            elif self.correlation_control.correlate_peak_track_speed():
                plot_y = get_plot_data_peak_track_speeds(episodes)
            elif self.correlation_control.correlate_peak_progress_speed():
                plot_y = get_plot_data_peak_progress_speeds(episodes)
            elif self.correlation_control.correlate_starting_point():
                plot_y = get_plot_data_starting_points(episodes)
            elif self.correlation_control.correlate_average_reward():
                plot_y = get_plot_data_average_rewards(episodes)
            elif self.correlation_control.correlate_total_reward():
                plot_y = get_plot_data_total_rewards(episodes)
            elif self.correlation_control.correlate_final_reward():
                plot_y = get_plot_data_final_rewards(episodes)
            elif self.correlation_control.correlate_smoothness():
                plot_y = get_plot_data_repeats(episodes)
            elif self.correlation_control.correlate_training_iteration():
                plot_y = get_plot_data_iterations(episodes)
            elif self.correlation_control.correlate_flying_start():
                plot_y = get_plot_data_flying_starts(episodes)
            elif self.correlation_control.correlate_max_slide():
                plot_y = get_plot_data_max_slide(episodes)
            else:
                return

        if make_predictions:
            plot_x = get_plot_data_lap_times_predicted(episodes)
        else:
            plot_x = get_plot_data_lap_times(episodes)

        # Calculate linear regression line through the points, if requested
        (smoothed_x, smoothed_y, r_label) = (None, None, None)
        if self._line_fitting_control.linear_fitting():
            (smoothed_x, smoothed_y, r) = get_linear_regression(plot_x, plot_y)
            r_label = "R = " + str(round(r, 2))
        elif self._line_fitting_control.quadratic_fitting():
            (smoothed_x,
             smoothed_y) = get_polynomial_quadratic_regression(plot_x, plot_y)
            r_label = "Quadratic"

        # Finally plot the data we have gathered
        if self.format_control.swap_axes():
            axes.plot(plot_y, plot_x, shape, color=colour, label=label)
            if smoothed_y is not None:
                axes.plot(smoothed_y, smoothed_x, color=colour, label=r_label)
        else:
            axes.plot(plot_x, plot_y, shape, color=colour, label=label)
            if smoothed_y is not None:
                axes.plot(smoothed_x, smoothed_y, color=colour, label=r_label)

    def format_axes(self, axes: Axes):

        general_title = "???"
        axis_label = "???"

        if self.correlation_control.correlate_total_distance():
            general_title = "Total Distance"
            axis_label = "Distance / metres"
        if self.correlation_control.correlate_peak_track_speed():
            general_title = "Peak Track Speed"
            axis_label = "Peak Speed / metres per second"
        if self.correlation_control.correlate_peak_progress_speed():
            general_title = "Peak Progress Speed"
            axis_label = "Peak Speed / metres per second"
        if self.correlation_control.correlate_starting_point():
            general_title = "Starting Point"
            axis_label = "Start Waypoint Id"
        if self.correlation_control.correlate_average_reward():
            general_title = "Average Reward Per Step"
            axis_label = general_title
        if self.correlation_control.correlate_total_reward():
            general_title = "Total Reward"
            axis_label = general_title
        if self.correlation_control.correlate_final_reward():
            general_title = "Final Reward"
            axis_label = general_title
        if self.correlation_control.correlate_smoothness():
            general_title = "Smoothness"
            axis_label = "Repeat Action Percent"
        if self.correlation_control.correlate_training_iteration():
            general_title = "Training Iteration"
            axis_label = general_title
        if self.correlation_control.correlate_flying_start():
            general_title = "Flying Start"
            axis_label = "Track Speed At One Second / metres per second"
        if self.correlation_control.correlate_max_slide():
            general_title = "Maximum Slide"
            axis_label = general_title

        axes.set_title("Lap Time Correlated With " + general_title)

        if self.format_control.swap_axes():
            axes.set_ylabel("Lap Time / Seconds")
            axes.set_xlabel(axis_label)
        else:
            axes.set_xlabel("Lap Time / Seconds")
            axes.set_ylabel(axis_label)

        if axes.has_data():
            axes.legend(frameon=True, framealpha=0.8, shadow=True)