modusa 0.3.73__tar.gz → 0.3.75__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. {modusa-0.3.73 → modusa-0.3.75}/PKG-INFO +1 -1
  2. {modusa-0.3.73 → modusa-0.3.75}/pyproject.toml +1 -1
  3. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/plotter.py +69 -0
  4. {modusa-0.3.73 → modusa-0.3.75}/LICENSE.md +0 -0
  5. {modusa-0.3.73 → modusa-0.3.75}/README.md +0 -0
  6. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/.DS_Store +0 -0
  7. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/__init__.py +0 -0
  8. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/config.py +0 -0
  9. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/decorators.py +0 -0
  10. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/generate_docs_source.py +0 -0
  11. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/generate_template.py +0 -0
  12. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/list_authors.py +0 -0
  13. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/list_plugins.py +0 -0
  14. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/main.py +0 -0
  15. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/generator.py +0 -0
  16. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/io.py +0 -0
  17. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/model.py +0 -0
  18. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/plugin.py +0 -0
  19. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/test.py +0 -0
  20. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/devtools/templates/tool.py +0 -0
  21. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/fonts/NotoSansDevanagari-Regular.ttf +0 -0
  22. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/__init__.py +0 -0
  23. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/audio.py +0 -0
  24. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/audio_waveforms.py +0 -0
  25. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/base.py +0 -0
  26. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/ftds.py +0 -0
  27. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/s1d.py +0 -0
  28. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/s2d.py +0 -0
  29. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/s_ax.py +0 -0
  30. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/t_ax.py +0 -0
  31. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/generators/tds.py +0 -0
  32. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/__init__.py +0 -0
  33. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/__pycache__/signal1D.cpython-312.pyc.4443461152 +0 -0
  34. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/audio.py +0 -0
  35. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/base.py +0 -0
  36. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/data.py +0 -0
  37. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/ftds.py +0 -0
  38. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/s1d.py +0 -0
  39. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/s2d.py +0 -0
  40. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/s_ax.py +0 -0
  41. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/t_ax.py +0 -0
  42. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/models/tds.py +0 -0
  43. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/plugins/__init__.py +0 -0
  44. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/plugins/base.py +0 -0
  45. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/__init__.py +0 -0
  46. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/_plotter_old.py +0 -0
  47. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/ann_loader.py +0 -0
  48. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/audio_converter.py +0 -0
  49. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/audio_loader.py +0 -0
  50. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/audio_player.py +0 -0
  51. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/audio_recorder.py +0 -0
  52. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/base.py +0 -0
  53. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/math_ops.py +0 -0
  54. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/tools/youtube_downloader.py +0 -0
  55. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/.DS_Store +0 -0
  56. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/__init__.py +0 -0
  57. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/config.py +0 -0
  58. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/excp.py +0 -0
  59. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/logger.py +0 -0
  60. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/np_func_cat.py +0 -0
  61. {modusa-0.3.73 → modusa-0.3.75}/src/modusa/utils/plot.py +0 -0
  62. {modusa-0.3.73 → modusa-0.3.75}/tests/__init__.py +0 -0
  63. {modusa-0.3.73 → modusa-0.3.75}/tests/data/song1.mp3 +0 -0
  64. {modusa-0.3.73 → modusa-0.3.75}/tests/data/song1.wav +0 -0
  65. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/audio_waveform.py +0 -0
  66. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_audio.py +0 -0
  67. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_ftds.py +0 -0
  68. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_s1d.py +0 -0
  69. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_s2d.py +0 -0
  70. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_s_ax.py +0 -0
  71. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_signal.py +0 -0
  72. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_signal_generator.py +0 -0
  73. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_t_ax.py +0 -0
  74. {modusa-0.3.73 → modusa-0.3.75}/tests/test_generators/test_tds.py +0 -0
  75. {modusa-0.3.73 → modusa-0.3.75}/tests/test_io/audio_player.py +0 -0
  76. {modusa-0.3.73 → modusa-0.3.75}/tests/test_io/plotter.py +0 -0
  77. {modusa-0.3.73 → modusa-0.3.75}/tests/test_models/test_data.py +0 -0
  78. {modusa-0.3.73 → modusa-0.3.75}/tests/test_models/test_t_ax.py +0 -0
  79. {modusa-0.3.73 → modusa-0.3.75}/tests/test_plugins/youtube_audio_loader.py +0 -0
  80. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/frequency_domain_signal.py +0 -0
  81. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/spectrogram.py +0 -0
  82. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_axis.py +0 -0
  83. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_feature_time_domain_signal.py +0 -0
  84. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_frequency_time_domain_signal.py +0 -0
  85. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_signal1D.py +0 -0
  86. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_signal2D.py +0 -0
  87. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_time_domain_signal.py +0 -0
  88. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_u_ax.py +0 -0
  89. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/test_window_signal.py +0 -0
  90. {modusa-0.3.73 → modusa-0.3.75}/tests/test_signals/time_domain_signal.py +0 -0
  91. {modusa-0.3.73 → modusa-0.3.75}/tests/test_tools/test_audio_converter.py +0 -0
  92. {modusa-0.3.73 → modusa-0.3.75}/tests/test_tools/test_fourier_tranform.py +0 -0
  93. {modusa-0.3.73 → modusa-0.3.75}/tests/test_tools/test_math_ops.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modusa
