circular_target.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. from dataclasses import dataclass
  2. import numpy as np
  3. from modules.graphs.style_settings import DEFAULT_STYLE_SETTINGS
  4. class CircularTarget:
  5. def __init__(self, fig, subplot_spec, max_dist, step, threshold, color_settings=DEFAULT_STYLE_SETTINGS):
  6. self._plt = fig.add_subplot(subplot_spec, projection='polar')
  7. self._max_dist = max_dist
  8. self._step = step
  9. self._threshold = threshold
  10. self._color_settings = color_settings
  11. def plot(self, x, y, resize_by_data=False):
  12. if resize_by_data:
  13. data_max = np.max(np.abs(np.concatenate([x, y])))
  14. actual_max_dist = max(data_max, self._threshold, self._max_dist)
  15. else:
  16. actual_max_dist = self._max_dist
  17. self._show_scale(actual_max_dist + self._step)
  18. self._show_ticks(['E', 'NE', 'N', 'NW', 'W', 'SW', 'S', 'SE'], actual_max_dist)
  19. r = np.sqrt(x**2 + y**2)
  20. theta = np.arctan2(y, x)
  21. self._plt.scatter(theta, r,
  22. c=self._color_settings.color_data_fill,
  23. edgecolors=self._color_settings.color_data_border,
  24. s=self._color_settings.size_data_point,
  25. linewidths=self._color_settings.size_data_border,
  26. zorder=3,
  27. alpha=self._color_settings.alpha_data,
  28. )
  29. def _show_scale(self, max_dist):
  30. theta_full = np.linspace(0, 2*np.pi, 200)
  31. is_dark = True
  32. # Show OK part
  33. for i in range(0, self._threshold, self._step):
  34. r_start = i
  35. r_end = i + self._step
  36. color = self._color_settings.color_ok_dark if is_dark else self._color_settings.color_ok_light
  37. self._plt.fill_between(theta_full, r_start, r_end, color=color, alpha=self._color_settings.alpha_scale, zorder=0)
  38. is_dark ^= 1
  39. # Show error zone
  40. for i in range(self._threshold, max_dist, self._step):
  41. r_start = i
  42. r_end = i + self._step
  43. color = self._color_settings.color_err_dark if is_dark else self._color_settings.color_err_light
  44. self._plt.fill_between(theta_full, r_start, r_end, color=color, alpha=self._color_settings.alpha_scale, zorder=0)
  45. is_dark ^= 1
  46. self._plt.set_ylim(0, max_dist)
  47. def _show_ticks(self, labels, max_dist):
  48. self._plt.set_xticks(np.linspace(0, 2*np.pi, len(labels), endpoint=False))
  49. self._plt.set_xticklabels(labels, color=self._color_settings.color_contour, alpha=self._color_settings.alpha_contour, fontweight='bold')
  50. self._plt.set_yticks(np.arange(self._step, max_dist + 1, self._step))
  51. self._plt.set_yticklabels([])
  52. self._plt.grid(True, linestyle='-', color=self._color_settings.color_contour, alpha=self._color_settings.alpha_contour)
  53. self._plt.spines['polar'].set_color(self._color_settings.color_contour)
  54. self._plt.spines['polar'].set_alpha(self._color_settings.alpha_contour)