modusa 0.3.91__py3-none-any.whl → 0.3.93__py3-none-any.whl
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.
- modusa/__init__.py +2 -2
- modusa/tools/__init__.py +1 -1
- modusa/tools/plotter.py +145 -5
- {modusa-0.3.91.dist-info → modusa-0.3.93.dist-info}/METADATA +1 -1
- {modusa-0.3.91.dist-info → modusa-0.3.93.dist-info}/RECORD +8 -8
- {modusa-0.3.91.dist-info → modusa-0.3.93.dist-info}/WHEEL +0 -0
- {modusa-0.3.91.dist-info → modusa-0.3.93.dist-info}/entry_points.txt +0 -0
- {modusa-0.3.91.dist-info → modusa-0.3.93.dist-info}/licenses/LICENSE.md +0 -0
modusa/__init__.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from modusa.utils import excp, config
|
|
2
2
|
|
|
3
3
|
#=====Giving access to plot functions to plot multiple signals.=====
|
|
4
|
-
from modusa.tools import
|
|
4
|
+
from modusa.tools import dist_plot, hill_plot, fig
|
|
5
5
|
#=====
|
|
6
6
|
|
|
7
7
|
from modusa.tools import play, convert, record, save
|
|
8
8
|
from modusa.tools import download
|
|
9
9
|
from modusa.tools import load, load_ann
|
|
10
10
|
|
|
11
|
-
__version__ = "0.3.
|
|
11
|
+
__version__ = "0.3.93"
|
modusa/tools/__init__.py
CHANGED
modusa/tools/plotter.py
CHANGED
|
@@ -564,9 +564,6 @@ class Fig:
|
|
|
564
564
|
if grid is True:
|
|
565
565
|
curr_row[0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
|
|
566
566
|
|
|
567
|
-
from matplotlib.patches import Rectangle
|
|
568
|
-
import matplotlib.pyplot as plt
|
|
569
|
-
|
|
570
567
|
def add_arrows(self, xys, labels, text_offset=(0, 0), c="r", fontsize=12, ax=None):
|
|
571
568
|
"""
|
|
572
569
|
Add multiple arrows pointing to specific points with boxed labels at the tails.
|
|
@@ -715,10 +712,153 @@ class Fig:
|
|
|
715
712
|
fig = self._fig
|
|
716
713
|
fig.savefig(path, bbox_inches="tight")
|
|
717
714
|
|
|
715
|
+
#======== Distribution ==========
|
|
716
|
+
def hill_plot(*args, labels=None, xlabel=None, ylabel=None, title=None, widths=0.7, bw_method=0.3, jitter_amount=0.1, side='upper', show_stats=True, ax=None):
|
|
717
|
+
"""
|
|
718
|
+
A plot to see distribution of different groups
|
|
719
|
+
along with statistical markers.
|
|
720
|
+
|
|
721
|
+
Parameters
|
|
722
|
+
----------
|
|
723
|
+
*args : array-like
|
|
724
|
+
- Data arrays for each group.
|
|
725
|
+
labels : list of str, optional
|
|
726
|
+
- Labels for each group (y-axis).
|
|
727
|
+
side : str, 'upper' or 'lower'
|
|
728
|
+
Which half of the violin to draw (upper or lower relative to y-axis).
|
|
729
|
+
show_stats : bool, optional
|
|
730
|
+
Whether to show mean and median markers.
|
|
731
|
+
xlabel : str, optional
|
|
732
|
+
Label for x-axis.
|
|
733
|
+
ylabel : str, optional
|
|
734
|
+
Label for y-axis.
|
|
735
|
+
ax : matplotlib axes, optional
|
|
736
|
+
Axes to plot on.
|
|
737
|
+
title : str, optional
|
|
738
|
+
Plot title.
|
|
739
|
+
widths : float, optional
|
|
740
|
+
Width of violins.
|
|
741
|
+
bw_method : float, optional
|
|
742
|
+
Bandwidth method for KDE.
|
|
743
|
+
jitter_amount : float, optional
|
|
744
|
+
Amount of vertical jitter for strip points.
|
|
745
|
+
"""
|
|
746
|
+
|
|
747
|
+
created_fig = False
|
|
748
|
+
if ax is None:
|
|
749
|
+
fig, ax = plt.subplots(figsize=(8, len(args) * 1.5))
|
|
750
|
+
created_fig = True
|
|
751
|
+
|
|
752
|
+
n = len(args)
|
|
753
|
+
|
|
754
|
+
# Default labels/colors
|
|
755
|
+
if labels is None:
|
|
756
|
+
labels = [f"Group {i}" for i in range(1, n+1)]
|
|
757
|
+
|
|
758
|
+
colors = plt.cm.tab10.colors
|
|
759
|
+
if len(colors) < n:
|
|
760
|
+
colors = [colors[i % len(colors)] for i in range(n)] # Repeat colors
|
|
761
|
+
|
|
762
|
+
# --- Half-violin ---
|
|
763
|
+
parts = ax.violinplot(args, vert=False, showmeans=False, showmedians=False, widths=widths, bw_method=bw_method)
|
|
764
|
+
|
|
765
|
+
# Remove the default bar lines from violin plot
|
|
766
|
+
for key in ['cbars', 'cmins', 'cmaxes', 'cmedians']:
|
|
767
|
+
if key in parts:
|
|
768
|
+
parts[key].set_visible(False)
|
|
769
|
+
|
|
770
|
+
# Clip violin bodies to show only upper or lower half
|
|
771
|
+
for i, pc in enumerate(parts['bodies']):
|
|
772
|
+
verts = pc.get_paths()[0].vertices
|
|
773
|
+
y_center = i + 1 # Center y-position for this violin
|
|
774
|
+
|
|
775
|
+
if side == 'upper':
|
|
776
|
+
verts[:, 1] = np.maximum(verts[:, 1], y_center)
|
|
777
|
+
else: # 'lower'
|
|
778
|
+
verts[:, 1] = np.minimum(verts[:, 1], y_center)
|
|
779
|
+
|
|
780
|
+
pc.set_facecolor(colors[i])
|
|
781
|
+
pc.set_edgecolor(colors[i])
|
|
782
|
+
pc.set_linewidth(1.5)
|
|
783
|
+
pc.set_alpha(0.3)
|
|
784
|
+
|
|
785
|
+
# --- Strip points with jitter ---
|
|
786
|
+
for i, x in enumerate(args, start=1):
|
|
787
|
+
x = np.array(x)
|
|
788
|
+
jitter = (np.random.rand(len(x)) - 0.5) * jitter_amount
|
|
789
|
+
y_positions = np.full(len(x), i) + jitter
|
|
790
|
+
ax.scatter(x, y_positions, color=colors[i-1], alpha=0.6, s=25, edgecolor="white", linewidth=0.8, zorder=2)
|
|
791
|
+
|
|
792
|
+
# --- Statistical markers on violin distribution curve ---
|
|
793
|
+
if show_stats:
|
|
794
|
+
for i, (pc, x) in enumerate(zip(parts['bodies'], args), start=1):
|
|
795
|
+
x = np.array(x)
|
|
796
|
+
median_val = np.median(x)
|
|
797
|
+
mean_val = np.mean(x)
|
|
798
|
+
|
|
799
|
+
# Get the violin curve vertices
|
|
800
|
+
verts = pc.get_paths()[0].vertices
|
|
801
|
+
|
|
802
|
+
# Find y-position on violin curve for median
|
|
803
|
+
median_mask = np.abs(verts[:, 0] - median_val) < (np.ptp(x) * 0.01)
|
|
804
|
+
if median_mask.any():
|
|
805
|
+
median_y = np.max(verts[median_mask, 1]) if side == 'upper' else np.min(verts[median_mask, 1])
|
|
806
|
+
else:
|
|
807
|
+
median_y = i + widths/2 if side == 'upper' else i - widths/2
|
|
808
|
+
|
|
809
|
+
# Find y-position on violin curve for mean
|
|
810
|
+
mean_mask = np.abs(verts[:, 0] - mean_val) < (np.ptp(x) * 0.01)
|
|
811
|
+
if mean_mask.any():
|
|
812
|
+
mean_y = np.max(verts[mean_mask, 1]) if side == 'upper' else np.min(verts[mean_mask, 1])
|
|
813
|
+
else:
|
|
814
|
+
mean_y = i + widths/2 if side == 'upper' else i - widths/2
|
|
815
|
+
|
|
816
|
+
# Triangle offset from curve
|
|
817
|
+
triangle_offset = 0.05
|
|
818
|
+
|
|
819
|
+
# Mean marker - triangle below curve pointing up
|
|
820
|
+
ax.scatter(mean_val, mean_y - triangle_offset, marker='^', s=30,
|
|
821
|
+
facecolor=colors[i-1], edgecolor='none',
|
|
822
|
+
linewidth=0, zorder=6,
|
|
823
|
+
label='Mean' if i == 1 else '')
|
|
824
|
+
|
|
825
|
+
# Mean value text - below the triangle
|
|
826
|
+
ax.text(mean_val, mean_y - triangle_offset - 0.05, f'mean: {mean_val:.2f}', ha='center', va='top', fontsize=8, fontweight='bold', color=colors[i-1], zorder=7)
|
|
827
|
+
|
|
828
|
+
# Median marker - triangle above curve pointing down
|
|
829
|
+
ax.scatter(median_val, median_y + triangle_offset, marker='v', s=30,
|
|
830
|
+
facecolor=colors[i-1], edgecolor='none',
|
|
831
|
+
linewidth=0, zorder=6,
|
|
832
|
+
label='Median' if i == 1 else '')
|
|
833
|
+
|
|
834
|
+
# Median value text - above the triangle
|
|
835
|
+
ax.text(median_val, median_y + triangle_offset + 0.05, f'median: {median_val:.2f}', ha='center', va='bottom', fontsize=8, fontweight='bold', color=colors[i-1], zorder=7)
|
|
836
|
+
|
|
837
|
+
# --- Labels & formatting ---
|
|
838
|
+
ax.set_yticks(range(1, n + 1))
|
|
839
|
+
ax.set_yticklabels(labels, fontsize=10)
|
|
840
|
+
if side == "lower":
|
|
841
|
+
ax.set_ylim(0.2, n + 0.5)
|
|
842
|
+
else:
|
|
843
|
+
ax.set_ylim(0.5, n + 0.5)
|
|
844
|
+
|
|
845
|
+
# Style improvements
|
|
846
|
+
ax.spines['top'].set_visible(False)
|
|
847
|
+
ax.spines['right'].set_visible(False)
|
|
848
|
+
ax.grid(axis='x', alpha=0.3, linestyle='--', linewidth=0.5)
|
|
849
|
+
|
|
850
|
+
if xlabel:
|
|
851
|
+
ax.set_xlabel(xlabel, fontsize=11, fontweight='bold')
|
|
852
|
+
if ylabel:
|
|
853
|
+
ax.set_ylabel(ylabel, fontsize=11, fontweight='bold')
|
|
854
|
+
if title:
|
|
855
|
+
ax.set_title(title, fontsize=13, fontweight='bold', pad=15)
|
|
856
|
+
|
|
857
|
+
plt.tight_layout()
|
|
858
|
+
return fig
|
|
718
859
|
|
|
719
860
|
|
|
720
|
-
|
|
721
|
-
def plot_dist(*args, ann=None, xlim=None, ylim=None, ylabel=None, xlabel=None, title=None, legend=None, show_hist=True, npoints=200, bins=30):
|
|
861
|
+
def dist_plot(*args, ann=None, xlim=None, ylim=None, ylabel=None, xlabel=None, title=None, legend=None, show_hist=True, npoints=200, bins=30):
|
|
722
862
|
"""
|
|
723
863
|
Plot distribution.
|
|
724
864
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
modusa-0.3.
|
|
2
|
-
modusa-0.3.
|
|
3
|
-
modusa-0.3.
|
|
4
|
-
modusa-0.3.
|
|
1
|
+
modusa-0.3.93.dist-info/METADATA,sha256=RDrVzEQDd_gSKmqp5zJb3sEXW1qf8ly0pUr_mMoT3ds,1436
|
|
2
|
+
modusa-0.3.93.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
|
3
|
+
modusa-0.3.93.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
|
|
4
|
+
modusa-0.3.93.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
|
|
5
5
|
modusa/.DS_Store,sha256=_gm6qJREwfMi8dE7n5S89_RG46u5t3xHyD-smNhtNoM,6148
|
|
6
|
-
modusa/__init__.py,sha256=
|
|
6
|
+
modusa/__init__.py,sha256=NlYjCzGVEesvEr3X2fIpNC4ZmNoEcoB3uUo-9VeI-8A,318
|
|
7
7
|
modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
|
|
8
8
|
modusa/decorators.py,sha256=8zeNX_wE37O6Vp0ysR4-WCZaEL8mq8dyCF_I5DHOzks,5905
|
|
9
9
|
modusa/devtools/generate_docs_source.py,sha256=UDflHsk-Yh9-3YJTVBzKL32y8hcxiRgAlFEBTMiDqwM,3301
|
|
@@ -41,7 +41,7 @@ modusa/models/t_ax.py,sha256=ZUhvZPUW1TkdZYuUd6Ucm-vsv0JqtZ9yEe3ab67Ma6w,8022
|
|
|
41
41
|
modusa/models/tds.py,sha256=FAGfibjyyE_lkEuQp-vSCuqQnopOjmy_IXqUjRlg9kc,11677
|
|
42
42
|
modusa/plugins/__init__.py,sha256=r1Bf5mnrVKRIwxboutY1iGzDy4EPQhqpk1kSW7iJj_Q,54
|
|
43
43
|
modusa/plugins/base.py,sha256=Bh_1Bja7fOymFsCgwhXDbV6ys3D8muNrPwrfDrG_G_A,2382
|
|
44
|
-
modusa/tools/__init__.py,sha256=
|
|
44
|
+
modusa/tools/__init__.py,sha256=q4d7J4xGraVLVLsk4h1OcWvi19FXd7DbJrGdUAOn5Es,336
|
|
45
45
|
modusa/tools/_plotter_old.py,sha256=KGow7mihA2H1WNq7s5bpivhCgGo2qVIeDaO6iabpsrg,19294
|
|
46
46
|
modusa/tools/ann_loader.py,sha256=GWiX7v4CxyAECthmtBAaSMMqsjo1YaVfRA9u-CtTTFM,1718
|
|
47
47
|
modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
|
|
@@ -51,7 +51,7 @@ modusa/tools/audio_recorder.py,sha256=K_LGqsPdjTdf3figEZTSQLmgMzYWgz18HTO8C1j5fE
|
|
|
51
51
|
modusa/tools/audio_saver.py,sha256=ldzfr_AydsHTnKbxmBLJblN-hLzTmOlppOm306xI4Ug,510
|
|
52
52
|
modusa/tools/base.py,sha256=C0ESJ0mIfjjRlAkRbSetNtMoOfS6IrHBjexRp3l_Mh4,1293
|
|
53
53
|
modusa/tools/math_ops.py,sha256=ZZ7U4DgqT7cOeE7_Lzi_Qq-48WYfwR9_osbZwTmE9eg,8690
|
|
54
|
-
modusa/tools/plotter.py,sha256=
|
|
54
|
+
modusa/tools/plotter.py,sha256=QUeFYJLP0u88VM_HJVRDzLRU0d8jTndgIvz8-OzUGuI,29786
|
|
55
55
|
modusa/tools/youtube_downloader.py,sha256=hB_X8-7nOHXOlxg6vv3wyhBLoAsWyomrULP6_uCQL7s,1698
|
|
56
56
|
modusa/utils/.DS_Store,sha256=nLXMwF7QJNuglLI_Gk74F7vl5Dyus2Wd74Mgowijmdo,6148
|
|
57
57
|
modusa/utils/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
|
@@ -60,4 +60,4 @@ modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906
|
|
|
60
60
|
modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
|
|
61
61
|
modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
|
|
62
62
|
modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
|
|
63
|
-
modusa-0.3.
|
|
63
|
+
modusa-0.3.93.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|