scitex 2.3.0__py3-none-any.whl → 2.4.1__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.
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1 -1
- scitex/ai/plt/__init__.py +2 -2
- scitex/ai/plt/{_plot_conf_mat.py → _stx_conf_mat.py} +3 -3
- scitex/config/PriorityConfig.py +195 -0
- scitex/config/__init__.py +24 -0
- scitex/io/_save.py +125 -34
- scitex/io/_save_modules/_image.py +37 -20
- scitex/plt/__init__.py +470 -17
- scitex/plt/_subplots/_AxisWrapper.py +98 -50
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +559 -124
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +49 -8
- scitex/plt/_subplots/_SubplotsWrapper.py +76 -91
- scitex/plt/_subplots/_export_as_csv.py +127 -58
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +25 -16
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contourf.py +54 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hexbin.py +41 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist2d.py +41 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -47
- scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +42 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_pie.py +42 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +72 -35
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -1
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +53 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stem.py +42 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_step.py +42 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +48 -0
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_conf_mat.py → _format_stx_conf_mat.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_ecdf.py → _format_stx_ecdf.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_fillv.py → _format_stx_fillv.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_heatmap.py → _format_stx_heatmap.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_image.py → _format_stx_image.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_joyplot.py → _format_stx_joyplot.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_line.py → _format_stx_line.py} +3 -3
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_mean_ci.py → _format_stx_mean_ci.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_mean_std.py → _format_stx_mean_std.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_median_iqr.py → _format_stx_median_iqr.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_raster.py → _format_stx_raster.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_rectangle.py → _format_stx_rectangle.py} +1 -1
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_scatter_hist.py → _format_stx_scatter_hist.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_shaded_line.py → _format_stx_shaded_line.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/{_format_plot_violin.py → _format_stx_violin.py} +2 -2
- scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +23 -23
- scitex/plt/ax/__init__.py +16 -15
- scitex/plt/ax/_plot/__init__.py +30 -30
- scitex/plt/ax/_plot/_add_fitted_line.py +65 -11
- scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +104 -76
- scitex/plt/ax/_plot/{_plot_conf_mat.py → _stx_conf_mat.py} +10 -10
- scitex/plt/ax/_plot/_stx_ecdf.py +109 -0
- scitex/plt/ax/_plot/{_plot_fillv.py → _stx_fillv.py} +7 -7
- scitex/plt/ax/_plot/_stx_heatmap.py +366 -0
- scitex/plt/ax/_plot/{_plot_image.py → _stx_image.py} +1 -1
- scitex/plt/ax/_plot/_stx_joyplot.py +113 -0
- scitex/plt/ax/_plot/{_plot_raster.py → _stx_raster.py} +37 -25
- scitex/plt/ax/_plot/{_plot_rectangle.py → _stx_rectangle.py} +10 -9
- scitex/plt/ax/_plot/{_plot_scatter_hist.py → _stx_scatter_hist.py} +1 -1
- scitex/plt/ax/_plot/_stx_shaded_line.py +215 -0
- scitex/plt/ax/_plot/{_plot_violin.py → _stx_violin.py} +13 -6
- scitex/plt/ax/_style/__init__.py +3 -0
- scitex/plt/ax/_style/_style_barplot.py +13 -2
- scitex/plt/ax/_style/_style_boxplot.py +78 -32
- scitex/plt/ax/_style/_style_errorbar.py +17 -3
- scitex/plt/ax/_style/_style_scatter.py +17 -3
- scitex/plt/ax/_style/_style_violinplot.py +109 -0
- scitex/plt/color/_vizualize_colors.py +3 -3
- scitex/plt/styles/SCITEX_STYLE.yaml +104 -0
- scitex/plt/styles/__init__.py +57 -0
- scitex/plt/styles/_plot_defaults.py +209 -0
- scitex/plt/styles/_plot_postprocess.py +518 -0
- scitex/plt/styles/_style_loader.py +268 -0
- scitex/plt/styles/presets.py +208 -0
- scitex/plt/utils/_collect_figure_metadata.py +160 -18
- scitex/plt/utils/_colorbar.py +72 -10
- scitex/plt/utils/_configure_mpl.py +108 -52
- scitex/plt/utils/_crop.py +21 -7
- scitex/plt/utils/_figure_mm.py +21 -7
- scitex/stats/__init__.py +13 -1
- scitex/stats/_schema.py +578 -0
- scitex/stats/tests/__init__.py +13 -0
- scitex/stats/tests/correlation/__init__.py +13 -0
- scitex/stats/tests/correlation/_test_pearson.py +262 -0
- scitex/vis/__init__.py +6 -0
- scitex/vis/editor/__init__.py +23 -0
- scitex/vis/editor/_defaults.py +205 -0
- scitex/vis/editor/_edit.py +342 -0
- scitex/vis/editor/_mpl_editor.py +231 -0
- scitex/vis/editor/_tkinter_editor.py +466 -0
- scitex/vis/editor/_web_editor.py +1440 -0
- scitex/vis/model/plot_types.py +15 -15
- {scitex-2.3.0.dist-info → scitex-2.4.1.dist-info}/METADATA +2 -1
- {scitex-2.3.0.dist-info → scitex-2.4.1.dist-info}/RECORD +94 -67
- {scitex-2.3.0.dist-info → scitex-2.4.1.dist-info}/WHEEL +1 -1
- scitex/plt/ax/_plot/_plot_ecdf.py +0 -84
- scitex/plt/ax/_plot/_plot_heatmap.py +0 -277
- scitex/plt/ax/_plot/_plot_joyplot.py +0 -77
- scitex/plt/ax/_plot/_plot_shaded_line.py +0 -142
- scitex/plt/presets.py +0 -224
- {scitex-2.3.0.dist-info → scitex-2.4.1.dist-info}/entry_points.txt +0 -0
- {scitex-2.3.0.dist-info → scitex-2.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-
|
|
4
|
-
# File: /home/ywatanabe/proj/
|
|
3
|
+
# Timestamp: "2025-12-01 12:00:00 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py
|
|
5
5
|
# ----------------------------------------
|
|
6
6
|
import os
|
|
7
7
|
|
|
@@ -19,17 +19,37 @@ from scipy.stats import gaussian_kde
|
|
|
19
19
|
|
|
20
20
|
from scitex.pd import to_xyz
|
|
21
21
|
from scitex.types import ArrayLike
|
|
22
|
+
from scitex.plt.utils import mm_to_pt
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ============================================================================
|
|
26
|
+
# Constants for default styling (same as styles/_plot_defaults.py)
|
|
27
|
+
# ============================================================================
|
|
28
|
+
DEFAULT_LINE_WIDTH_MM = 0.2
|
|
29
|
+
DEFAULT_MARKER_SIZE_MM = 0.8
|
|
30
|
+
DEFAULT_FILL_ALPHA = 0.3
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
class MatplotlibPlotMixin:
|
|
25
34
|
"""Mixin class for basic plotting operations."""
|
|
26
|
-
|
|
35
|
+
|
|
27
36
|
def _get_ax_module(self):
|
|
28
37
|
"""Lazy import ax module to avoid circular imports."""
|
|
29
38
|
from ....plt import ax as ax_module
|
|
30
39
|
return ax_module
|
|
31
40
|
|
|
32
|
-
def
|
|
41
|
+
def _apply_scitex_postprocess(self, method_name, result=None, kwargs=None, args=None):
|
|
42
|
+
"""Apply scitex post-processing styling after plotting.
|
|
43
|
+
|
|
44
|
+
This ensures all scitex wrapper methods get the same styling
|
|
45
|
+
as matplotlib methods going through __getattr__ (tick locator, spines, etc.).
|
|
46
|
+
"""
|
|
47
|
+
from scitex.plt.styles import apply_plot_postprocess
|
|
48
|
+
apply_plot_postprocess(
|
|
49
|
+
method_name, result, self._axis_mpl, kwargs or {}, args
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def stx_image(
|
|
33
53
|
self,
|
|
34
54
|
arr_2d: ArrayLike,
|
|
35
55
|
track: bool = True,
|
|
@@ -37,11 +57,11 @@ class MatplotlibPlotMixin:
|
|
|
37
57
|
**kwargs,
|
|
38
58
|
) -> None:
|
|
39
59
|
# Method Name for downstream csv exporting
|
|
40
|
-
method_name = "
|
|
60
|
+
method_name = "stx_image"
|
|
41
61
|
|
|
42
62
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
43
63
|
with self._no_tracking():
|
|
44
|
-
self._axis_mpl = self._get_ax_module().
|
|
64
|
+
self._axis_mpl = self._get_ax_module().stx_image(self._axis_mpl, arr_2d, **kwargs)
|
|
45
65
|
|
|
46
66
|
# Tracking
|
|
47
67
|
tracked_dict = {"image_df": pd.DataFrame(arr_2d)}
|
|
@@ -55,11 +75,14 @@ class MatplotlibPlotMixin:
|
|
|
55
75
|
None,
|
|
56
76
|
)
|
|
57
77
|
|
|
78
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
79
|
+
self._apply_scitex_postprocess(method_name)
|
|
80
|
+
|
|
58
81
|
return self._axis_mpl
|
|
59
82
|
|
|
60
|
-
def
|
|
83
|
+
def stx_kde(
|
|
61
84
|
self,
|
|
62
|
-
|
|
85
|
+
values_1d: ArrayLike,
|
|
63
86
|
cumulative=False,
|
|
64
87
|
fill=False,
|
|
65
88
|
track: bool = True,
|
|
@@ -67,23 +90,23 @@ class MatplotlibPlotMixin:
|
|
|
67
90
|
**kwargs,
|
|
68
91
|
) -> None:
|
|
69
92
|
# Method Name for downstream csv exporting
|
|
70
|
-
method_name = "
|
|
93
|
+
method_name = "stx_kde"
|
|
71
94
|
|
|
72
95
|
# Sample count as label
|
|
73
|
-
n_samples = (~np.isnan(
|
|
96
|
+
n_samples = (~np.isnan(values_1d)).sum()
|
|
74
97
|
if kwargs.get("label"):
|
|
75
|
-
kwargs["label"] = f"{kwargs['label']} (n
|
|
98
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
76
99
|
|
|
77
100
|
# Xlim (kwargs["xlim"] is not accepted in downstream plotters)
|
|
78
|
-
xlim = kwargs.
|
|
101
|
+
xlim = kwargs.pop("xlim", None)
|
|
79
102
|
if not xlim:
|
|
80
|
-
xlim = (np.nanmin(
|
|
103
|
+
xlim = (np.nanmin(values_1d), np.nanmax(values_1d))
|
|
81
104
|
|
|
82
105
|
# X
|
|
83
106
|
xx = np.linspace(xlim[0], xlim[1], int(1e3))
|
|
84
107
|
|
|
85
108
|
# Y
|
|
86
|
-
density = gaussian_kde(
|
|
109
|
+
density = gaussian_kde(values_1d)(xx)
|
|
87
110
|
density /= density.sum()
|
|
88
111
|
|
|
89
112
|
# Cumulative
|
|
@@ -101,6 +124,10 @@ class MatplotlibPlotMixin:
|
|
|
101
124
|
if 'color' not in kwargs and 'c' not in kwargs:
|
|
102
125
|
kwargs['color'] = 'black'
|
|
103
126
|
|
|
127
|
+
# Set default linestyle to dashed (customizable via linestyle kwarg)
|
|
128
|
+
if 'linestyle' not in kwargs and 'ls' not in kwargs:
|
|
129
|
+
kwargs['linestyle'] = '--'
|
|
130
|
+
|
|
104
131
|
# Filled Line
|
|
105
132
|
if fill:
|
|
106
133
|
self._axis_mpl.fill_between(
|
|
@@ -126,11 +153,14 @@ class MatplotlibPlotMixin:
|
|
|
126
153
|
None,
|
|
127
154
|
)
|
|
128
155
|
|
|
156
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
157
|
+
self._apply_scitex_postprocess(method_name)
|
|
158
|
+
|
|
129
159
|
return self._axis_mpl
|
|
130
160
|
|
|
131
|
-
def
|
|
161
|
+
def stx_conf_mat(
|
|
132
162
|
self,
|
|
133
|
-
|
|
163
|
+
conf_mat_2d: ArrayLike,
|
|
134
164
|
x_labels: Optional[List[str]] = None,
|
|
135
165
|
y_labels: Optional[List[str]] = None,
|
|
136
166
|
title: str = "Confusion Matrix",
|
|
@@ -146,13 +176,13 @@ class MatplotlibPlotMixin:
|
|
|
146
176
|
**kwargs,
|
|
147
177
|
) -> None:
|
|
148
178
|
# Method Name for downstream csv exporting
|
|
149
|
-
method_name = "
|
|
179
|
+
method_name = "stx_conf_mat"
|
|
150
180
|
|
|
151
181
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
152
182
|
with self._no_tracking():
|
|
153
|
-
self._axis_mpl, bacc_val = self._get_ax_module().
|
|
183
|
+
self._axis_mpl, bacc_val = self._get_ax_module().stx_conf_mat(
|
|
154
184
|
self._axis_mpl,
|
|
155
|
-
|
|
185
|
+
conf_mat_2d,
|
|
156
186
|
x_labels=x_labels,
|
|
157
187
|
y_labels=y_labels,
|
|
158
188
|
title=title,
|
|
@@ -170,10 +200,13 @@ class MatplotlibPlotMixin:
|
|
|
170
200
|
# Tracking
|
|
171
201
|
self._track(track, id, method_name, tracked_dict, None)
|
|
172
202
|
|
|
203
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
204
|
+
self._apply_scitex_postprocess(method_name)
|
|
205
|
+
|
|
173
206
|
return self._axis_mpl, bacc_val
|
|
174
207
|
|
|
175
208
|
# @wraps removed to avoid circular import
|
|
176
|
-
def
|
|
209
|
+
def stx_rectangle(
|
|
177
210
|
self,
|
|
178
211
|
xx: float,
|
|
179
212
|
yy: float,
|
|
@@ -184,11 +217,11 @@ class MatplotlibPlotMixin:
|
|
|
184
217
|
**kwargs,
|
|
185
218
|
) -> None:
|
|
186
219
|
# Method Name for downstream csv exporting
|
|
187
|
-
method_name = "
|
|
220
|
+
method_name = "stx_rectangle"
|
|
188
221
|
|
|
189
222
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
190
223
|
with self._no_tracking():
|
|
191
|
-
self._axis_mpl = self._get_ax_module().
|
|
224
|
+
self._axis_mpl = self._get_ax_module().stx_rectangle(
|
|
192
225
|
self._axis_mpl, xx, yy, width, height, **kwargs
|
|
193
226
|
)
|
|
194
227
|
|
|
@@ -196,13 +229,16 @@ class MatplotlibPlotMixin:
|
|
|
196
229
|
tracked_dict = {"xx": xx, "yy": yy, "width": width, "height": height}
|
|
197
230
|
self._track(track, id, method_name, tracked_dict, None)
|
|
198
231
|
|
|
232
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
233
|
+
self._apply_scitex_postprocess(method_name)
|
|
234
|
+
|
|
199
235
|
return self._axis_mpl
|
|
200
236
|
|
|
201
237
|
# @wraps removed to avoid circular import
|
|
202
|
-
def
|
|
238
|
+
def stx_fillv(
|
|
203
239
|
self,
|
|
204
|
-
|
|
205
|
-
|
|
240
|
+
starts_1d: ArrayLike,
|
|
241
|
+
ends_1d: ArrayLike,
|
|
206
242
|
color: str = "red",
|
|
207
243
|
alpha: float = 0.2,
|
|
208
244
|
track: bool = True,
|
|
@@ -210,51 +246,70 @@ class MatplotlibPlotMixin:
|
|
|
210
246
|
**kwargs,
|
|
211
247
|
) -> None:
|
|
212
248
|
# Method Name for downstream csv exporting
|
|
213
|
-
method_name = "
|
|
249
|
+
method_name = "stx_fillv"
|
|
214
250
|
|
|
215
251
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
216
252
|
with self._no_tracking():
|
|
217
|
-
self._axis_mpl = self._get_ax_module().
|
|
218
|
-
self._axis_mpl,
|
|
253
|
+
self._axis_mpl = self._get_ax_module().stx_fillv(
|
|
254
|
+
self._axis_mpl, starts_1d, ends_1d, color=color, alpha=alpha
|
|
219
255
|
)
|
|
220
256
|
|
|
221
257
|
# Tracking
|
|
222
|
-
tracked_dict = {"starts":
|
|
258
|
+
tracked_dict = {"starts": starts_1d, "ends": ends_1d}
|
|
223
259
|
self._track(track, id, method_name, tracked_dict, None)
|
|
224
260
|
|
|
261
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
262
|
+
self._apply_scitex_postprocess(method_name)
|
|
263
|
+
|
|
225
264
|
return self._axis_mpl
|
|
226
265
|
|
|
227
|
-
def
|
|
266
|
+
def stx_box(
|
|
228
267
|
self,
|
|
229
|
-
|
|
268
|
+
values_list: ArrayLike,
|
|
269
|
+
colors: Optional[List] = None,
|
|
230
270
|
track: bool = True,
|
|
231
271
|
id: Optional[str] = None,
|
|
232
272
|
**kwargs,
|
|
233
|
-
) ->
|
|
273
|
+
) -> dict:
|
|
234
274
|
# Method Name for downstream csv exporting
|
|
235
|
-
method_name = "
|
|
275
|
+
method_name = "stx_box"
|
|
236
276
|
|
|
237
277
|
# Copy data
|
|
238
|
-
_data =
|
|
278
|
+
_data = values_list.copy()
|
|
239
279
|
|
|
240
|
-
# Sample count as label
|
|
241
|
-
n = len(data)
|
|
280
|
+
# Sample count per group as label (show range if variable)
|
|
242
281
|
if kwargs.get("label"):
|
|
243
|
-
|
|
282
|
+
n_per_group = [len(g) for g in values_list]
|
|
283
|
+
n_min, n_max = min(n_per_group), max(n_per_group)
|
|
284
|
+
n_str = str(n_min) if n_min == n_max else f"{n_min}-{n_max}"
|
|
285
|
+
kwargs["label"] = kwargs["label"] + f" ($n$={n_str})"
|
|
286
|
+
|
|
287
|
+
# Enable patch_artist for styling (fill colors, edges)
|
|
288
|
+
if "patch_artist" not in kwargs:
|
|
289
|
+
kwargs["patch_artist"] = True
|
|
244
290
|
|
|
245
291
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
246
292
|
with self._no_tracking():
|
|
247
|
-
self._axis_mpl.boxplot(
|
|
293
|
+
result = self._axis_mpl.boxplot(values_list, **kwargs)
|
|
248
294
|
|
|
249
|
-
# Tracking
|
|
295
|
+
# Tracking - calculate sample size per group
|
|
296
|
+
n_per_group = [len(g) for g in values_list]
|
|
250
297
|
tracked_dict = {
|
|
251
298
|
"data": _data,
|
|
252
|
-
"n":
|
|
299
|
+
"n": n_per_group,
|
|
253
300
|
}
|
|
254
301
|
self._track(track, id, method_name, tracked_dict, None)
|
|
255
302
|
|
|
256
|
-
|
|
257
|
-
|
|
303
|
+
# Apply style_boxplot automatically for publication quality
|
|
304
|
+
# Uses scitex palette by default, or custom colors if provided
|
|
305
|
+
from scitex.plt.ax import style_boxplot
|
|
306
|
+
style_boxplot(result, colors=colors)
|
|
307
|
+
|
|
308
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
309
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
310
|
+
|
|
311
|
+
return result
|
|
312
|
+
|
|
258
313
|
def hist(
|
|
259
314
|
self,
|
|
260
315
|
x: ArrayLike,
|
|
@@ -312,13 +367,16 @@ class MatplotlibPlotMixin:
|
|
|
312
367
|
}
|
|
313
368
|
|
|
314
369
|
self._track(track, id, method_name, tracked_dict, kwargs)
|
|
315
|
-
|
|
370
|
+
|
|
371
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
372
|
+
self._apply_scitex_postprocess(method_name, hist_data)
|
|
373
|
+
|
|
316
374
|
return hist_data
|
|
317
375
|
|
|
318
376
|
# @wraps removed to avoid circular import
|
|
319
|
-
def
|
|
377
|
+
def stx_raster(
|
|
320
378
|
self,
|
|
321
|
-
|
|
379
|
+
spike_times_list: List[ArrayLike],
|
|
322
380
|
time: Optional[ArrayLike] = None,
|
|
323
381
|
labels: Optional[List[str]] = None,
|
|
324
382
|
colors: Optional[List[str]] = None,
|
|
@@ -327,90 +385,77 @@ class MatplotlibPlotMixin:
|
|
|
327
385
|
**kwargs,
|
|
328
386
|
) -> None:
|
|
329
387
|
# Method Name for downstream csv exporting
|
|
330
|
-
method_name = "
|
|
388
|
+
method_name = "stx_raster"
|
|
331
389
|
|
|
332
390
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
333
391
|
with self._no_tracking():
|
|
334
|
-
self._axis_mpl, raster_digit_df = self._get_ax_module().
|
|
335
|
-
self._axis_mpl,
|
|
392
|
+
self._axis_mpl, raster_digit_df = self._get_ax_module().stx_raster(
|
|
393
|
+
self._axis_mpl, spike_times_list, time=time
|
|
336
394
|
)
|
|
337
395
|
|
|
338
396
|
# Tracking
|
|
339
397
|
tracked_dict = {"raster_digit_df": raster_digit_df}
|
|
340
398
|
self._track(track, id, method_name, tracked_dict, None)
|
|
341
399
|
|
|
400
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
401
|
+
self._apply_scitex_postprocess(method_name)
|
|
402
|
+
|
|
342
403
|
return self._axis_mpl, raster_digit_df
|
|
343
404
|
|
|
344
405
|
# @wraps removed to avoid circular import
|
|
345
|
-
def
|
|
406
|
+
def stx_ecdf(
|
|
346
407
|
self,
|
|
347
|
-
|
|
408
|
+
values_1d: ArrayLike,
|
|
348
409
|
track: bool = True,
|
|
349
410
|
id: Optional[str] = None,
|
|
350
411
|
**kwargs,
|
|
351
412
|
) -> None:
|
|
352
413
|
# Method Name for downstream csv exporting
|
|
353
|
-
method_name = "
|
|
414
|
+
method_name = "stx_ecdf"
|
|
354
415
|
|
|
355
416
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
356
417
|
with self._no_tracking():
|
|
357
|
-
self._axis_mpl, ecdf_df = self._get_ax_module().
|
|
358
|
-
self._axis_mpl,
|
|
418
|
+
self._axis_mpl, ecdf_df = self._get_ax_module().stx_ecdf(
|
|
419
|
+
self._axis_mpl, values_1d, **kwargs
|
|
359
420
|
)
|
|
360
421
|
|
|
361
422
|
# Tracking
|
|
362
423
|
tracked_dict = {"ecdf_df": ecdf_df}
|
|
363
424
|
self._track(track, id, method_name, tracked_dict, None)
|
|
364
425
|
|
|
426
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
427
|
+
self._apply_scitex_postprocess(method_name)
|
|
428
|
+
|
|
365
429
|
return self._axis_mpl, ecdf_df
|
|
366
430
|
|
|
367
431
|
# @wraps removed to avoid circular import
|
|
368
|
-
def
|
|
432
|
+
def stx_joyplot(
|
|
369
433
|
self,
|
|
370
|
-
|
|
371
|
-
orientation: str = "vertical",
|
|
434
|
+
arrays: ArrayLike,
|
|
372
435
|
track: bool = True,
|
|
373
436
|
id: Optional[str] = None,
|
|
374
437
|
**kwargs,
|
|
375
438
|
) -> None:
|
|
376
439
|
# Method Name for downstream csv exporting
|
|
377
|
-
method_name = "
|
|
440
|
+
method_name = "stx_joyplot"
|
|
378
441
|
|
|
379
442
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
380
443
|
with self._no_tracking():
|
|
381
|
-
self._axis_mpl = self._get_ax_module().
|
|
382
|
-
self._axis_mpl,
|
|
444
|
+
self._axis_mpl = self._get_ax_module().stx_joyplot(
|
|
445
|
+
self._axis_mpl, arrays, **kwargs
|
|
383
446
|
)
|
|
384
447
|
|
|
385
448
|
# Tracking
|
|
386
|
-
tracked_dict = {"
|
|
449
|
+
tracked_dict = {"joyplot_arrays": arrays}
|
|
387
450
|
self._track(track, id, method_name, tracked_dict, None)
|
|
388
451
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
# @wraps removed to avoid circular import
|
|
392
|
-
def plot_joyplot(
|
|
393
|
-
self,
|
|
394
|
-
data: ArrayLike,
|
|
395
|
-
track: bool = True,
|
|
396
|
-
id: Optional[str] = None,
|
|
397
|
-
**kwargs,
|
|
398
|
-
) -> None:
|
|
399
|
-
# Method Name for downstream csv exporting
|
|
400
|
-
method_name = "plot_joyplot"
|
|
401
|
-
|
|
402
|
-
# Plotting with pure matplotlib methods under non-tracking context
|
|
403
|
-
with self._no_tracking():
|
|
404
|
-
self._axis_mpl = self._get_ax_module().plot_joyplot(self._axis_mpl, data, **kwargs)
|
|
405
|
-
|
|
406
|
-
# Tracking
|
|
407
|
-
tracked_dict = {"joyplot_data": data}
|
|
408
|
-
self._track(track, id, method_name, tracked_dict, None)
|
|
452
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
453
|
+
self._apply_scitex_postprocess(method_name)
|
|
409
454
|
|
|
410
455
|
return self._axis_mpl
|
|
411
456
|
|
|
412
457
|
# @wraps removed to avoid circular import
|
|
413
|
-
def
|
|
458
|
+
def stx_scatter_hist(
|
|
414
459
|
self,
|
|
415
460
|
x: ArrayLike,
|
|
416
461
|
y: ArrayLike,
|
|
@@ -428,11 +473,11 @@ class MatplotlibPlotMixin:
|
|
|
428
473
|
) -> None:
|
|
429
474
|
"""Plot a scatter plot with marginal histograms."""
|
|
430
475
|
# Method Name for downstream csv exporting
|
|
431
|
-
method_name = "
|
|
476
|
+
method_name = "stx_scatter_hist"
|
|
432
477
|
|
|
433
478
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
434
479
|
with self._no_tracking():
|
|
435
|
-
self._axis_mpl, ax_histx, ax_histy, hist_data = self._get_ax_module().
|
|
480
|
+
self._axis_mpl, ax_histx, ax_histy, hist_data = self._get_ax_module().stx_scatter_hist(
|
|
436
481
|
self._axis_mpl,
|
|
437
482
|
x,
|
|
438
483
|
y,
|
|
@@ -458,12 +503,15 @@ class MatplotlibPlotMixin:
|
|
|
458
503
|
}
|
|
459
504
|
self._track(track, id, method_name, tracked_dict, None)
|
|
460
505
|
|
|
506
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
507
|
+
self._apply_scitex_postprocess(method_name)
|
|
508
|
+
|
|
461
509
|
return self._axis_mpl, ax_histx, ax_histy, hist_data
|
|
462
510
|
|
|
463
511
|
# @wraps removed to avoid circular import
|
|
464
|
-
def
|
|
512
|
+
def stx_heatmap(
|
|
465
513
|
self,
|
|
466
|
-
|
|
514
|
+
values_2d: ArrayLike,
|
|
467
515
|
x_labels: Optional[List[str]] = None,
|
|
468
516
|
y_labels: Optional[List[str]] = None,
|
|
469
517
|
cmap: str = "viridis",
|
|
@@ -478,13 +526,13 @@ class MatplotlibPlotMixin:
|
|
|
478
526
|
) -> Tuple[matplotlib.image.AxesImage, matplotlib.colorbar.Colorbar]:
|
|
479
527
|
"""Plot a heatmap on the axes."""
|
|
480
528
|
# Method Name for downstream csv exporting
|
|
481
|
-
method_name = "
|
|
529
|
+
method_name = "stx_heatmap"
|
|
482
530
|
|
|
483
531
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
484
532
|
with self._no_tracking():
|
|
485
|
-
ax, im, cbar = self._get_ax_module().
|
|
533
|
+
ax, im, cbar = self._get_ax_module().stx_heatmap(
|
|
486
534
|
self._axis_mpl,
|
|
487
|
-
|
|
535
|
+
values_2d,
|
|
488
536
|
x_labels=x_labels,
|
|
489
537
|
y_labels=y_labels,
|
|
490
538
|
cmap=cmap,
|
|
@@ -498,18 +546,21 @@ class MatplotlibPlotMixin:
|
|
|
498
546
|
|
|
499
547
|
# Tracking
|
|
500
548
|
tracked_dict = {
|
|
501
|
-
"data":
|
|
549
|
+
"data": values_2d,
|
|
502
550
|
"x_labels": x_labels,
|
|
503
551
|
"y_labels": y_labels,
|
|
504
552
|
}
|
|
505
553
|
self._track(track, id, method_name, tracked_dict, None)
|
|
506
554
|
|
|
555
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
556
|
+
self._apply_scitex_postprocess(method_name)
|
|
557
|
+
|
|
507
558
|
return ax, im, cbar
|
|
508
559
|
|
|
509
560
|
# @wraps removed to avoid circular import
|
|
510
|
-
def
|
|
561
|
+
def stx_violin(
|
|
511
562
|
self,
|
|
512
|
-
|
|
563
|
+
values_list: Union[pd.DataFrame, List, ArrayLike],
|
|
513
564
|
x=None,
|
|
514
565
|
y=None,
|
|
515
566
|
hue=None,
|
|
@@ -522,17 +573,17 @@ class MatplotlibPlotMixin:
|
|
|
522
573
|
) -> None:
|
|
523
574
|
"""Plot a violin plot."""
|
|
524
575
|
# Method Name for downstream csv exporting
|
|
525
|
-
method_name = "
|
|
576
|
+
method_name = "stx_violin"
|
|
526
577
|
|
|
527
578
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
528
579
|
with self._no_tracking():
|
|
529
580
|
# Handle the list-style input case
|
|
530
|
-
if isinstance(
|
|
531
|
-
isinstance(item, (list, np.ndarray)) for item in
|
|
581
|
+
if isinstance(values_list, list) and all(
|
|
582
|
+
isinstance(item, (list, np.ndarray)) for item in values_list
|
|
532
583
|
):
|
|
533
|
-
self._axis_mpl = self._get_ax_module().
|
|
584
|
+
self._axis_mpl = self._get_ax_module().stx_violin(
|
|
534
585
|
self._axis_mpl,
|
|
535
|
-
|
|
586
|
+
values_list=values_list,
|
|
536
587
|
labels=labels,
|
|
537
588
|
colors=colors,
|
|
538
589
|
half=half,
|
|
@@ -540,9 +591,9 @@ class MatplotlibPlotMixin:
|
|
|
540
591
|
)
|
|
541
592
|
# Handle DataFrame or other inputs
|
|
542
593
|
else:
|
|
543
|
-
self._axis_mpl = self._get_ax_module().
|
|
594
|
+
self._axis_mpl = self._get_ax_module().stx_violin(
|
|
544
595
|
self._axis_mpl,
|
|
545
|
-
data=
|
|
596
|
+
data=values_list,
|
|
546
597
|
x=x,
|
|
547
598
|
y=y,
|
|
548
599
|
hue=hue,
|
|
@@ -552,7 +603,7 @@ class MatplotlibPlotMixin:
|
|
|
552
603
|
|
|
553
604
|
# Tracking
|
|
554
605
|
tracked_dict = {
|
|
555
|
-
"data":
|
|
606
|
+
"data": values_list,
|
|
556
607
|
"x": x,
|
|
557
608
|
"y": y,
|
|
558
609
|
"hue": hue,
|
|
@@ -561,6 +612,10 @@ class MatplotlibPlotMixin:
|
|
|
561
612
|
"colors": colors,
|
|
562
613
|
}
|
|
563
614
|
self._track(track, id, method_name, tracked_dict, None)
|
|
615
|
+
|
|
616
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
617
|
+
self._apply_scitex_postprocess(method_name)
|
|
618
|
+
|
|
564
619
|
return self._axis_mpl
|
|
565
620
|
|
|
566
621
|
# def plot_area(
|
|
@@ -766,9 +821,9 @@ class MatplotlibPlotMixin:
|
|
|
766
821
|
# return self._axis_mpl
|
|
767
822
|
|
|
768
823
|
# @wraps removed to avoid circular import
|
|
769
|
-
def
|
|
824
|
+
def stx_line(
|
|
770
825
|
self,
|
|
771
|
-
|
|
826
|
+
values_1d: ArrayLike,
|
|
772
827
|
xx: Optional[ArrayLike] = None,
|
|
773
828
|
track: bool = True,
|
|
774
829
|
id: Optional[str] = None,
|
|
@@ -776,24 +831,27 @@ class MatplotlibPlotMixin:
|
|
|
776
831
|
) -> None:
|
|
777
832
|
"""Plot a simple line."""
|
|
778
833
|
# Method Name for downstream csv exporting
|
|
779
|
-
method_name = "
|
|
834
|
+
method_name = "stx_line"
|
|
780
835
|
|
|
781
836
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
782
837
|
with self._no_tracking():
|
|
783
|
-
self._axis_mpl, plot_df = self._get_ax_module().
|
|
784
|
-
self._axis_mpl,
|
|
838
|
+
self._axis_mpl, plot_df = self._get_ax_module().stx_line(
|
|
839
|
+
self._axis_mpl, values_1d, xx=xx, **kwargs
|
|
785
840
|
)
|
|
786
841
|
|
|
787
842
|
# Tracking
|
|
788
843
|
tracked_dict = {"plot_df": plot_df}
|
|
789
844
|
self._track(track, id, method_name, tracked_dict, None)
|
|
790
845
|
|
|
846
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
847
|
+
self._apply_scitex_postprocess(method_name)
|
|
848
|
+
|
|
791
849
|
return self._axis_mpl, plot_df
|
|
792
850
|
|
|
793
851
|
# @wraps removed to avoid circular import
|
|
794
|
-
def
|
|
852
|
+
def stx_mean_std(
|
|
795
853
|
self,
|
|
796
|
-
|
|
854
|
+
values_2d: ArrayLike,
|
|
797
855
|
xx: Optional[ArrayLike] = None,
|
|
798
856
|
sd: float = 1,
|
|
799
857
|
track: bool = True,
|
|
@@ -802,24 +860,27 @@ class MatplotlibPlotMixin:
|
|
|
802
860
|
) -> None:
|
|
803
861
|
"""Plot mean line with standard deviation shading."""
|
|
804
862
|
# Method Name for downstream csv exporting
|
|
805
|
-
method_name = "
|
|
863
|
+
method_name = "stx_mean_std"
|
|
806
864
|
|
|
807
865
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
808
866
|
with self._no_tracking():
|
|
809
|
-
self._axis_mpl, plot_df = self._get_ax_module().
|
|
810
|
-
self._axis_mpl,
|
|
867
|
+
self._axis_mpl, plot_df = self._get_ax_module().stx_mean_std(
|
|
868
|
+
self._axis_mpl, values_2d, xx=xx, sd=sd, **kwargs
|
|
811
869
|
)
|
|
812
870
|
|
|
813
871
|
# Tracking
|
|
814
872
|
tracked_dict = {"plot_df": plot_df}
|
|
815
873
|
self._track(track, id, method_name, tracked_dict, None)
|
|
816
874
|
|
|
875
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
876
|
+
self._apply_scitex_postprocess(method_name)
|
|
877
|
+
|
|
817
878
|
return self._axis_mpl, plot_df
|
|
818
879
|
|
|
819
880
|
# @wraps removed to avoid circular import
|
|
820
|
-
def
|
|
881
|
+
def stx_mean_ci(
|
|
821
882
|
self,
|
|
822
|
-
|
|
883
|
+
values_2d: ArrayLike,
|
|
823
884
|
xx: Optional[ArrayLike] = None,
|
|
824
885
|
perc: float = 95,
|
|
825
886
|
track: bool = True,
|
|
@@ -828,24 +889,27 @@ class MatplotlibPlotMixin:
|
|
|
828
889
|
) -> None:
|
|
829
890
|
"""Plot mean line with confidence interval shading."""
|
|
830
891
|
# Method Name for downstream csv exporting
|
|
831
|
-
method_name = "
|
|
892
|
+
method_name = "stx_mean_ci"
|
|
832
893
|
|
|
833
894
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
834
895
|
with self._no_tracking():
|
|
835
|
-
self._axis_mpl, plot_df = self._get_ax_module().
|
|
836
|
-
self._axis_mpl,
|
|
896
|
+
self._axis_mpl, plot_df = self._get_ax_module().stx_mean_ci(
|
|
897
|
+
self._axis_mpl, values_2d, xx=xx, perc=perc, **kwargs
|
|
837
898
|
)
|
|
838
899
|
|
|
839
900
|
# Tracking
|
|
840
901
|
tracked_dict = {"plot_df": plot_df}
|
|
841
902
|
self._track(track, id, method_name, tracked_dict, None)
|
|
842
903
|
|
|
904
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
905
|
+
self._apply_scitex_postprocess(method_name)
|
|
906
|
+
|
|
843
907
|
return self._axis_mpl, plot_df
|
|
844
908
|
|
|
845
909
|
# @wraps removed to avoid circular import
|
|
846
|
-
def
|
|
910
|
+
def stx_median_iqr(
|
|
847
911
|
self,
|
|
848
|
-
|
|
912
|
+
values_2d: ArrayLike,
|
|
849
913
|
xx: Optional[ArrayLike] = None,
|
|
850
914
|
track: bool = True,
|
|
851
915
|
id: Optional[str] = None,
|
|
@@ -853,22 +917,25 @@ class MatplotlibPlotMixin:
|
|
|
853
917
|
) -> None:
|
|
854
918
|
"""Plot median line with interquartile range shading."""
|
|
855
919
|
# Method Name for downstream csv exporting
|
|
856
|
-
method_name = "
|
|
920
|
+
method_name = "stx_median_iqr"
|
|
857
921
|
|
|
858
922
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
859
923
|
with self._no_tracking():
|
|
860
|
-
self._axis_mpl, plot_df = self._get_ax_module().
|
|
861
|
-
self._axis_mpl,
|
|
924
|
+
self._axis_mpl, plot_df = self._get_ax_module().stx_median_iqr(
|
|
925
|
+
self._axis_mpl, values_2d, xx=xx, **kwargs
|
|
862
926
|
)
|
|
863
927
|
|
|
864
928
|
# Tracking
|
|
865
929
|
tracked_dict = {"plot_df": plot_df}
|
|
866
930
|
self._track(track, id, method_name, tracked_dict, None)
|
|
867
931
|
|
|
932
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
933
|
+
self._apply_scitex_postprocess(method_name)
|
|
934
|
+
|
|
868
935
|
return self._axis_mpl, plot_df
|
|
869
936
|
|
|
870
937
|
# @wraps removed to avoid circular import
|
|
871
|
-
def
|
|
938
|
+
def stx_shaded_line(
|
|
872
939
|
self,
|
|
873
940
|
xs: ArrayLike,
|
|
874
941
|
ys_lower: ArrayLike,
|
|
@@ -882,11 +949,11 @@ class MatplotlibPlotMixin:
|
|
|
882
949
|
) -> None:
|
|
883
950
|
"""Plot a line with shaded area between lower and upper bounds."""
|
|
884
951
|
# Method Name for downstream csv exporting
|
|
885
|
-
method_name = "
|
|
952
|
+
method_name = "stx_shaded_line"
|
|
886
953
|
|
|
887
954
|
# Plotting with pure matplotlib methods under non-tracking context
|
|
888
955
|
with self._no_tracking():
|
|
889
|
-
self._axis_mpl, plot_df = self._get_ax_module().
|
|
956
|
+
self._axis_mpl, plot_df = self._get_ax_module().stx_shaded_line(
|
|
890
957
|
self._axis_mpl,
|
|
891
958
|
xs,
|
|
892
959
|
ys_lower,
|
|
@@ -901,8 +968,316 @@ class MatplotlibPlotMixin:
|
|
|
901
968
|
tracked_dict = {"plot_df": plot_df}
|
|
902
969
|
self._track(track, id, method_name, tracked_dict, None)
|
|
903
970
|
|
|
971
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
972
|
+
self._apply_scitex_postprocess(method_name)
|
|
973
|
+
|
|
904
974
|
return self._axis_mpl, plot_df
|
|
905
975
|
|
|
976
|
+
# =========================================================================
|
|
977
|
+
# stx_ aliases for standard matplotlib methods
|
|
978
|
+
# These provide a consistent stx_ prefix for all scitex wrapper methods
|
|
979
|
+
# =========================================================================
|
|
980
|
+
|
|
981
|
+
def stx_bar(self, x, height, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
982
|
+
"""Bar plot with scitex styling and tracking.
|
|
983
|
+
|
|
984
|
+
Parameters
|
|
985
|
+
----------
|
|
986
|
+
x : array-like
|
|
987
|
+
The x coordinates of the bars
|
|
988
|
+
height : array-like
|
|
989
|
+
The heights of the bars
|
|
990
|
+
track : bool
|
|
991
|
+
Whether to track data for CSV export
|
|
992
|
+
id : str, optional
|
|
993
|
+
Identifier for tracking
|
|
994
|
+
**kwargs
|
|
995
|
+
Additional arguments passed to matplotlib bar
|
|
996
|
+
"""
|
|
997
|
+
method_name = "stx_bar"
|
|
998
|
+
|
|
999
|
+
# Add sample size to label if provided
|
|
1000
|
+
if kwargs.get("label"):
|
|
1001
|
+
n_samples = len(x)
|
|
1002
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
1003
|
+
|
|
1004
|
+
with self._no_tracking():
|
|
1005
|
+
result = self._axis_mpl.bar(x, height, **kwargs)
|
|
1006
|
+
|
|
1007
|
+
# Track bar data
|
|
1008
|
+
tracked_dict = {"bar_df": pd.DataFrame({"x": x, "height": height})}
|
|
1009
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1010
|
+
|
|
1011
|
+
# Apply style_barplot automatically for publication quality
|
|
1012
|
+
from scitex.plt.ax import style_barplot
|
|
1013
|
+
style_barplot(result)
|
|
1014
|
+
|
|
1015
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1016
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1017
|
+
|
|
1018
|
+
return result
|
|
1019
|
+
|
|
1020
|
+
def stx_barh(self, y, width, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1021
|
+
"""Horizontal bar plot with scitex styling and tracking.
|
|
1022
|
+
|
|
1023
|
+
Parameters
|
|
1024
|
+
----------
|
|
1025
|
+
y : array-like
|
|
1026
|
+
The y coordinates of the bars
|
|
1027
|
+
width : array-like
|
|
1028
|
+
The widths of the bars
|
|
1029
|
+
track : bool
|
|
1030
|
+
Whether to track data for CSV export
|
|
1031
|
+
id : str, optional
|
|
1032
|
+
Identifier for tracking
|
|
1033
|
+
**kwargs
|
|
1034
|
+
Additional arguments passed to matplotlib barh
|
|
1035
|
+
"""
|
|
1036
|
+
method_name = "stx_barh"
|
|
1037
|
+
|
|
1038
|
+
# Add sample size to label if provided
|
|
1039
|
+
if kwargs.get("label"):
|
|
1040
|
+
n_samples = len(y)
|
|
1041
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
1042
|
+
|
|
1043
|
+
with self._no_tracking():
|
|
1044
|
+
result = self._axis_mpl.barh(y, width, **kwargs)
|
|
1045
|
+
|
|
1046
|
+
# Track bar data
|
|
1047
|
+
tracked_dict = {"barh_df": pd.DataFrame({"y": y, "width": width})}
|
|
1048
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1049
|
+
|
|
1050
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1051
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1052
|
+
|
|
1053
|
+
return result
|
|
1054
|
+
|
|
1055
|
+
def stx_scatter(self, x, y, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1056
|
+
"""Scatter plot with scitex styling and tracking.
|
|
1057
|
+
|
|
1058
|
+
Parameters
|
|
1059
|
+
----------
|
|
1060
|
+
x : array-like
|
|
1061
|
+
The x coordinates of the points
|
|
1062
|
+
y : array-like
|
|
1063
|
+
The y coordinates of the points
|
|
1064
|
+
track : bool
|
|
1065
|
+
Whether to track data for CSV export
|
|
1066
|
+
id : str, optional
|
|
1067
|
+
Identifier for tracking
|
|
1068
|
+
**kwargs
|
|
1069
|
+
Additional arguments passed to matplotlib scatter
|
|
1070
|
+
"""
|
|
1071
|
+
method_name = "stx_scatter"
|
|
1072
|
+
|
|
1073
|
+
# Add sample size to label if provided
|
|
1074
|
+
if kwargs.get("label"):
|
|
1075
|
+
n_samples = len(x)
|
|
1076
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
1077
|
+
|
|
1078
|
+
with self._no_tracking():
|
|
1079
|
+
result = self._axis_mpl.scatter(x, y, **kwargs)
|
|
1080
|
+
|
|
1081
|
+
# Track scatter data
|
|
1082
|
+
tracked_dict = {"scatter_df": pd.DataFrame({"x": x, "y": y})}
|
|
1083
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1084
|
+
|
|
1085
|
+
# Apply style_scatter automatically for publication quality
|
|
1086
|
+
from scitex.plt.ax import style_scatter
|
|
1087
|
+
style_scatter(result)
|
|
1088
|
+
|
|
1089
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1090
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1091
|
+
|
|
1092
|
+
return result
|
|
1093
|
+
|
|
1094
|
+
def stx_errorbar(self, x, y, yerr=None, xerr=None, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1095
|
+
"""Error bar plot with scitex styling and tracking.
|
|
1096
|
+
|
|
1097
|
+
Parameters
|
|
1098
|
+
----------
|
|
1099
|
+
x : array-like
|
|
1100
|
+
The x coordinates of the data points
|
|
1101
|
+
y : array-like
|
|
1102
|
+
The y coordinates of the data points
|
|
1103
|
+
yerr : array-like, optional
|
|
1104
|
+
The y error values
|
|
1105
|
+
xerr : array-like, optional
|
|
1106
|
+
The x error values
|
|
1107
|
+
track : bool
|
|
1108
|
+
Whether to track data for CSV export
|
|
1109
|
+
id : str, optional
|
|
1110
|
+
Identifier for tracking
|
|
1111
|
+
**kwargs
|
|
1112
|
+
Additional arguments passed to matplotlib errorbar
|
|
1113
|
+
"""
|
|
1114
|
+
method_name = "stx_errorbar"
|
|
1115
|
+
|
|
1116
|
+
# Add sample size to label if provided
|
|
1117
|
+
if kwargs.get("label"):
|
|
1118
|
+
n_samples = len(x)
|
|
1119
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
1120
|
+
|
|
1121
|
+
with self._no_tracking():
|
|
1122
|
+
result = self._axis_mpl.errorbar(x, y, yerr=yerr, xerr=xerr, **kwargs)
|
|
1123
|
+
|
|
1124
|
+
# Track errorbar data
|
|
1125
|
+
df_dict = {"x": x, "y": y}
|
|
1126
|
+
if yerr is not None:
|
|
1127
|
+
df_dict["yerr"] = yerr
|
|
1128
|
+
if xerr is not None:
|
|
1129
|
+
df_dict["xerr"] = xerr
|
|
1130
|
+
tracked_dict = {"errorbar_df": pd.DataFrame(df_dict)}
|
|
1131
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1132
|
+
|
|
1133
|
+
# Apply style_errorbar automatically for publication quality
|
|
1134
|
+
from scitex.plt.ax import style_errorbar
|
|
1135
|
+
style_errorbar(result)
|
|
1136
|
+
|
|
1137
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1138
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1139
|
+
|
|
1140
|
+
return result
|
|
1141
|
+
|
|
1142
|
+
def stx_fill_between(self, x, y1, y2=0, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1143
|
+
"""Fill between plot with scitex styling and tracking.
|
|
1144
|
+
|
|
1145
|
+
Parameters
|
|
1146
|
+
----------
|
|
1147
|
+
x : array-like
|
|
1148
|
+
The x coordinates
|
|
1149
|
+
y1 : array-like
|
|
1150
|
+
The first y boundary
|
|
1151
|
+
y2 : array-like or scalar, optional
|
|
1152
|
+
The second y boundary (default 0)
|
|
1153
|
+
track : bool
|
|
1154
|
+
Whether to track data for CSV export
|
|
1155
|
+
id : str, optional
|
|
1156
|
+
Identifier for tracking
|
|
1157
|
+
**kwargs
|
|
1158
|
+
Additional arguments passed to matplotlib fill_between
|
|
1159
|
+
"""
|
|
1160
|
+
method_name = "stx_fill_between"
|
|
1161
|
+
|
|
1162
|
+
with self._no_tracking():
|
|
1163
|
+
result = self._axis_mpl.fill_between(x, y1, y2, **kwargs)
|
|
1164
|
+
|
|
1165
|
+
# Track fill_between data
|
|
1166
|
+
tracked_dict = {"fill_between_df": pd.DataFrame({
|
|
1167
|
+
"x": x,
|
|
1168
|
+
"y1": y1,
|
|
1169
|
+
"y2": y2 if hasattr(y2, '__len__') else [y2] * len(x)
|
|
1170
|
+
})}
|
|
1171
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1172
|
+
|
|
1173
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1174
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1175
|
+
|
|
1176
|
+
return result
|
|
1177
|
+
|
|
1178
|
+
def stx_contour(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1179
|
+
"""Contour plot with scitex styling and tracking.
|
|
1180
|
+
|
|
1181
|
+
Parameters
|
|
1182
|
+
----------
|
|
1183
|
+
*args
|
|
1184
|
+
Positional arguments passed to matplotlib contour (X, Y, Z)
|
|
1185
|
+
track : bool
|
|
1186
|
+
Whether to track data for CSV export
|
|
1187
|
+
id : str, optional
|
|
1188
|
+
Identifier for tracking
|
|
1189
|
+
**kwargs
|
|
1190
|
+
Additional arguments passed to matplotlib contour
|
|
1191
|
+
"""
|
|
1192
|
+
method_name = "stx_contour"
|
|
1193
|
+
|
|
1194
|
+
with self._no_tracking():
|
|
1195
|
+
result = self._axis_mpl.contour(*args, **kwargs)
|
|
1196
|
+
|
|
1197
|
+
# Track contour data
|
|
1198
|
+
if len(args) >= 3:
|
|
1199
|
+
X, Y, Z = args[0], args[1], args[2]
|
|
1200
|
+
tracked_dict = {"contour_df": pd.DataFrame({
|
|
1201
|
+
"X": np.ravel(X),
|
|
1202
|
+
"Y": np.ravel(Y),
|
|
1203
|
+
"Z": np.ravel(Z)
|
|
1204
|
+
})}
|
|
1205
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1206
|
+
|
|
1207
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1208
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1209
|
+
|
|
1210
|
+
return result
|
|
1211
|
+
|
|
1212
|
+
def stx_imshow(self, data, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1213
|
+
"""Image display with scitex styling and tracking.
|
|
1214
|
+
|
|
1215
|
+
Parameters
|
|
1216
|
+
----------
|
|
1217
|
+
data : array-like
|
|
1218
|
+
2D array of image data
|
|
1219
|
+
track : bool
|
|
1220
|
+
Whether to track data for CSV export
|
|
1221
|
+
id : str, optional
|
|
1222
|
+
Identifier for tracking
|
|
1223
|
+
**kwargs
|
|
1224
|
+
Additional arguments passed to matplotlib imshow
|
|
1225
|
+
"""
|
|
1226
|
+
method_name = "stx_imshow"
|
|
1227
|
+
|
|
1228
|
+
with self._no_tracking():
|
|
1229
|
+
result = self._axis_mpl.imshow(data, **kwargs)
|
|
1230
|
+
|
|
1231
|
+
# Track image data
|
|
1232
|
+
if hasattr(data, 'shape') and len(data.shape) == 2:
|
|
1233
|
+
n_rows, n_cols = data.shape
|
|
1234
|
+
df = pd.DataFrame(data, columns=[f"col_{i}" for i in range(n_cols)])
|
|
1235
|
+
else:
|
|
1236
|
+
df = pd.DataFrame(data)
|
|
1237
|
+
tracked_dict = {"imshow_df": df}
|
|
1238
|
+
self._track(track, id, method_name, tracked_dict, None)
|
|
1239
|
+
|
|
1240
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1241
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1242
|
+
|
|
1243
|
+
return result
|
|
1244
|
+
|
|
1245
|
+
def stx_boxplot(self, data, colors: Optional[List] = None, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1246
|
+
"""Boxplot with scitex styling and tracking (alias for stx_box).
|
|
1247
|
+
|
|
1248
|
+
Parameters
|
|
1249
|
+
----------
|
|
1250
|
+
data : list of array-like
|
|
1251
|
+
List of data arrays for each box
|
|
1252
|
+
colors : list, optional
|
|
1253
|
+
Colors for each box
|
|
1254
|
+
track : bool
|
|
1255
|
+
Whether to track data for CSV export
|
|
1256
|
+
id : str, optional
|
|
1257
|
+
Identifier for tracking
|
|
1258
|
+
**kwargs
|
|
1259
|
+
Additional arguments passed to matplotlib boxplot
|
|
1260
|
+
"""
|
|
1261
|
+
return self.stx_box(data, colors=colors, track=track, id=id, **kwargs)
|
|
1262
|
+
|
|
1263
|
+
def stx_violinplot(self, data, colors: Optional[List] = None, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1264
|
+
"""Violinplot with scitex styling and tracking (alias for stx_violin).
|
|
1265
|
+
|
|
1266
|
+
Parameters
|
|
1267
|
+
----------
|
|
1268
|
+
data : list of array-like or DataFrame
|
|
1269
|
+
Data for violin plot
|
|
1270
|
+
colors : list, optional
|
|
1271
|
+
Colors for each violin
|
|
1272
|
+
track : bool
|
|
1273
|
+
Whether to track data for CSV export
|
|
1274
|
+
id : str, optional
|
|
1275
|
+
Identifier for tracking
|
|
1276
|
+
**kwargs
|
|
1277
|
+
Additional arguments passed to stx_violin
|
|
1278
|
+
"""
|
|
1279
|
+
return self.stx_violin(data, colors=colors, track=track, id=id, **kwargs)
|
|
1280
|
+
|
|
906
1281
|
# Standard matplotlib plot methods with plot_ prefix
|
|
907
1282
|
def plot_bar(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
908
1283
|
"""Wrapper for matplotlib bar plot with tracking support."""
|
|
@@ -916,6 +1291,9 @@ class MatplotlibPlotMixin:
|
|
|
916
1291
|
tracked_dict = {"bar_df": pd.DataFrame({"x": args[0], "height": args[1]})}
|
|
917
1292
|
self._track(track, id, method_name, tracked_dict, None)
|
|
918
1293
|
|
|
1294
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1295
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1296
|
+
|
|
919
1297
|
return result
|
|
920
1298
|
|
|
921
1299
|
def plot_barh(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
@@ -930,12 +1308,20 @@ class MatplotlibPlotMixin:
|
|
|
930
1308
|
tracked_dict = {"barh_df": pd.DataFrame({"y": args[0], "width": args[1]})}
|
|
931
1309
|
self._track(track, id, method_name, tracked_dict, None)
|
|
932
1310
|
|
|
1311
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1312
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1313
|
+
|
|
933
1314
|
return result
|
|
934
1315
|
|
|
935
1316
|
def plot_scatter(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
936
1317
|
"""Wrapper for matplotlib scatter plot with tracking support."""
|
|
937
1318
|
method_name = "plot_scatter"
|
|
938
1319
|
|
|
1320
|
+
# Add sample size to label if provided
|
|
1321
|
+
if kwargs.get("label") and len(args) >= 1:
|
|
1322
|
+
n_samples = len(args[0])
|
|
1323
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_samples})"
|
|
1324
|
+
|
|
939
1325
|
with self._no_tracking():
|
|
940
1326
|
result = self._axis_mpl.scatter(*args, **kwargs)
|
|
941
1327
|
|
|
@@ -944,6 +1330,9 @@ class MatplotlibPlotMixin:
|
|
|
944
1330
|
tracked_dict = {"scatter_df": pd.DataFrame({"x": args[0], "y": args[1]})}
|
|
945
1331
|
self._track(track, id, method_name, tracked_dict, None)
|
|
946
1332
|
|
|
1333
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1334
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1335
|
+
|
|
947
1336
|
return result
|
|
948
1337
|
|
|
949
1338
|
def plot_errorbar(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
@@ -963,6 +1352,9 @@ class MatplotlibPlotMixin:
|
|
|
963
1352
|
tracked_dict = {"errorbar_df": pd.DataFrame(df_dict)}
|
|
964
1353
|
self._track(track, id, method_name, tracked_dict, None)
|
|
965
1354
|
|
|
1355
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1356
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1357
|
+
|
|
966
1358
|
return result
|
|
967
1359
|
|
|
968
1360
|
def plot_fill_between(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
@@ -981,6 +1373,9 @@ class MatplotlibPlotMixin:
|
|
|
981
1373
|
})}
|
|
982
1374
|
self._track(track, id, method_name, tracked_dict, None)
|
|
983
1375
|
|
|
1376
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1377
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1378
|
+
|
|
984
1379
|
return result
|
|
985
1380
|
|
|
986
1381
|
def plot_contour(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
@@ -1001,6 +1396,9 @@ class MatplotlibPlotMixin:
|
|
|
1001
1396
|
})}
|
|
1002
1397
|
self._track(track, id, method_name, tracked_dict, None)
|
|
1003
1398
|
|
|
1399
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1400
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1401
|
+
|
|
1004
1402
|
return result
|
|
1005
1403
|
|
|
1006
1404
|
def plot_imshow(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
@@ -1023,12 +1421,28 @@ class MatplotlibPlotMixin:
|
|
|
1023
1421
|
tracked_dict = {"imshow_df": df}
|
|
1024
1422
|
self._track(track, id, method_name, tracked_dict, None)
|
|
1025
1423
|
|
|
1424
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1425
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1426
|
+
|
|
1026
1427
|
return result
|
|
1027
1428
|
|
|
1028
|
-
def plot_boxplot(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1029
|
-
"""Wrapper for matplotlib boxplot with tracking support."""
|
|
1429
|
+
def plot_boxplot(self, *args, colors: Optional[List] = None, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1430
|
+
"""Wrapper for matplotlib boxplot with tracking support and auto-styling."""
|
|
1030
1431
|
method_name = "plot_boxplot"
|
|
1031
1432
|
|
|
1433
|
+
# Add sample size per group to label if provided (show range if variable)
|
|
1434
|
+
if kwargs.get("label") and len(args) >= 1:
|
|
1435
|
+
data = args[0]
|
|
1436
|
+
if isinstance(data, list):
|
|
1437
|
+
n_per_group = [len(g) for g in data]
|
|
1438
|
+
n_min, n_max = min(n_per_group), max(n_per_group)
|
|
1439
|
+
n_str = str(n_min) if n_min == n_max else f"{n_min}-{n_max}"
|
|
1440
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_str})"
|
|
1441
|
+
|
|
1442
|
+
# Enable patch_artist for styling (fill colors, edges)
|
|
1443
|
+
if "patch_artist" not in kwargs:
|
|
1444
|
+
kwargs["patch_artist"] = True
|
|
1445
|
+
|
|
1032
1446
|
with self._no_tracking():
|
|
1033
1447
|
result = self._axis_mpl.boxplot(*args, **kwargs)
|
|
1034
1448
|
|
|
@@ -1041,12 +1455,29 @@ class MatplotlibPlotMixin:
|
|
|
1041
1455
|
tracked_dict = {"boxplot_df": pd.DataFrame({"data": data})}
|
|
1042
1456
|
self._track(track, id, method_name, tracked_dict, None)
|
|
1043
1457
|
|
|
1458
|
+
# Apply style_boxplot automatically for publication quality
|
|
1459
|
+
# Uses scitex palette by default, or custom colors if provided
|
|
1460
|
+
from scitex.plt.ax import style_boxplot
|
|
1461
|
+
style_boxplot(result, colors=colors)
|
|
1462
|
+
|
|
1463
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1464
|
+
self._apply_scitex_postprocess(method_name, result)
|
|
1465
|
+
|
|
1044
1466
|
return result
|
|
1045
1467
|
|
|
1046
1468
|
def plot_violinplot(self, *args, track: bool = True, id: Optional[str] = None, **kwargs):
|
|
1047
1469
|
"""Wrapper for matplotlib violinplot with tracking support."""
|
|
1048
1470
|
method_name = "plot_violinplot"
|
|
1049
1471
|
|
|
1472
|
+
# Add sample size per group to label if provided (show range if variable)
|
|
1473
|
+
if kwargs.get("label") and len(args) >= 1:
|
|
1474
|
+
data = args[0]
|
|
1475
|
+
if isinstance(data, list):
|
|
1476
|
+
n_per_group = [len(g) for g in data]
|
|
1477
|
+
n_min, n_max = min(n_per_group), max(n_per_group)
|
|
1478
|
+
n_str = str(n_min) if n_min == n_max else f"{n_min}-{n_max}"
|
|
1479
|
+
kwargs["label"] = f"{kwargs['label']} ($n$={n_str})"
|
|
1480
|
+
|
|
1050
1481
|
with self._no_tracking():
|
|
1051
1482
|
result = self._axis_mpl.violinplot(*args, **kwargs)
|
|
1052
1483
|
|
|
@@ -1059,6 +1490,10 @@ class MatplotlibPlotMixin:
|
|
|
1059
1490
|
tracked_dict = {"violinplot_df": pd.DataFrame({"data": data})}
|
|
1060
1491
|
self._track(track, id, method_name, tracked_dict, None)
|
|
1061
1492
|
|
|
1493
|
+
# Apply post-processing (tick locator, spines, etc.)
|
|
1494
|
+
self._apply_scitex_postprocess(method_name, result, kwargs, args)
|
|
1495
|
+
|
|
1062
1496
|
return result
|
|
1063
1497
|
|
|
1498
|
+
|
|
1064
1499
|
# EOF
|