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)
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)
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)
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)
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)
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)