scitex 2.0.0__py2.py3-none-any.whl → 2.1.0__py2.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/__init__.py +53 -15
- scitex/__main__.py +72 -26
- scitex/__version__.py +1 -1
- scitex/_sh.py +145 -23
- scitex/ai/__init__.py +30 -16
- scitex/ai/_gen_ai/_Anthropic.py +5 -7
- scitex/ai/_gen_ai/_BaseGenAI.py +2 -2
- scitex/ai/_gen_ai/_DeepSeek.py +10 -2
- scitex/ai/_gen_ai/_Google.py +2 -2
- scitex/ai/_gen_ai/_Llama.py +2 -2
- scitex/ai/_gen_ai/_OpenAI.py +2 -2
- scitex/ai/_gen_ai/_PARAMS.py +51 -65
- scitex/ai/_gen_ai/_Perplexity.py +2 -2
- scitex/ai/_gen_ai/__init__.py +25 -14
- scitex/ai/_gen_ai/_format_output_func.py +4 -4
- scitex/ai/classification/{classifier_server.py → Classifier.py} +5 -5
- scitex/ai/classification/CrossValidationExperiment.py +374 -0
- scitex/ai/classification/__init__.py +43 -4
- scitex/ai/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ai/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ai/classification/reporters/__init__.py +11 -0
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ai/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ai/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ai/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ai/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ai/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ai/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ai/classification/timeseries/__init__.py +39 -0
- scitex/ai/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ai/clustering/_umap.py +2 -2
- scitex/ai/feature_extraction/vit.py +1 -0
- scitex/ai/feature_selection/__init__.py +30 -0
- scitex/ai/feature_selection/feature_selection.py +364 -0
- scitex/ai/loss/multi_task_loss.py +1 -1
- scitex/ai/metrics/__init__.py +51 -4
- scitex/ai/metrics/_calc_bacc.py +61 -0
- scitex/ai/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ai/metrics/_calc_clf_report.py +78 -0
- scitex/ai/metrics/_calc_conf_mat.py +93 -0
- scitex/ai/metrics/_calc_feature_importance.py +183 -0
- scitex/ai/metrics/_calc_mcc.py +61 -0
- scitex/ai/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ai/metrics/_calc_roc_auc.py +110 -0
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ai/metrics/{silhoute_score_block.py → _calc_silhouette_score.py} +15 -8
- scitex/ai/metrics/_normalize_labels.py +83 -0
- scitex/ai/plt/__init__.py +47 -8
- scitex/ai/plt/{_conf_mat.py → _plot_conf_mat.py} +158 -87
- scitex/ai/plt/_plot_feature_importance.py +323 -0
- scitex/ai/plt/_plot_learning_curve.py +345 -0
- scitex/ai/plt/_plot_optuna_study.py +225 -0
- scitex/ai/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ai/plt/_plot_roc_curve.py +255 -0
- scitex/ai/training/{learning_curve_logger.py → _LearningCurveLogger.py} +197 -213
- scitex/ai/training/__init__.py +2 -2
- scitex/ai/utils/grid_search.py +3 -3
- scitex/benchmark/__init__.py +52 -0
- scitex/benchmark/benchmark.py +400 -0
- scitex/benchmark/monitor.py +370 -0
- scitex/benchmark/profiler.py +297 -0
- scitex/browser/__init__.py +48 -0
- scitex/browser/automation/CookieHandler.py +216 -0
- scitex/browser/automation/__init__.py +7 -0
- scitex/browser/collaboration/__init__.py +55 -0
- scitex/browser/collaboration/auth_helpers.py +94 -0
- scitex/browser/collaboration/collaborative_agent.py +136 -0
- scitex/browser/collaboration/credential_manager.py +188 -0
- scitex/browser/collaboration/interactive_panel.py +400 -0
- scitex/browser/collaboration/persistent_browser.py +170 -0
- scitex/browser/collaboration/shared_session.py +383 -0
- scitex/browser/collaboration/standard_interactions.py +246 -0
- scitex/browser/collaboration/visual_feedback.py +181 -0
- scitex/browser/core/BrowserMixin.py +326 -0
- scitex/browser/core/ChromeProfileManager.py +446 -0
- scitex/browser/core/__init__.py +9 -0
- scitex/browser/debugging/__init__.py +18 -0
- scitex/browser/debugging/_browser_logger.py +657 -0
- scitex/browser/debugging/_highlight_element.py +143 -0
- scitex/browser/debugging/_show_grid.py +154 -0
- scitex/browser/interaction/__init__.py +24 -0
- scitex/browser/interaction/click_center.py +149 -0
- scitex/browser/interaction/click_with_fallbacks.py +206 -0
- scitex/browser/interaction/close_popups.py +498 -0
- scitex/browser/interaction/fill_with_fallbacks.py +209 -0
- scitex/browser/pdf/__init__.py +14 -0
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +200 -0
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +198 -0
- scitex/browser/remote/CaptchaHandler.py +434 -0
- scitex/browser/remote/ZenRowsAPIClient.py +347 -0
- scitex/browser/remote/ZenRowsBrowserManager.py +570 -0
- scitex/browser/remote/__init__.py +11 -0
- scitex/browser/stealth/HumanBehavior.py +344 -0
- scitex/browser/stealth/StealthManager.py +1008 -0
- scitex/browser/stealth/__init__.py +9 -0
- scitex/browser/template.py +122 -0
- scitex/capture/__init__.py +110 -0
- scitex/capture/__main__.py +25 -0
- scitex/capture/capture.py +848 -0
- scitex/capture/cli.py +233 -0
- scitex/capture/gif.py +344 -0
- scitex/capture/mcp_server.py +961 -0
- scitex/capture/session.py +70 -0
- scitex/capture/utils.py +705 -0
- scitex/cli/__init__.py +17 -0
- scitex/cli/cloud.py +447 -0
- scitex/cli/main.py +42 -0
- scitex/cli/scholar.py +280 -0
- scitex/context/_suppress_output.py +5 -3
- scitex/db/__init__.py +30 -3
- scitex/db/__main__.py +75 -0
- scitex/db/_check_health.py +381 -0
- scitex/db/_delete_duplicates.py +25 -386
- scitex/db/_inspect.py +335 -114
- scitex/db/_inspect_optimized.py +301 -0
- scitex/db/{_PostgreSQL.py → _postgresql/_PostgreSQL.py} +3 -3
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BackupMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BatchMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BlobMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ConnectionMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_MaintenanceMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_QueryMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_SchemaMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TransactionMixin.py +1 -1
- scitex/db/_postgresql/__init__.py +6 -0
- scitex/db/_sqlite3/_SQLite3.py +210 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +581 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +517 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_BatchMixin.py +1 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +281 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +548 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ConnectionMixin.py +29 -13
- scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ImportExportMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_IndexMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_MaintenanceMixin.py +2 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_QueryMixin.py +37 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_RowMixin.py +46 -6
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TableMixin.py +56 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TransactionMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/__init__.py +14 -2
- scitex/db/_sqlite3/__init__.py +7 -0
- scitex/db/_sqlite3/_delete_duplicates.py +274 -0
- scitex/decorators/__init__.py +2 -0
- scitex/decorators/_cache_disk.py +13 -5
- scitex/decorators/_cache_disk_async.py +49 -0
- scitex/decorators/_deprecated.py +175 -10
- scitex/decorators/_timeout.py +1 -1
- scitex/dev/_analyze_code_flow.py +2 -2
- scitex/dict/_DotDict.py +73 -15
- scitex/dict/_DotDict_v01-not-handling-recursive-instantiations.py +442 -0
- scitex/dict/_DotDict_v02-not-serializing-Path-object.py +446 -0
- scitex/dict/__init__.py +2 -0
- scitex/dict/_flatten.py +27 -0
- scitex/dsp/_crop.py +2 -2
- scitex/dsp/_demo_sig.py +2 -2
- scitex/dsp/_detect_ripples.py +2 -2
- scitex/dsp/_hilbert.py +2 -2
- scitex/dsp/_listen.py +6 -6
- scitex/dsp/_modulation_index.py +2 -2
- scitex/dsp/_pac.py +1 -1
- scitex/dsp/_psd.py +2 -2
- scitex/dsp/_resample.py +2 -1
- scitex/dsp/_time.py +3 -2
- scitex/dsp/_wavelet.py +3 -2
- scitex/dsp/add_noise.py +2 -2
- scitex/dsp/example.py +1 -0
- scitex/dsp/filt.py +10 -9
- scitex/dsp/template.py +3 -2
- scitex/dsp/utils/_differential_bandpass_filters.py +1 -1
- scitex/dsp/utils/pac.py +2 -2
- scitex/dt/_normalize_timestamp.py +432 -0
- scitex/errors.py +572 -0
- scitex/gen/_DimHandler.py +2 -2
- scitex/gen/__init__.py +37 -7
- scitex/gen/_deprecated_close.py +80 -0
- scitex/gen/_deprecated_start.py +26 -0
- scitex/gen/_detect_environment.py +152 -0
- scitex/gen/_detect_notebook_path.py +169 -0
- scitex/gen/_embed.py +6 -2
- scitex/gen/_get_notebook_path.py +257 -0
- scitex/gen/_less.py +1 -1
- scitex/gen/_list_packages.py +2 -2
- scitex/gen/_norm.py +44 -9
- scitex/gen/_norm_cache.py +269 -0
- scitex/gen/_src.py +3 -5
- scitex/gen/_title_case.py +3 -3
- scitex/io/__init__.py +28 -6
- scitex/io/_glob.py +13 -7
- scitex/io/_load.py +108 -21
- scitex/io/_load_cache.py +303 -0
- scitex/io/_load_configs.py +40 -15
- scitex/io/{_H5Explorer.py → _load_modules/_H5Explorer.py} +80 -17
- scitex/io/_load_modules/_ZarrExplorer.py +114 -0
- scitex/io/_load_modules/_bibtex.py +207 -0
- scitex/io/_load_modules/_hdf5.py +53 -178
- scitex/io/_load_modules/_json.py +5 -3
- scitex/io/_load_modules/_pdf.py +871 -16
- scitex/io/_load_modules/_sqlite3.py +15 -0
- scitex/io/_load_modules/_txt.py +41 -12
- scitex/io/_load_modules/_yaml.py +4 -3
- scitex/io/_load_modules/_zarr.py +126 -0
- scitex/io/_save.py +429 -171
- scitex/io/_save_modules/__init__.py +6 -0
- scitex/io/_save_modules/_bibtex.py +194 -0
- scitex/io/_save_modules/_csv.py +8 -4
- scitex/io/_save_modules/_excel.py +174 -15
- scitex/io/_save_modules/_hdf5.py +251 -226
- scitex/io/_save_modules/_image.py +1 -3
- scitex/io/_save_modules/_json.py +49 -4
- scitex/io/_save_modules/_listed_dfs_as_csv.py +1 -3
- scitex/io/_save_modules/_listed_scalars_as_csv.py +1 -3
- scitex/io/_save_modules/_tex.py +277 -0
- scitex/io/_save_modules/_yaml.py +42 -3
- scitex/io/_save_modules/_zarr.py +160 -0
- scitex/io/utils/__init__.py +20 -0
- scitex/io/utils/h5_to_zarr.py +616 -0
- scitex/linalg/_geometric_median.py +6 -2
- scitex/{gen/_tee.py → logging/_Tee.py} +43 -84
- scitex/logging/__init__.py +122 -0
- scitex/logging/_config.py +158 -0
- scitex/logging/_context.py +103 -0
- scitex/logging/_formatters.py +128 -0
- scitex/logging/_handlers.py +64 -0
- scitex/logging/_levels.py +35 -0
- scitex/logging/_logger.py +163 -0
- scitex/logging/_print_capture.py +95 -0
- scitex/ml/__init__.py +69 -0
- scitex/{ai/genai/anthropic.py → ml/_gen_ai/_Anthropic.py} +13 -19
- scitex/{ai/genai/base_genai.py → ml/_gen_ai/_BaseGenAI.py} +5 -5
- scitex/{ai/genai/deepseek.py → ml/_gen_ai/_DeepSeek.py} +11 -16
- scitex/{ai/genai/google.py → ml/_gen_ai/_Google.py} +7 -15
- scitex/{ai/genai/groq.py → ml/_gen_ai/_Groq.py} +1 -8
- scitex/{ai/genai/llama.py → ml/_gen_ai/_Llama.py} +3 -16
- scitex/{ai/genai/openai.py → ml/_gen_ai/_OpenAI.py} +3 -3
- scitex/{ai/genai/params.py → ml/_gen_ai/_PARAMS.py} +51 -65
- scitex/{ai/genai/perplexity.py → ml/_gen_ai/_Perplexity.py} +3 -14
- scitex/ml/_gen_ai/__init__.py +43 -0
- scitex/{ai/genai/calc_cost.py → ml/_gen_ai/_calc_cost.py} +1 -1
- scitex/{ai/genai/format_output_func.py → ml/_gen_ai/_format_output_func.py} +4 -4
- scitex/{ai/genai/genai_factory.py → ml/_gen_ai/_genai_factory.py} +8 -8
- scitex/ml/activation/__init__.py +8 -0
- scitex/ml/activation/_define.py +11 -0
- scitex/{ai/classifier_server.py → ml/classification/Classifier.py} +5 -5
- scitex/ml/classification/CrossValidationExperiment.py +374 -0
- scitex/ml/classification/__init__.py +46 -0
- scitex/ml/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ml/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ml/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ml/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ml/classification/reporters/__init__.py +11 -0
- scitex/ml/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ml/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ml/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ml/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ml/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ml/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ml/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ml/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ml/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ml/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ml/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ml/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ml/classification/timeseries/__init__.py +39 -0
- scitex/ml/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ml/clustering/__init__.py +11 -0
- scitex/ml/clustering/_pca.py +115 -0
- scitex/ml/clustering/_umap.py +376 -0
- scitex/ml/feature_extraction/__init__.py +56 -0
- scitex/ml/feature_extraction/vit.py +149 -0
- scitex/ml/feature_selection/__init__.py +30 -0
- scitex/ml/feature_selection/feature_selection.py +364 -0
- scitex/ml/loss/_L1L2Losses.py +34 -0
- scitex/ml/loss/__init__.py +12 -0
- scitex/ml/loss/multi_task_loss.py +47 -0
- scitex/ml/metrics/__init__.py +56 -0
- scitex/ml/metrics/_calc_bacc.py +61 -0
- scitex/ml/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ml/metrics/_calc_clf_report.py +78 -0
- scitex/ml/metrics/_calc_conf_mat.py +93 -0
- scitex/ml/metrics/_calc_feature_importance.py +183 -0
- scitex/ml/metrics/_calc_mcc.py +61 -0
- scitex/ml/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ml/metrics/_calc_roc_auc.py +110 -0
- scitex/ml/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ml/metrics/_calc_silhouette_score.py +503 -0
- scitex/ml/metrics/_normalize_labels.py +83 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ml/optim/__init__.py +13 -0
- scitex/ml/optim/_get_set.py +31 -0
- scitex/ml/optim/_optimizers.py +71 -0
- scitex/ml/plt/__init__.py +60 -0
- scitex/ml/plt/_plot_conf_mat.py +663 -0
- scitex/ml/plt/_plot_feature_importance.py +323 -0
- scitex/ml/plt/_plot_learning_curve.py +345 -0
- scitex/ml/plt/_plot_optuna_study.py +225 -0
- scitex/ml/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ml/plt/_plot_roc_curve.py +255 -0
- scitex/ml/sk/__init__.py +11 -0
- scitex/ml/sk/_clf.py +58 -0
- scitex/ml/sk/_to_sktime.py +100 -0
- scitex/ml/sklearn/__init__.py +26 -0
- scitex/ml/sklearn/clf.py +58 -0
- scitex/ml/sklearn/to_sktime.py +100 -0
- scitex/{ai/training/early_stopping.py → ml/training/_EarlyStopping.py} +1 -2
- scitex/{ai → ml/training}/_LearningCurveLogger.py +198 -242
- scitex/ml/training/__init__.py +7 -0
- scitex/ml/utils/__init__.py +22 -0
- scitex/ml/utils/_check_params.py +50 -0
- scitex/ml/utils/_default_dataset.py +46 -0
- scitex/ml/utils/_format_samples_for_sktime.py +26 -0
- scitex/ml/utils/_label_encoder.py +134 -0
- scitex/ml/utils/_merge_labels.py +22 -0
- scitex/ml/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ml/utils/_under_sample.py +51 -0
- scitex/ml/utils/_verify_n_gpus.py +16 -0
- scitex/ml/utils/grid_search.py +148 -0
- scitex/nn/_BNet.py +15 -9
- scitex/nn/_Filters.py +2 -2
- scitex/nn/_ModulationIndex.py +2 -2
- scitex/nn/_PAC.py +1 -1
- scitex/nn/_Spectrogram.py +12 -3
- scitex/nn/__init__.py +9 -10
- scitex/path/__init__.py +18 -0
- scitex/path/_clean.py +4 -0
- scitex/path/_find.py +9 -4
- scitex/path/_symlink.py +348 -0
- scitex/path/_version.py +4 -3
- scitex/pd/__init__.py +2 -0
- scitex/pd/_get_unique.py +99 -0
- scitex/plt/__init__.py +114 -5
- scitex/plt/_subplots/_AxesWrapper.py +1 -3
- scitex/plt/_subplots/_AxisWrapper.py +7 -3
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +47 -13
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +160 -2
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +26 -4
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +322 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +1 -0
- scitex/plt/_subplots/_FigWrapper.py +62 -6
- scitex/plt/_subplots/_export_as_csv.py +43 -27
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +5 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +81 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +20 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +35 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +15 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +35 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +60 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters.py +56 -59
- scitex/plt/ax/_style/_hide_spines.py +1 -3
- scitex/plt/ax/_style/_rotate_labels.py +180 -76
- scitex/plt/ax/_style/_rotate_labels_v01.py +248 -0
- scitex/plt/ax/_style/_set_meta.py +11 -4
- scitex/plt/ax/_style/_set_supxyt.py +3 -3
- scitex/plt/ax/_style/_set_xyt.py +3 -3
- scitex/plt/ax/_style/_share_axes.py +2 -2
- scitex/plt/color/__init__.py +4 -4
- scitex/plt/color/{_get_colors_from_cmap.py → _get_colors_from_conf_matap.py} +7 -7
- scitex/plt/utils/_configure_mpl.py +99 -86
- scitex/plt/utils/_histogram_utils.py +1 -3
- scitex/plt/utils/_is_valid_axis.py +1 -3
- scitex/plt/utils/_scitex_config.py +1 -0
- scitex/repro/__init__.py +75 -0
- scitex/{reproduce → repro}/_gen_ID.py +1 -1
- scitex/{reproduce → repro}/_gen_timestamp.py +1 -1
- scitex/repro_rng/_RandomStateManager.py +590 -0
- scitex/repro_rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/repro_rng/__init__.py +39 -0
- scitex/reproduce/__init__.py +25 -13
- scitex/reproduce/_hash_array.py +22 -0
- scitex/resource/_get_processor_usages.py +4 -4
- scitex/resource/_get_specs.py +2 -2
- scitex/resource/_log_processor_usages.py +2 -2
- scitex/rng/_RandomStateManager.py +590 -0
- scitex/rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/rng/__init__.py +39 -0
- scitex/scholar/__init__.py +309 -19
- scitex/scholar/__main__.py +319 -0
- scitex/scholar/auth/ScholarAuthManager.py +308 -0
- scitex/scholar/auth/__init__.py +12 -0
- scitex/scholar/auth/core/AuthenticationGateway.py +473 -0
- scitex/scholar/auth/core/BrowserAuthenticator.py +386 -0
- scitex/scholar/auth/core/StrategyResolver.py +309 -0
- scitex/scholar/auth/core/__init__.py +16 -0
- scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +120 -0
- scitex/scholar/auth/gateway/_OpenURLResolver.py +209 -0
- scitex/scholar/auth/gateway/__init__.py +38 -0
- scitex/scholar/auth/gateway/_resolve_functions.py +101 -0
- scitex/scholar/auth/providers/BaseAuthenticator.py +166 -0
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +484 -0
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +619 -0
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +686 -0
- scitex/scholar/auth/providers/__init__.py +18 -0
- scitex/scholar/auth/session/AuthCacheManager.py +189 -0
- scitex/scholar/auth/session/SessionManager.py +159 -0
- scitex/scholar/auth/session/__init__.py +11 -0
- scitex/scholar/auth/sso/BaseSSOAutomator.py +373 -0
- scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +378 -0
- scitex/scholar/auth/sso/SSOAutomator.py +180 -0
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +380 -0
- scitex/scholar/auth/sso/__init__.py +15 -0
- scitex/scholar/browser/ScholarBrowserManager.py +705 -0
- scitex/scholar/browser/__init__.py +38 -0
- scitex/scholar/browser/utils/__init__.py +13 -0
- scitex/scholar/browser/utils/click_and_wait.py +205 -0
- scitex/scholar/browser/utils/close_unwanted_pages.py +140 -0
- scitex/scholar/browser/utils/wait_redirects.py +732 -0
- scitex/scholar/config/PublisherRules.py +132 -0
- scitex/scholar/config/ScholarConfig.py +126 -0
- scitex/scholar/config/__init__.py +17 -0
- scitex/scholar/core/Paper.py +627 -0
- scitex/scholar/core/Papers.py +722 -0
- scitex/scholar/core/Scholar.py +1975 -0
- scitex/scholar/core/__init__.py +9 -0
- scitex/scholar/impact_factor/ImpactFactorEngine.py +204 -0
- scitex/scholar/impact_factor/__init__.py +20 -0
- scitex/scholar/impact_factor/estimation/ImpactFactorEstimationEngine.py +0 -0
- scitex/scholar/impact_factor/estimation/__init__.py +40 -0
- scitex/scholar/impact_factor/estimation/build_database.py +0 -0
- scitex/scholar/impact_factor/estimation/core/__init__.py +28 -0
- scitex/scholar/impact_factor/estimation/core/cache_manager.py +523 -0
- scitex/scholar/impact_factor/estimation/core/calculator.py +355 -0
- scitex/scholar/impact_factor/estimation/core/journal_matcher.py +428 -0
- scitex/scholar/integration/__init__.py +59 -0
- scitex/scholar/integration/base.py +502 -0
- scitex/scholar/integration/mendeley/__init__.py +22 -0
- scitex/scholar/integration/mendeley/exporter.py +166 -0
- scitex/scholar/integration/mendeley/importer.py +236 -0
- scitex/scholar/integration/mendeley/linker.py +79 -0
- scitex/scholar/integration/mendeley/mapper.py +212 -0
- scitex/scholar/integration/zotero/__init__.py +27 -0
- scitex/scholar/integration/zotero/__main__.py +264 -0
- scitex/scholar/integration/zotero/exporter.py +351 -0
- scitex/scholar/integration/zotero/importer.py +372 -0
- scitex/scholar/integration/zotero/linker.py +415 -0
- scitex/scholar/integration/zotero/mapper.py +286 -0
- scitex/scholar/metadata_engines/ScholarEngine.py +588 -0
- scitex/scholar/metadata_engines/__init__.py +21 -0
- scitex/scholar/metadata_engines/individual/ArXivEngine.py +397 -0
- scitex/scholar/metadata_engines/individual/CrossRefEngine.py +274 -0
- scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +263 -0
- scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +350 -0
- scitex/scholar/metadata_engines/individual/PubMedEngine.py +329 -0
- scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +438 -0
- scitex/scholar/metadata_engines/individual/URLDOIEngine.py +410 -0
- scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +487 -0
- scitex/scholar/metadata_engines/individual/__init__.py +7 -0
- scitex/scholar/metadata_engines/utils/_PubMedConverter.py +469 -0
- scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +283 -0
- scitex/scholar/metadata_engines/utils/__init__.py +30 -0
- scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +103 -0
- scitex/scholar/metadata_engines/utils/_standardize_metadata.py +376 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +579 -0
- scitex/scholar/pdf_download/__init__.py +5 -0
- scitex/scholar/pdf_download/strategies/__init__.py +38 -0
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +376 -0
- scitex/scholar/pdf_download/strategies/direct_download.py +131 -0
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +167 -0
- scitex/scholar/pdf_download/strategies/manual_download_utils.py +996 -0
- scitex/scholar/pdf_download/strategies/response_body.py +207 -0
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +364 -0
- scitex/scholar/pipelines/ScholarPipelineParallel.py +478 -0
- scitex/scholar/pipelines/ScholarPipelineSingle.py +767 -0
- scitex/scholar/pipelines/__init__.py +49 -0
- scitex/scholar/storage/BibTeXHandler.py +1018 -0
- scitex/scholar/storage/PaperIO.py +468 -0
- scitex/scholar/storage/ScholarLibrary.py +182 -0
- scitex/scholar/storage/_DeduplicationManager.py +548 -0
- scitex/scholar/storage/_LibraryCacheManager.py +724 -0
- scitex/scholar/storage/_LibraryManager.py +1835 -0
- scitex/scholar/storage/__init__.py +28 -0
- scitex/scholar/url_finder/ScholarURLFinder.py +379 -0
- scitex/scholar/url_finder/__init__.py +7 -0
- scitex/scholar/url_finder/strategies/__init__.py +33 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +261 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_dropdown.py +67 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +204 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +256 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +165 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +163 -0
- scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +70 -0
- scitex/scholar/utils/__init__.py +22 -0
- scitex/scholar/utils/bibtex/__init__.py +9 -0
- scitex/scholar/utils/bibtex/_parse_bibtex.py +71 -0
- scitex/scholar/utils/cleanup/__init__.py +8 -0
- scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +96 -0
- scitex/scholar/utils/cleanup/cleanup_old_extractions.py +117 -0
- scitex/scholar/utils/text/_TextNormalizer.py +407 -0
- scitex/scholar/utils/text/__init__.py +9 -0
- scitex/scholar/zotero/__init__.py +38 -0
- scitex/session/__init__.py +51 -0
- scitex/session/_lifecycle.py +736 -0
- scitex/session/_manager.py +102 -0
- scitex/session/template.py +122 -0
- scitex/stats/__init__.py +30 -26
- scitex/stats/correct/__init__.py +21 -0
- scitex/stats/correct/_correct_bonferroni.py +551 -0
- scitex/stats/correct/_correct_fdr.py +634 -0
- scitex/stats/correct/_correct_holm.py +548 -0
- scitex/stats/correct/_correct_sidak.py +499 -0
- scitex/stats/descriptive/__init__.py +85 -0
- scitex/stats/descriptive/_circular.py +540 -0
- scitex/stats/descriptive/_describe.py +219 -0
- scitex/stats/descriptive/_nan.py +518 -0
- scitex/stats/descriptive/_real.py +189 -0
- scitex/stats/effect_sizes/__init__.py +41 -0
- scitex/stats/effect_sizes/_cliffs_delta.py +325 -0
- scitex/stats/effect_sizes/_cohens_d.py +342 -0
- scitex/stats/effect_sizes/_epsilon_squared.py +315 -0
- scitex/stats/effect_sizes/_eta_squared.py +302 -0
- scitex/stats/effect_sizes/_prob_superiority.py +296 -0
- scitex/stats/posthoc/__init__.py +19 -0
- scitex/stats/posthoc/_dunnett.py +463 -0
- scitex/stats/posthoc/_games_howell.py +383 -0
- scitex/stats/posthoc/_tukey_hsd.py +367 -0
- scitex/stats/power/__init__.py +19 -0
- scitex/stats/power/_power.py +433 -0
- scitex/stats/template.py +119 -0
- scitex/stats/utils/__init__.py +62 -0
- scitex/stats/utils/_effect_size.py +985 -0
- scitex/stats/utils/_formatters.py +270 -0
- scitex/stats/utils/_normalizers.py +927 -0
- scitex/stats/utils/_power.py +433 -0
- scitex/stats_v01/_EffectSizeCalculator.py +488 -0
- scitex/stats_v01/_StatisticalValidator.py +411 -0
- scitex/stats_v01/__init__.py +60 -0
- scitex/stats_v01/_additional_tests.py +415 -0
- scitex/{stats → stats_v01}/_p2stars.py +19 -5
- scitex/stats_v01/_two_sample_tests.py +141 -0
- scitex/stats_v01/desc/__init__.py +83 -0
- scitex/stats_v01/desc/_circular.py +540 -0
- scitex/stats_v01/desc/_describe.py +219 -0
- scitex/stats_v01/desc/_nan.py +518 -0
- scitex/{stats/desc/_nan.py → stats_v01/desc/_nan_v01-20250920_145731.py} +23 -12
- scitex/stats_v01/desc/_real.py +189 -0
- scitex/stats_v01/tests/__corr_test_optimized.py +221 -0
- scitex/stats_v01/tests/_corr_test_optimized.py +179 -0
- scitex/str/__init__.py +1 -3
- scitex/str/_clean_path.py +6 -2
- scitex/str/_latex_fallback.py +267 -160
- scitex/str/_parse.py +44 -36
- scitex/str/_printc.py +1 -3
- scitex/template/__init__.py +87 -0
- scitex/template/_create_project.py +267 -0
- scitex/template/create_pip_project.py +80 -0
- scitex/template/create_research.py +80 -0
- scitex/template/create_singularity.py +80 -0
- scitex/units.py +291 -0
- scitex/utils/_compress_hdf5.py +14 -3
- scitex/utils/_email.py +21 -2
- scitex/utils/_grid.py +6 -4
- scitex/utils/_notify.py +13 -10
- scitex/utils/_verify_scitex_format.py +589 -0
- scitex/utils/_verify_scitex_format_v01.py +370 -0
- scitex/utils/template.py +122 -0
- scitex/web/_search_pubmed.py +62 -16
- scitex-2.1.0.dist-info/LICENSE +21 -0
- scitex-2.1.0.dist-info/METADATA +677 -0
- scitex-2.1.0.dist-info/RECORD +919 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/WHEEL +1 -1
- scitex-2.1.0.dist-info/entry_points.txt +3 -0
- scitex/ai/__Classifiers.py +0 -101
- scitex/ai/classification/classification_reporter.py +0 -1137
- scitex/ai/classification/classifiers.py +0 -101
- scitex/ai/classification_reporter.py +0 -1161
- scitex/ai/genai/__init__.py +0 -277
- scitex/ai/genai/anthropic_provider.py +0 -320
- scitex/ai/genai/anthropic_refactored.py +0 -109
- scitex/ai/genai/auth_manager.py +0 -200
- scitex/ai/genai/base_provider.py +0 -291
- scitex/ai/genai/chat_history.py +0 -307
- scitex/ai/genai/cost_tracker.py +0 -276
- scitex/ai/genai/deepseek_provider.py +0 -251
- scitex/ai/genai/google_provider.py +0 -228
- scitex/ai/genai/groq_provider.py +0 -248
- scitex/ai/genai/image_processor.py +0 -250
- scitex/ai/genai/llama_provider.py +0 -214
- scitex/ai/genai/mock_provider.py +0 -127
- scitex/ai/genai/model_registry.py +0 -304
- scitex/ai/genai/openai_provider.py +0 -293
- scitex/ai/genai/perplexity_provider.py +0 -205
- scitex/ai/genai/provider_base.py +0 -302
- scitex/ai/genai/provider_factory.py +0 -370
- scitex/ai/genai/response_handler.py +0 -235
- scitex/ai/layer/_Pass.py +0 -21
- scitex/ai/layer/__init__.py +0 -10
- scitex/ai/layer/_switch.py +0 -8
- scitex/ai/metrics/_bACC.py +0 -51
- scitex/ai/plt/_learning_curve.py +0 -194
- scitex/ai/plt/_optuna_study.py +0 -111
- scitex/ai/plt/aucs/__init__.py +0 -2
- scitex/ai/plt/aucs/example.py +0 -60
- scitex/ai/plt/aucs/pre_rec_auc.py +0 -223
- scitex/ai/plt/aucs/roc_auc.py +0 -246
- scitex/ai/sampling/undersample.py +0 -29
- scitex/db/_SQLite3.py +0 -2136
- scitex/db/_SQLite3Mixins/_BlobMixin.py +0 -229
- scitex/gen/_close.py +0 -222
- scitex/gen/_start.py +0 -451
- scitex/general/__init__.py +0 -5
- scitex/io/_load_modules/_db.py +0 -24
- scitex/life/__init__.py +0 -10
- scitex/life/_monitor_rain.py +0 -49
- scitex/reproduce/_fix_seeds.py +0 -45
- scitex/res/__init__.py +0 -5
- scitex/scholar/_local_search.py +0 -454
- scitex/scholar/_paper.py +0 -244
- scitex/scholar/_pdf_downloader.py +0 -325
- scitex/scholar/_search.py +0 -393
- scitex/scholar/_vector_search.py +0 -370
- scitex/scholar/_web_sources.py +0 -457
- scitex/stats/desc/__init__.py +0 -40
- scitex-2.0.0.dist-info/METADATA +0 -307
- scitex-2.0.0.dist-info/RECORD +0 -572
- scitex-2.0.0.dist-info/licenses/LICENSE +0 -7
- /scitex/ai/{act → activation}/__init__.py +0 -0
- /scitex/ai/{act → activation}/_define.py +0 -0
- /scitex/ai/{early_stopping.py → training/_EarlyStopping.py} +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ImportExportMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_IndexMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_RowMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TableMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/__init__.py +0 -0
- /scitex/{stats → stats_v01}/_calc_partial_corr.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_describe_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_multiple_corrections.py +0 -0
- /scitex/{stats → stats_v01}/_nan_stats.py +0 -0
- /scitex/{stats → stats_v01}/_p2stars_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_statistical_tests.py +0 -0
- /scitex/{stats/desc/_describe.py → stats_v01/desc/_describe_v01-20250920_145731.py} +0 -0
- /scitex/{stats/desc/_real.py → stats_v01/desc/_real_v01-20250920_145731.py} +0 -0
- /scitex/{stats → stats_v01}/multiple/__init__.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_bonferroni_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_fdr_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_multicompair.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_single.py +0 -0
- /scitex/{stats → stats_v01}/tests/__init__.py +0 -0
- /scitex/{stats → stats_v01}/tests/_brunner_munzel_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_nocorrelation_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_smirnov_grubbs.py +0 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-09-24 13:22:52 (ywatanabe)"
|
|
4
|
+
# File: /ssh:sp:/home/ywatanabe/proj/scitex_repo/src/scitex/plt/ax/_style/_rotate_labels.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
+
# ----------------------------------------
|
|
11
|
+
|
|
3
12
|
# Time-stamp: "2024-10-27 13:24:32 (ywatanabe)"
|
|
4
13
|
# /home/ywatanabe/proj/_scitex_repo_openhands/src/scitex/plt/ax/_rotate_labels.py
|
|
5
14
|
|
|
@@ -9,8 +18,18 @@
|
|
|
9
18
|
import numpy as np
|
|
10
19
|
|
|
11
20
|
|
|
12
|
-
def rotate_labels(
|
|
13
|
-
|
|
21
|
+
def rotate_labels(
|
|
22
|
+
ax,
|
|
23
|
+
x=None,
|
|
24
|
+
y=None,
|
|
25
|
+
x_ha=None,
|
|
26
|
+
y_ha=None,
|
|
27
|
+
x_va=None,
|
|
28
|
+
y_va=None,
|
|
29
|
+
auto_adjust=True,
|
|
30
|
+
scientific_convention=True,
|
|
31
|
+
tight_layout=False,
|
|
32
|
+
):
|
|
14
33
|
"""
|
|
15
34
|
Rotate x and y axis labels of a matplotlib Axes object with automatic positioning.
|
|
16
35
|
|
|
@@ -18,10 +37,12 @@ def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
|
18
37
|
----------
|
|
19
38
|
ax : matplotlib.axes.Axes
|
|
20
39
|
The Axes object to modify.
|
|
21
|
-
x : float, optional
|
|
22
|
-
Rotation angle for x-axis labels in degrees. Default is
|
|
23
|
-
|
|
24
|
-
|
|
40
|
+
x : float or None, optional
|
|
41
|
+
Rotation angle for x-axis labels in degrees. Default is None.
|
|
42
|
+
If 0 or None, x-axis labels are not rotated.
|
|
43
|
+
y : float or None, optional
|
|
44
|
+
Rotation angle for y-axis labels in degrees. Default is None.
|
|
45
|
+
If 0 or None, y-axis labels are not rotated.
|
|
25
46
|
x_ha : str, optional
|
|
26
47
|
Horizontal alignment for x-axis labels. If None, automatically determined.
|
|
27
48
|
y_ha : str, optional
|
|
@@ -34,6 +55,8 @@ def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
|
34
55
|
Whether to automatically adjust alignment based on rotation angle. Default is True.
|
|
35
56
|
scientific_convention : bool, optional
|
|
36
57
|
Whether to follow scientific plotting conventions. Default is True.
|
|
58
|
+
tight_layout : bool, optional
|
|
59
|
+
Whether to apply tight_layout to prevent overlapping. Default is False.
|
|
37
60
|
|
|
38
61
|
Returns
|
|
39
62
|
-------
|
|
@@ -46,7 +69,7 @@ def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
|
46
69
|
ax.plot([1, 2, 3], [1, 2, 3])
|
|
47
70
|
rotate_labels(ax)
|
|
48
71
|
plt.show()
|
|
49
|
-
|
|
72
|
+
|
|
50
73
|
Notes
|
|
51
74
|
-----
|
|
52
75
|
Scientific conventions for label rotation:
|
|
@@ -54,6 +77,10 @@ def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
|
54
77
|
- Y-axis labels: For angles 0-90°, use 'center' alignment; adjust vertical as needed
|
|
55
78
|
- Optimal readability maintained through automatic positioning
|
|
56
79
|
"""
|
|
80
|
+
# Determine which axes to rotate (skip if None or 0)
|
|
81
|
+
rotate_x = x is not None and x != 0
|
|
82
|
+
rotate_y = y is not None and y != 0
|
|
83
|
+
|
|
57
84
|
# Get current tick positions
|
|
58
85
|
xticks = ax.get_xticks()
|
|
59
86
|
yticks = ax.get_yticks()
|
|
@@ -64,34 +91,65 @@ def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
|
64
91
|
|
|
65
92
|
# Auto-adjust alignment based on rotation angle and scientific conventions
|
|
66
93
|
if auto_adjust:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
94
|
+
if rotate_x:
|
|
95
|
+
x_ha, x_va = _get_optimal_alignment(
|
|
96
|
+
"x", x, x_ha, x_va, scientific_convention
|
|
97
|
+
)
|
|
98
|
+
if rotate_y:
|
|
99
|
+
y_ha, y_va = _get_optimal_alignment(
|
|
100
|
+
"y", y, y_ha, y_va, scientific_convention
|
|
101
|
+
)
|
|
102
|
+
|
|
70
103
|
# Apply defaults if not auto-adjusting
|
|
71
|
-
if
|
|
72
|
-
x_ha
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
104
|
+
if rotate_x:
|
|
105
|
+
if x_ha is None:
|
|
106
|
+
x_ha = "center"
|
|
107
|
+
if x_va is None:
|
|
108
|
+
x_va = "center"
|
|
109
|
+
if rotate_y:
|
|
110
|
+
if y_ha is None:
|
|
111
|
+
y_ha = "center"
|
|
112
|
+
if y_va is None:
|
|
113
|
+
y_va = "center"
|
|
114
|
+
|
|
115
|
+
# Check if this axis is part of a shared x-axis configuration
|
|
116
|
+
# If labels are already visible (bottom subplot or not shared), keep them visible
|
|
117
|
+
# This preserves matplotlib's default sharex behavior
|
|
118
|
+
x_labels_visible = ax.xaxis.get_tick_params()["labelbottom"]
|
|
119
|
+
y_labels_visible = ax.yaxis.get_tick_params()["labelleft"]
|
|
79
120
|
|
|
80
121
|
# Set labels with rotation and proper alignment
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
# Only set labels if they're currently visible (respects sharex/sharey)
|
|
123
|
+
if x_labels_visible and rotate_x:
|
|
124
|
+
ax.set_xticklabels(ax.get_xticklabels(), rotation=x, ha=x_ha, va=x_va)
|
|
125
|
+
if y_labels_visible and rotate_y:
|
|
126
|
+
ax.set_yticklabels(ax.get_yticklabels(), rotation=y, ha=y_ha, va=y_va)
|
|
127
|
+
|
|
84
128
|
# Auto-adjust subplot parameters for better layout if needed
|
|
85
129
|
if auto_adjust and scientific_convention:
|
|
86
|
-
|
|
87
|
-
|
|
130
|
+
# Only pass non-zero angles for adjustment
|
|
131
|
+
x_angle = x if rotate_x else 0
|
|
132
|
+
y_angle = y if rotate_y else 0
|
|
133
|
+
_adjust_subplot_params(ax, x_angle, y_angle)
|
|
134
|
+
|
|
135
|
+
# Apply tight_layout if requested to prevent overlapping
|
|
136
|
+
if tight_layout:
|
|
137
|
+
fig = ax.get_figure()
|
|
138
|
+
try:
|
|
139
|
+
fig.tight_layout()
|
|
140
|
+
except Exception:
|
|
141
|
+
# Fallback to manual adjustment if tight_layout fails
|
|
142
|
+
x_angle = x if rotate_x else 0
|
|
143
|
+
y_angle = y if rotate_y else 0
|
|
144
|
+
_adjust_subplot_params(ax, x_angle, y_angle)
|
|
145
|
+
|
|
88
146
|
return ax
|
|
89
147
|
|
|
90
148
|
|
|
91
149
|
def _get_optimal_alignment(axis, angle, ha, va, scientific_convention):
|
|
92
150
|
"""
|
|
93
151
|
Determine optimal alignment based on rotation angle and scientific conventions.
|
|
94
|
-
|
|
152
|
+
|
|
95
153
|
Parameters
|
|
96
154
|
----------
|
|
97
155
|
axis : str
|
|
@@ -100,11 +158,11 @@ def _get_optimal_alignment(axis, angle, ha, va, scientific_convention):
|
|
|
100
158
|
Rotation angle in degrees
|
|
101
159
|
ha : str or None
|
|
102
160
|
Current horizontal alignment
|
|
103
|
-
va : str or None
|
|
161
|
+
va : str or None
|
|
104
162
|
Current vertical alignment
|
|
105
163
|
scientific_convention : bool
|
|
106
164
|
Whether to follow scientific conventions
|
|
107
|
-
|
|
165
|
+
|
|
108
166
|
Returns
|
|
109
167
|
-------
|
|
110
168
|
tuple
|
|
@@ -112,76 +170,83 @@ def _get_optimal_alignment(axis, angle, ha, va, scientific_convention):
|
|
|
112
170
|
"""
|
|
113
171
|
# Normalize angle to 0-360 range
|
|
114
172
|
angle = angle % 360
|
|
115
|
-
|
|
116
|
-
if axis ==
|
|
173
|
+
|
|
174
|
+
if axis == "x":
|
|
117
175
|
if scientific_convention:
|
|
118
176
|
# Scientific convention for x-axis labels
|
|
119
177
|
if 0 <= angle <= 30:
|
|
120
|
-
ha = ha or
|
|
121
|
-
va = va or
|
|
178
|
+
ha = ha or "center"
|
|
179
|
+
va = va or "top"
|
|
122
180
|
elif 30 < angle <= 60:
|
|
123
|
-
ha = ha or
|
|
124
|
-
va = va or
|
|
125
|
-
elif 60 < angle
|
|
126
|
-
ha = ha or
|
|
127
|
-
va = va or
|
|
181
|
+
ha = ha or "right"
|
|
182
|
+
va = va or "top"
|
|
183
|
+
elif 60 < angle < 90:
|
|
184
|
+
ha = ha or "right"
|
|
185
|
+
va = va or "top"
|
|
186
|
+
elif angle == 90:
|
|
187
|
+
# Special case for exact 90 degrees
|
|
188
|
+
ha = ha or "right"
|
|
189
|
+
va = va or "top"
|
|
190
|
+
elif 90 < angle <= 120:
|
|
191
|
+
ha = ha or "right"
|
|
192
|
+
va = va or "center"
|
|
128
193
|
elif 120 < angle <= 150:
|
|
129
|
-
ha = ha or
|
|
130
|
-
va = va or
|
|
194
|
+
ha = ha or "right"
|
|
195
|
+
va = va or "bottom"
|
|
131
196
|
elif 150 < angle <= 210:
|
|
132
|
-
ha = ha or
|
|
133
|
-
va = va or
|
|
197
|
+
ha = ha or "center"
|
|
198
|
+
va = va or "bottom"
|
|
134
199
|
elif 210 < angle <= 240:
|
|
135
|
-
ha = ha or
|
|
136
|
-
va = va or
|
|
200
|
+
ha = ha or "left"
|
|
201
|
+
va = va or "bottom"
|
|
137
202
|
elif 240 < angle <= 300:
|
|
138
|
-
ha = ha or
|
|
139
|
-
va = va or
|
|
203
|
+
ha = ha or "left"
|
|
204
|
+
va = va or "center"
|
|
140
205
|
else: # 300-360
|
|
141
|
-
ha = ha or
|
|
142
|
-
va = va or
|
|
206
|
+
ha = ha or "left"
|
|
207
|
+
va = va or "top"
|
|
143
208
|
else:
|
|
144
|
-
ha = ha or
|
|
145
|
-
va = va or
|
|
146
|
-
|
|
209
|
+
ha = ha or "center"
|
|
210
|
+
va = va or "top"
|
|
211
|
+
|
|
147
212
|
else: # y-axis
|
|
148
213
|
if scientific_convention:
|
|
149
214
|
# Scientific convention for y-axis labels
|
|
150
215
|
if 0 <= angle <= 30:
|
|
151
|
-
ha = ha or
|
|
152
|
-
va = va or
|
|
216
|
+
ha = ha or "right"
|
|
217
|
+
va = va or "center"
|
|
153
218
|
elif 30 < angle <= 60:
|
|
154
|
-
ha = ha or
|
|
155
|
-
va = va or
|
|
219
|
+
ha = ha or "right"
|
|
220
|
+
va = va or "bottom"
|
|
156
221
|
elif 60 < angle <= 120:
|
|
157
|
-
ha = ha or
|
|
158
|
-
va = va or
|
|
222
|
+
ha = ha or "center"
|
|
223
|
+
va = va or "bottom"
|
|
159
224
|
elif 120 < angle <= 150:
|
|
160
|
-
ha = ha or
|
|
161
|
-
va = va or
|
|
225
|
+
ha = ha or "left"
|
|
226
|
+
va = va or "bottom"
|
|
162
227
|
elif 150 < angle <= 210:
|
|
163
|
-
ha = ha or
|
|
164
|
-
va = va or
|
|
228
|
+
ha = ha or "left"
|
|
229
|
+
va = va or "center"
|
|
165
230
|
elif 210 < angle <= 240:
|
|
166
|
-
ha = ha or
|
|
167
|
-
va = va or
|
|
231
|
+
ha = ha or "left"
|
|
232
|
+
va = va or "top"
|
|
168
233
|
elif 240 < angle <= 300:
|
|
169
|
-
ha = ha or
|
|
170
|
-
va = va or
|
|
234
|
+
ha = ha or "center"
|
|
235
|
+
va = va or "top"
|
|
171
236
|
else: # 300-360
|
|
172
|
-
ha = ha or
|
|
173
|
-
va = va or
|
|
237
|
+
ha = ha or "right"
|
|
238
|
+
va = va or "top"
|
|
174
239
|
else:
|
|
175
|
-
ha = ha or
|
|
176
|
-
va = va or
|
|
177
|
-
|
|
240
|
+
ha = ha or "center"
|
|
241
|
+
va = va or "center"
|
|
242
|
+
|
|
178
243
|
return ha, va
|
|
179
244
|
|
|
180
245
|
|
|
181
246
|
def _adjust_subplot_params(ax, x_angle, y_angle):
|
|
182
247
|
"""
|
|
183
248
|
Automatically adjust subplot parameters to accommodate rotated labels.
|
|
184
|
-
|
|
249
|
+
|
|
185
250
|
Parameters
|
|
186
251
|
----------
|
|
187
252
|
ax : matplotlib.axes.Axes
|
|
@@ -192,24 +257,63 @@ def _adjust_subplot_params(ax, x_angle, y_angle):
|
|
|
192
257
|
Y-axis rotation angle
|
|
193
258
|
"""
|
|
194
259
|
fig = ax.get_figure()
|
|
195
|
-
|
|
260
|
+
|
|
261
|
+
# Check if figure is using a layout engine that is incompatible with subplots_adjust
|
|
262
|
+
try:
|
|
263
|
+
# For matplotlib >= 3.6
|
|
264
|
+
if hasattr(fig, "get_layout_engine"):
|
|
265
|
+
layout_engine = fig.get_layout_engine()
|
|
266
|
+
if layout_engine is not None:
|
|
267
|
+
# If using constrained_layout or tight_layout, don't adjust
|
|
268
|
+
return
|
|
269
|
+
except AttributeError:
|
|
270
|
+
pass
|
|
271
|
+
|
|
272
|
+
# Check for constrained_layout (older matplotlib versions)
|
|
273
|
+
try:
|
|
274
|
+
if hasattr(fig, "get_constrained_layout"):
|
|
275
|
+
if fig.get_constrained_layout():
|
|
276
|
+
# Constrained layout is active, don't adjust
|
|
277
|
+
return
|
|
278
|
+
except AttributeError:
|
|
279
|
+
pass
|
|
280
|
+
|
|
196
281
|
# Calculate required margins based on rotation angles
|
|
197
|
-
|
|
198
|
-
|
|
282
|
+
# Special handling for 90-degree rotation
|
|
283
|
+
if x_angle == 90:
|
|
284
|
+
x_margin_factor = 0.3 # Maximum margin for 90 degrees
|
|
285
|
+
else:
|
|
286
|
+
# Increase margin more significantly for rotated x-axis labels to prevent xlabel overlap
|
|
287
|
+
x_margin_factor = abs(np.sin(np.radians(x_angle))) * 0.25 # Increased from 0.2
|
|
199
288
|
|
|
289
|
+
y_margin_factor = abs(np.sin(np.radians(y_angle))) * 0.15
|
|
290
|
+
|
|
200
291
|
# Get current subplot parameters
|
|
201
292
|
try:
|
|
202
293
|
subplotpars = fig.subplotpars
|
|
203
294
|
current_bottom = subplotpars.bottom
|
|
204
295
|
current_left = subplotpars.left
|
|
205
|
-
|
|
296
|
+
|
|
206
297
|
# Adjust margins if they need to be increased
|
|
207
|
-
|
|
298
|
+
# Ensure more space for rotated x-labels and xlabel
|
|
299
|
+
new_bottom = max(
|
|
300
|
+
current_bottom, 0.2 + x_margin_factor
|
|
301
|
+
) # Increased base from 0.15
|
|
208
302
|
new_left = max(current_left, 0.1 + y_margin_factor)
|
|
209
|
-
|
|
303
|
+
|
|
210
304
|
# Only adjust if we're increasing the margins significantly
|
|
211
|
-
if
|
|
212
|
-
|
|
305
|
+
if (
|
|
306
|
+
new_bottom > current_bottom + 0.02
|
|
307
|
+
or new_left > current_left + 0.02
|
|
308
|
+
): # Reduced threshold
|
|
309
|
+
# Suppress warning and try to adjust
|
|
310
|
+
import warnings
|
|
311
|
+
|
|
312
|
+
with warnings.catch_warnings():
|
|
313
|
+
warnings.simplefilter("ignore")
|
|
314
|
+
fig.subplots_adjust(bottom=new_bottom, left=new_left)
|
|
213
315
|
except Exception:
|
|
214
316
|
# Skip adjustment if there are issues
|
|
215
317
|
pass
|
|
318
|
+
|
|
319
|
+
# EOF
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2024-10-27 13:24:32 (ywatanabe)"
|
|
4
|
+
# /home/ywatanabe/proj/_scitex_repo_openhands/src/scitex/plt/ax/_rotate_labels.py
|
|
5
|
+
|
|
6
|
+
"""This script does XYZ."""
|
|
7
|
+
|
|
8
|
+
"""Imports"""
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def rotate_labels(ax, x=45, y=45, x_ha=None, y_ha=None, x_va=None, y_va=None,
|
|
13
|
+
auto_adjust=True, scientific_convention=True):
|
|
14
|
+
"""
|
|
15
|
+
Rotate x and y axis labels of a matplotlib Axes object with automatic positioning.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
ax : matplotlib.axes.Axes
|
|
20
|
+
The Axes object to modify.
|
|
21
|
+
x : float, optional
|
|
22
|
+
Rotation angle for x-axis labels in degrees. Default is 45.
|
|
23
|
+
y : float, optional
|
|
24
|
+
Rotation angle for y-axis labels in degrees. Default is 45.
|
|
25
|
+
x_ha : str, optional
|
|
26
|
+
Horizontal alignment for x-axis labels. If None, automatically determined.
|
|
27
|
+
y_ha : str, optional
|
|
28
|
+
Horizontal alignment for y-axis labels. If None, automatically determined.
|
|
29
|
+
x_va : str, optional
|
|
30
|
+
Vertical alignment for x-axis labels. If None, automatically determined.
|
|
31
|
+
y_va : str, optional
|
|
32
|
+
Vertical alignment for y-axis labels. If None, automatically determined.
|
|
33
|
+
auto_adjust : bool, optional
|
|
34
|
+
Whether to automatically adjust alignment based on rotation angle. Default is True.
|
|
35
|
+
scientific_convention : bool, optional
|
|
36
|
+
Whether to follow scientific plotting conventions. Default is True.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
matplotlib.axes.Axes
|
|
41
|
+
The modified Axes object.
|
|
42
|
+
|
|
43
|
+
Example
|
|
44
|
+
-------
|
|
45
|
+
fig, ax = plt.subplots()
|
|
46
|
+
ax.plot([1, 2, 3], [1, 2, 3])
|
|
47
|
+
rotate_labels(ax)
|
|
48
|
+
plt.show()
|
|
49
|
+
|
|
50
|
+
Notes
|
|
51
|
+
-----
|
|
52
|
+
Scientific conventions for label rotation:
|
|
53
|
+
- X-axis labels: For angles 0-90°, use 'right' alignment; for 90-180°, use 'left'
|
|
54
|
+
- Y-axis labels: For angles 0-90°, use 'center' alignment; adjust vertical as needed
|
|
55
|
+
- Optimal readability maintained through automatic positioning
|
|
56
|
+
"""
|
|
57
|
+
# Get current tick positions
|
|
58
|
+
xticks = ax.get_xticks()
|
|
59
|
+
yticks = ax.get_yticks()
|
|
60
|
+
|
|
61
|
+
# Set ticks explicitly
|
|
62
|
+
ax.set_xticks(xticks)
|
|
63
|
+
ax.set_yticks(yticks)
|
|
64
|
+
|
|
65
|
+
# Auto-adjust alignment based on rotation angle and scientific conventions
|
|
66
|
+
if auto_adjust:
|
|
67
|
+
x_ha, x_va = _get_optimal_alignment('x', x, x_ha, x_va, scientific_convention)
|
|
68
|
+
y_ha, y_va = _get_optimal_alignment('y', y, y_ha, y_va, scientific_convention)
|
|
69
|
+
|
|
70
|
+
# Apply defaults if not auto-adjusting
|
|
71
|
+
if x_ha is None:
|
|
72
|
+
x_ha = "center"
|
|
73
|
+
if y_ha is None:
|
|
74
|
+
y_ha = "center"
|
|
75
|
+
if x_va is None:
|
|
76
|
+
x_va = "center"
|
|
77
|
+
if y_va is None:
|
|
78
|
+
y_va = "center"
|
|
79
|
+
|
|
80
|
+
# Check if this axis is part of a shared x-axis configuration
|
|
81
|
+
# If labels are already visible (bottom subplot or not shared), keep them visible
|
|
82
|
+
# This preserves matplotlib's default sharex behavior
|
|
83
|
+
x_labels_visible = ax.xaxis.get_tick_params()['labelbottom']
|
|
84
|
+
y_labels_visible = ax.yaxis.get_tick_params()['labelleft']
|
|
85
|
+
|
|
86
|
+
# Set labels with rotation and proper alignment
|
|
87
|
+
# Only set labels if they're currently visible (respects sharex/sharey)
|
|
88
|
+
if x_labels_visible:
|
|
89
|
+
ax.set_xticklabels(ax.get_xticklabels(), rotation=x, ha=x_ha, va=x_va)
|
|
90
|
+
if y_labels_visible:
|
|
91
|
+
ax.set_yticklabels(ax.get_yticklabels(), rotation=y, ha=y_ha, va=y_va)
|
|
92
|
+
|
|
93
|
+
# Auto-adjust subplot parameters for better layout if needed
|
|
94
|
+
if auto_adjust and scientific_convention:
|
|
95
|
+
_adjust_subplot_params(ax, x, y)
|
|
96
|
+
|
|
97
|
+
return ax
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _get_optimal_alignment(axis, angle, ha, va, scientific_convention):
|
|
101
|
+
"""
|
|
102
|
+
Determine optimal alignment based on rotation angle and scientific conventions.
|
|
103
|
+
|
|
104
|
+
Parameters
|
|
105
|
+
----------
|
|
106
|
+
axis : str
|
|
107
|
+
'x' or 'y' axis
|
|
108
|
+
angle : float
|
|
109
|
+
Rotation angle in degrees
|
|
110
|
+
ha : str or None
|
|
111
|
+
Current horizontal alignment
|
|
112
|
+
va : str or None
|
|
113
|
+
Current vertical alignment
|
|
114
|
+
scientific_convention : bool
|
|
115
|
+
Whether to follow scientific conventions
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
tuple
|
|
120
|
+
(horizontal_alignment, vertical_alignment)
|
|
121
|
+
"""
|
|
122
|
+
# Normalize angle to 0-360 range
|
|
123
|
+
angle = angle % 360
|
|
124
|
+
|
|
125
|
+
if axis == 'x':
|
|
126
|
+
if scientific_convention:
|
|
127
|
+
# Scientific convention for x-axis labels
|
|
128
|
+
if 0 <= angle <= 30:
|
|
129
|
+
ha = ha or 'center'
|
|
130
|
+
va = va or 'top'
|
|
131
|
+
elif 30 < angle <= 60:
|
|
132
|
+
ha = ha or 'right'
|
|
133
|
+
va = va or 'top'
|
|
134
|
+
elif 60 < angle <= 120:
|
|
135
|
+
ha = ha or 'right'
|
|
136
|
+
va = va or 'center'
|
|
137
|
+
elif 120 < angle <= 150:
|
|
138
|
+
ha = ha or 'right'
|
|
139
|
+
va = va or 'bottom'
|
|
140
|
+
elif 150 < angle <= 210:
|
|
141
|
+
ha = ha or 'center'
|
|
142
|
+
va = va or 'bottom'
|
|
143
|
+
elif 210 < angle <= 240:
|
|
144
|
+
ha = ha or 'left'
|
|
145
|
+
va = va or 'bottom'
|
|
146
|
+
elif 240 < angle <= 300:
|
|
147
|
+
ha = ha or 'left'
|
|
148
|
+
va = va or 'center'
|
|
149
|
+
else: # 300-360
|
|
150
|
+
ha = ha or 'left'
|
|
151
|
+
va = va or 'top'
|
|
152
|
+
else:
|
|
153
|
+
ha = ha or 'center'
|
|
154
|
+
va = va or 'top'
|
|
155
|
+
|
|
156
|
+
else: # y-axis
|
|
157
|
+
if scientific_convention:
|
|
158
|
+
# Scientific convention for y-axis labels
|
|
159
|
+
if 0 <= angle <= 30:
|
|
160
|
+
ha = ha or 'right'
|
|
161
|
+
va = va or 'center'
|
|
162
|
+
elif 30 < angle <= 60:
|
|
163
|
+
ha = ha or 'right'
|
|
164
|
+
va = va or 'bottom'
|
|
165
|
+
elif 60 < angle <= 120:
|
|
166
|
+
ha = ha or 'center'
|
|
167
|
+
va = va or 'bottom'
|
|
168
|
+
elif 120 < angle <= 150:
|
|
169
|
+
ha = ha or 'left'
|
|
170
|
+
va = va or 'bottom'
|
|
171
|
+
elif 150 < angle <= 210:
|
|
172
|
+
ha = ha or 'left'
|
|
173
|
+
va = va or 'center'
|
|
174
|
+
elif 210 < angle <= 240:
|
|
175
|
+
ha = ha or 'left'
|
|
176
|
+
va = va or 'top'
|
|
177
|
+
elif 240 < angle <= 300:
|
|
178
|
+
ha = ha or 'center'
|
|
179
|
+
va = va or 'top'
|
|
180
|
+
else: # 300-360
|
|
181
|
+
ha = ha or 'right'
|
|
182
|
+
va = va or 'top'
|
|
183
|
+
else:
|
|
184
|
+
ha = ha or 'center'
|
|
185
|
+
va = va or 'center'
|
|
186
|
+
|
|
187
|
+
return ha, va
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _adjust_subplot_params(ax, x_angle, y_angle):
|
|
191
|
+
"""
|
|
192
|
+
Automatically adjust subplot parameters to accommodate rotated labels.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
ax : matplotlib.axes.Axes
|
|
197
|
+
The axes object
|
|
198
|
+
x_angle : float
|
|
199
|
+
X-axis rotation angle
|
|
200
|
+
y_angle : float
|
|
201
|
+
Y-axis rotation angle
|
|
202
|
+
"""
|
|
203
|
+
fig = ax.get_figure()
|
|
204
|
+
|
|
205
|
+
# Check if figure is using a layout engine that is incompatible with subplots_adjust
|
|
206
|
+
try:
|
|
207
|
+
# For matplotlib >= 3.6
|
|
208
|
+
if hasattr(fig, 'get_layout_engine'):
|
|
209
|
+
layout_engine = fig.get_layout_engine()
|
|
210
|
+
if layout_engine is not None:
|
|
211
|
+
# If using constrained_layout or tight_layout, don't adjust
|
|
212
|
+
return
|
|
213
|
+
except AttributeError:
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
# Check for constrained_layout (older matplotlib versions)
|
|
217
|
+
try:
|
|
218
|
+
if hasattr(fig, 'get_constrained_layout'):
|
|
219
|
+
if fig.get_constrained_layout():
|
|
220
|
+
# Constrained layout is active, don't adjust
|
|
221
|
+
return
|
|
222
|
+
except AttributeError:
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
# Calculate required margins based on rotation angles
|
|
226
|
+
x_margin_factor = abs(np.sin(np.radians(x_angle))) * 0.1
|
|
227
|
+
y_margin_factor = abs(np.sin(np.radians(y_angle))) * 0.15
|
|
228
|
+
|
|
229
|
+
# Get current subplot parameters
|
|
230
|
+
try:
|
|
231
|
+
subplotpars = fig.subplotpars
|
|
232
|
+
current_bottom = subplotpars.bottom
|
|
233
|
+
current_left = subplotpars.left
|
|
234
|
+
|
|
235
|
+
# Adjust margins if they need to be increased
|
|
236
|
+
new_bottom = max(current_bottom, 0.1 + x_margin_factor)
|
|
237
|
+
new_left = max(current_left, 0.1 + y_margin_factor)
|
|
238
|
+
|
|
239
|
+
# Only adjust if we're increasing the margins significantly
|
|
240
|
+
if new_bottom > current_bottom + 0.05 or new_left > current_left + 0.05:
|
|
241
|
+
# Suppress warning and try to adjust
|
|
242
|
+
import warnings
|
|
243
|
+
with warnings.catch_warnings():
|
|
244
|
+
warnings.simplefilter("ignore")
|
|
245
|
+
fig.subplots_adjust(bottom=new_bottom, left=new_left)
|
|
246
|
+
except Exception:
|
|
247
|
+
# Skip adjustment if there are issues
|
|
248
|
+
pass
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!./env/bin/python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
# Time-stamp: "2025-06-04 11:35:00 (ywatanabe)"
|
|
4
|
-
# Author: Yusuke Watanabe (
|
|
4
|
+
# Author: Yusuke Watanabe (ywatanabe@scitex.ai)
|
|
5
5
|
|
|
6
6
|
"""
|
|
7
7
|
Scientific metadata management for figures with YAML export.
|
|
@@ -92,7 +92,13 @@ def set_meta(ax, caption=None, methods=None, stats=None, keywords=None,
|
|
|
92
92
|
# Add automatic metadata
|
|
93
93
|
import datetime
|
|
94
94
|
metadata['created_timestamp'] = datetime.datetime.now().isoformat()
|
|
95
|
-
|
|
95
|
+
|
|
96
|
+
# Get version dynamically
|
|
97
|
+
try:
|
|
98
|
+
import scitex
|
|
99
|
+
metadata['scitex_version'] = getattr(scitex, '__version__', 'unknown')
|
|
100
|
+
except ImportError:
|
|
101
|
+
metadata['scitex_version'] = 'unknown'
|
|
96
102
|
|
|
97
103
|
# Store metadata in figure for automatic saving
|
|
98
104
|
fig = ax.get_figure()
|
|
@@ -241,7 +247,8 @@ if __name__ == "__main__":
|
|
|
241
247
|
# Start
|
|
242
248
|
import sys
|
|
243
249
|
import matplotlib.pyplot as plt
|
|
244
|
-
|
|
250
|
+
import scitex
|
|
251
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(sys, plt)
|
|
245
252
|
|
|
246
253
|
# Example usage
|
|
247
254
|
fig, ax = plt.subplots()
|
|
@@ -256,6 +263,6 @@ if __name__ == "__main__":
|
|
|
256
263
|
export_metadata_yaml(fig, 'example_metadata.yaml')
|
|
257
264
|
|
|
258
265
|
# Close
|
|
259
|
-
scitex.
|
|
266
|
+
scitex.session.close(CONFIG)
|
|
260
267
|
|
|
261
268
|
# EOF
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!./env/bin/python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
# Time-stamp: "2024-07-13 07:56:46 (ywatanabe)"
|
|
4
|
-
# Author: Yusuke Watanabe (
|
|
4
|
+
# Author: Yusuke Watanabe (ywatanabe@scitex.ai)
|
|
5
5
|
|
|
6
6
|
"""
|
|
7
7
|
This script does XYZ.
|
|
@@ -106,11 +106,11 @@ def set_supxytc(ax, xlabel=False, ylabel=False, title=False, caption=False, meth
|
|
|
106
106
|
|
|
107
107
|
if __name__ == "__main__":
|
|
108
108
|
# Start
|
|
109
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.
|
|
109
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(sys, plt)
|
|
110
110
|
|
|
111
111
|
# (YOUR AWESOME CODE)
|
|
112
112
|
|
|
113
113
|
# Close
|
|
114
|
-
scitex.
|
|
114
|
+
scitex.session.close(CONFIG)
|
|
115
115
|
|
|
116
116
|
# EOF
|