from dataclasses import dataclass import numpy as np from modules.graphs.style_settings import DEFAULT_STYLE_SETTINGS class CircularTarget: def __init__(self, fig, subplot_spec, max_dist, step, threshold, color_settings=DEFAULT_STYLE_SETTINGS): self._plt = fig.add_subplot(subplot_spec, projection='polar') self._max_dist = max_dist self._step = step self._threshold = threshold self._color_settings = color_settings def plot(self, x, y, resize_by_data=False): if resize_by_data: data_max = np.max(np.abs(np.concatenate([x, y]))) actual_max_dist = max(data_max, self._threshold, self._max_dist) else: actual_max_dist = self._max_dist self._show_scale(actual_max_dist + self._step) self._show_ticks(['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'], actual_max_dist) r = np.sqrt(x**2 + y**2) theta = np.arctan2(y, x) self._plt.scatter(theta, r, c=self._color_settings.color_data_fill, edgecolors=self._color_settings.color_data_border, s=self._color_settings.size_data_point, linewidths=self._color_settings.size_data_border, zorder=3, alpha=self._color_settings.alpha_data, ) def _show_scale(self, max_dist): theta_full = np.linspace(0, 2*np.pi, 200) is_dark = True # Show OK part for i in range(0, self._threshold, self._step): r_start = i r_end = i + self._step color = self._color_settings.color_ok_dark if is_dark else self._color_settings.color_ok_light self._plt.fill_between(theta_full, r_start, r_end, color=color, alpha=self._color_settings.alpha_scale, zorder=0) is_dark ^= 1 # Show error zone for i in range(self._threshold, max_dist, self._step): r_start = i r_end = i + self._step color = self._color_settings.color_err_dark if is_dark else self._color_settings.color_err_light self._plt.fill_between(theta_full, r_start, r_end, color=color, alpha=self._color_settings.alpha_scale, zorder=0) is_dark ^= 1 self._plt.set_ylim(0, max_dist) def _show_ticks(self, labels, max_dist): self._plt.set_xticks(np.linspace(0, 2*np.pi, len(labels), endpoint=False)) self._plt.set_xticklabels(labels, color=self._color_settings.color_contour, alpha=self._color_settings.alpha_contour, fontweight='bold') self._plt.set_yticks(np.arange(self._step, max_dist + 1, self._step)) self._plt.set_yticklabels([]) self._plt.grid(True, linestyle='-', color=self._color_settings.color_contour, alpha=self._color_settings.alpha_contour) self._plt.spines['polar'].set_color(self._color_settings.color_contour) self._plt.spines['polar'].set_alpha(self._color_settings.alpha_contour)