3
- Version: 0.3.73
3
+ Version: 0.3.75
4
4
  Summary: A modular signal analysis python library.
5
5
  Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "modusa"
3
- version = "0.3.73"
3
+ version = "0.3.75"
4
4
  description = "A modular signal analysis python library."
5
5
  authors = [
6
6
  { name = "Ankit Anand", email = "ankit0.anand0@gmail.com" },
@@ -95,6 +95,14 @@ class Fig:
95
95
 
96
96
  return curr_row
97
97
 
98
+ def _get_prev_row(self):
99
+ """
100
+ Get the prev row where you can add arrows.
101
+ """
102
+ prev_pow = self._axs[self._curr_row_idx - 1]
103
+
104
+ return prev_pow
105
+
98
106
  def _get_new_color(self):
99
107
  """
100
108
  Get a new color for different lines.
@@ -529,6 +537,67 @@ class Fig:
529
537
 
530
538
  if grid is True:
531
539
  curr_row[0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
540
+
541
+ from matplotlib.patches import Rectangle
542
+ import matplotlib.pyplot as plt
543
+
544
+ def add_arrows(self, xys, labels, text_offset=(0, 0), c="r", fontsize=12, ax=None):
545
+ """
546
+ Add multiple arrows pointing to specific points with boxed labels at the tails.
547
+
548
+ Parameters
549
+ ----------
550
+ xys : list[tuple[float, float]]
551
+ - List of target points (x, y) for the arrow heads.
552
+ labels : list[str] | str
553
+ - List of text labels at the arrow tails.
554
+ - If str, the same label is used for all points.
555
+ text_offset : tuple[float, float] | list[tuple[float, float]]
556
+ - Offset(s) (dx, dy) for label positions from arrow tails.
557
+ - If single tuple, same offset is applied to all.
558
+ c : str | list[str]
559
+ - Color(s) for arrow and text.
560
+ - If str, same color is applied to all.
561
+ fontsize : int | list[int]
562
+ - Font size(s) of the label text.
563
+ - If int, same size is applied to all.
564
+ ax : int | None
565
+ - Which specific axis to plot (1, 2, 3, ...).
566
+ - If None, uses the current row.
567
+
568
+ Returns
569
+ -------
570
+ None
571
+ """
572
+ curr_row = self._get_prev_row() if ax is None else self._axs[ax]
573
+
574
+ # Normalize single values into lists
575
+ n = len(xys)
576
+ if isinstance(labels, str):
577
+ labels = [labels] * n
578
+ if isinstance(text_offset, tuple):
579
+ text_offset = [text_offset] * n
580
+ if isinstance(c, str):
581
+ c = [c] * n
582
+ if isinstance(fontsize, int):
583
+ fontsize = [fontsize] * n
584
+
585
+ for (xy, label, offset, color, fs) in zip(xys, labels, text_offset, c, fontsize):
586
+ arrowprops = dict(arrowstyle="->", color=color, lw=2)
587
+ bbox = dict(boxstyle="round,pad=0.3", fc="white", ec=color, lw=1.2)
588
+
589
+ text_x, text_y = xy[0] + offset[0], xy[1] + offset[1]
590
+
591
+ curr_row[0].annotate(
592
+ label,
593
+ xy=xy, xycoords="data",
594
+ xytext=(text_x, text_y), textcoords="data",
595
+ arrowprops=arrowprops,
596
+ fontsize=fs,
597
+ color=color,
598
+ ha="center", va="center",
599
+ bbox=bbox
600
+ )
532
601
 
533
602
  def add_legend(self, ypos=1.0):
534
603
  """
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes