scitex 2.0.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 +73 -0
- scitex/__main__.py +89 -0
- scitex/__version__.py +14 -0
- scitex/_sh.py +59 -0
- scitex/ai/_LearningCurveLogger.py +583 -0
- scitex/ai/__Classifiers.py +101 -0
- scitex/ai/__init__.py +55 -0
- scitex/ai/_gen_ai/_Anthropic.py +173 -0
- scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
- scitex/ai/_gen_ai/_DeepSeek.py +175 -0
- scitex/ai/_gen_ai/_Google.py +161 -0
- scitex/ai/_gen_ai/_Groq.py +97 -0
- scitex/ai/_gen_ai/_Llama.py +142 -0
- scitex/ai/_gen_ai/_OpenAI.py +230 -0
- scitex/ai/_gen_ai/_PARAMS.py +565 -0
- scitex/ai/_gen_ai/_Perplexity.py +191 -0
- scitex/ai/_gen_ai/__init__.py +32 -0
- scitex/ai/_gen_ai/_calc_cost.py +78 -0
- scitex/ai/_gen_ai/_format_output_func.py +183 -0
- scitex/ai/_gen_ai/_genai_factory.py +71 -0
- scitex/ai/act/__init__.py +8 -0
- scitex/ai/act/_define.py +11 -0
- scitex/ai/classification/__init__.py +7 -0
- scitex/ai/classification/classification_reporter.py +1137 -0
- scitex/ai/classification/classifier_server.py +131 -0
- scitex/ai/classification/classifiers.py +101 -0
- scitex/ai/classification_reporter.py +1161 -0
- scitex/ai/classifier_server.py +131 -0
- scitex/ai/clustering/__init__.py +11 -0
- scitex/ai/clustering/_pca.py +115 -0
- scitex/ai/clustering/_umap.py +376 -0
- scitex/ai/early_stopping.py +149 -0
- scitex/ai/feature_extraction/__init__.py +56 -0
- scitex/ai/feature_extraction/vit.py +148 -0
- scitex/ai/genai/__init__.py +277 -0
- scitex/ai/genai/anthropic.py +177 -0
- scitex/ai/genai/anthropic_provider.py +320 -0
- scitex/ai/genai/anthropic_refactored.py +109 -0
- scitex/ai/genai/auth_manager.py +200 -0
- scitex/ai/genai/base_genai.py +336 -0
- scitex/ai/genai/base_provider.py +291 -0
- scitex/ai/genai/calc_cost.py +78 -0
- scitex/ai/genai/chat_history.py +307 -0
- scitex/ai/genai/cost_tracker.py +276 -0
- scitex/ai/genai/deepseek.py +188 -0
- scitex/ai/genai/deepseek_provider.py +251 -0
- scitex/ai/genai/format_output_func.py +183 -0
- scitex/ai/genai/genai_factory.py +71 -0
- scitex/ai/genai/google.py +169 -0
- scitex/ai/genai/google_provider.py +228 -0
- scitex/ai/genai/groq.py +104 -0
- scitex/ai/genai/groq_provider.py +248 -0
- scitex/ai/genai/image_processor.py +250 -0
- scitex/ai/genai/llama.py +155 -0
- scitex/ai/genai/llama_provider.py +214 -0
- scitex/ai/genai/mock_provider.py +127 -0
- scitex/ai/genai/model_registry.py +304 -0
- scitex/ai/genai/openai.py +230 -0
- scitex/ai/genai/openai_provider.py +293 -0
- scitex/ai/genai/params.py +565 -0
- scitex/ai/genai/perplexity.py +202 -0
- scitex/ai/genai/perplexity_provider.py +205 -0
- scitex/ai/genai/provider_base.py +302 -0
- scitex/ai/genai/provider_factory.py +370 -0
- scitex/ai/genai/response_handler.py +235 -0
- scitex/ai/layer/_Pass.py +21 -0
- scitex/ai/layer/__init__.py +10 -0
- scitex/ai/layer/_switch.py +8 -0
- scitex/ai/loss/_L1L2Losses.py +34 -0
- scitex/ai/loss/__init__.py +12 -0
- scitex/ai/loss/multi_task_loss.py +47 -0
- scitex/ai/metrics/__init__.py +9 -0
- scitex/ai/metrics/_bACC.py +51 -0
- scitex/ai/metrics/silhoute_score_block.py +496 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ai/optim/__init__.py +13 -0
- scitex/ai/optim/_get_set.py +31 -0
- scitex/ai/optim/_optimizers.py +71 -0
- scitex/ai/plt/__init__.py +21 -0
- scitex/ai/plt/_conf_mat.py +592 -0
- scitex/ai/plt/_learning_curve.py +194 -0
- scitex/ai/plt/_optuna_study.py +111 -0
- scitex/ai/plt/aucs/__init__.py +2 -0
- scitex/ai/plt/aucs/example.py +60 -0
- scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
- scitex/ai/plt/aucs/roc_auc.py +246 -0
- scitex/ai/sampling/undersample.py +29 -0
- scitex/ai/sk/__init__.py +11 -0
- scitex/ai/sk/_clf.py +58 -0
- scitex/ai/sk/_to_sktime.py +100 -0
- scitex/ai/sklearn/__init__.py +26 -0
- scitex/ai/sklearn/clf.py +58 -0
- scitex/ai/sklearn/to_sktime.py +100 -0
- scitex/ai/training/__init__.py +7 -0
- scitex/ai/training/early_stopping.py +150 -0
- scitex/ai/training/learning_curve_logger.py +555 -0
- scitex/ai/utils/__init__.py +22 -0
- scitex/ai/utils/_check_params.py +50 -0
- scitex/ai/utils/_default_dataset.py +46 -0
- scitex/ai/utils/_format_samples_for_sktime.py +26 -0
- scitex/ai/utils/_label_encoder.py +134 -0
- scitex/ai/utils/_merge_labels.py +22 -0
- scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ai/utils/_under_sample.py +51 -0
- scitex/ai/utils/_verify_n_gpus.py +16 -0
- scitex/ai/utils/grid_search.py +148 -0
- scitex/context/__init__.py +9 -0
- scitex/context/_suppress_output.py +38 -0
- scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
- scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
- scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
- scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
- scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
- scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
- scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
- scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
- scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
- scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
- scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
- scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
- scitex/db/_BaseMixins/__init__.py +30 -0
- scitex/db/_PostgreSQL.py +126 -0
- scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
- scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
- scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
- scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
- scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
- scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
- scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
- scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
- scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
- scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
- scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
- scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
- scitex/db/_PostgreSQLMixins/__init__.py +34 -0
- scitex/db/_SQLite3.py +2136 -0
- scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
- scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
- scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
- scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
- scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
- scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
- scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
- scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
- scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
- scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
- scitex/db/_SQLite3Mixins/__init__.py +30 -0
- scitex/db/__init__.py +14 -0
- scitex/db/_delete_duplicates.py +397 -0
- scitex/db/_inspect.py +163 -0
- scitex/decorators/__init__.py +54 -0
- scitex/decorators/_auto_order.py +172 -0
- scitex/decorators/_batch_fn.py +127 -0
- scitex/decorators/_cache_disk.py +32 -0
- scitex/decorators/_cache_mem.py +12 -0
- scitex/decorators/_combined.py +98 -0
- scitex/decorators/_converters.py +282 -0
- scitex/decorators/_deprecated.py +26 -0
- scitex/decorators/_not_implemented.py +30 -0
- scitex/decorators/_numpy_fn.py +86 -0
- scitex/decorators/_pandas_fn.py +121 -0
- scitex/decorators/_preserve_doc.py +19 -0
- scitex/decorators/_signal_fn.py +95 -0
- scitex/decorators/_timeout.py +55 -0
- scitex/decorators/_torch_fn.py +136 -0
- scitex/decorators/_wrap.py +39 -0
- scitex/decorators/_xarray_fn.py +88 -0
- scitex/dev/__init__.py +15 -0
- scitex/dev/_analyze_code_flow.py +284 -0
- scitex/dev/_reload.py +59 -0
- scitex/dict/_DotDict.py +442 -0
- scitex/dict/__init__.py +18 -0
- scitex/dict/_listed_dict.py +42 -0
- scitex/dict/_pop_keys.py +36 -0
- scitex/dict/_replace.py +13 -0
- scitex/dict/_safe_merge.py +62 -0
- scitex/dict/_to_str.py +32 -0
- scitex/dsp/__init__.py +72 -0
- scitex/dsp/_crop.py +122 -0
- scitex/dsp/_demo_sig.py +331 -0
- scitex/dsp/_detect_ripples.py +212 -0
- scitex/dsp/_ensure_3d.py +18 -0
- scitex/dsp/_hilbert.py +78 -0
- scitex/dsp/_listen.py +702 -0
- scitex/dsp/_misc.py +30 -0
- scitex/dsp/_mne.py +32 -0
- scitex/dsp/_modulation_index.py +79 -0
- scitex/dsp/_pac.py +319 -0
- scitex/dsp/_psd.py +102 -0
- scitex/dsp/_resample.py +65 -0
- scitex/dsp/_time.py +36 -0
- scitex/dsp/_transform.py +68 -0
- scitex/dsp/_wavelet.py +212 -0
- scitex/dsp/add_noise.py +111 -0
- scitex/dsp/example.py +253 -0
- scitex/dsp/filt.py +155 -0
- scitex/dsp/norm.py +18 -0
- scitex/dsp/params.py +51 -0
- scitex/dsp/reference.py +43 -0
- scitex/dsp/template.py +25 -0
- scitex/dsp/utils/__init__.py +15 -0
- scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
- scitex/dsp/utils/_ensure_3d.py +18 -0
- scitex/dsp/utils/_ensure_even_len.py +10 -0
- scitex/dsp/utils/_zero_pad.py +48 -0
- scitex/dsp/utils/filter.py +408 -0
- scitex/dsp/utils/pac.py +177 -0
- scitex/dt/__init__.py +8 -0
- scitex/dt/_linspace.py +130 -0
- scitex/etc/__init__.py +15 -0
- scitex/etc/wait_key.py +34 -0
- scitex/gen/_DimHandler.py +196 -0
- scitex/gen/_TimeStamper.py +244 -0
- scitex/gen/__init__.py +95 -0
- scitex/gen/_alternate_kwarg.py +13 -0
- scitex/gen/_cache.py +11 -0
- scitex/gen/_check_host.py +34 -0
- scitex/gen/_ci.py +12 -0
- scitex/gen/_close.py +222 -0
- scitex/gen/_embed.py +78 -0
- scitex/gen/_inspect_module.py +257 -0
- scitex/gen/_is_ipython.py +12 -0
- scitex/gen/_less.py +48 -0
- scitex/gen/_list_packages.py +139 -0
- scitex/gen/_mat2py.py +88 -0
- scitex/gen/_norm.py +170 -0
- scitex/gen/_paste.py +18 -0
- scitex/gen/_print_config.py +84 -0
- scitex/gen/_shell.py +48 -0
- scitex/gen/_src.py +111 -0
- scitex/gen/_start.py +451 -0
- scitex/gen/_symlink.py +55 -0
- scitex/gen/_symlog.py +27 -0
- scitex/gen/_tee.py +238 -0
- scitex/gen/_title2path.py +60 -0
- scitex/gen/_title_case.py +88 -0
- scitex/gen/_to_even.py +84 -0
- scitex/gen/_to_odd.py +34 -0
- scitex/gen/_to_rank.py +39 -0
- scitex/gen/_transpose.py +37 -0
- scitex/gen/_type.py +78 -0
- scitex/gen/_var_info.py +73 -0
- scitex/gen/_wrap.py +17 -0
- scitex/gen/_xml2dict.py +76 -0
- scitex/gen/misc.py +730 -0
- scitex/gen/path.py +0 -0
- scitex/general/__init__.py +5 -0
- scitex/gists/_SigMacro_processFigure_S.py +128 -0
- scitex/gists/_SigMacro_toBlue.py +172 -0
- scitex/gists/__init__.py +12 -0
- scitex/io/_H5Explorer.py +292 -0
- scitex/io/__init__.py +82 -0
- scitex/io/_cache.py +101 -0
- scitex/io/_flush.py +24 -0
- scitex/io/_glob.py +103 -0
- scitex/io/_json2md.py +113 -0
- scitex/io/_load.py +168 -0
- scitex/io/_load_configs.py +146 -0
- scitex/io/_load_modules/__init__.py +38 -0
- scitex/io/_load_modules/_catboost.py +66 -0
- scitex/io/_load_modules/_con.py +20 -0
- scitex/io/_load_modules/_db.py +24 -0
- scitex/io/_load_modules/_docx.py +42 -0
- scitex/io/_load_modules/_eeg.py +110 -0
- scitex/io/_load_modules/_hdf5.py +196 -0
- scitex/io/_load_modules/_image.py +19 -0
- scitex/io/_load_modules/_joblib.py +19 -0
- scitex/io/_load_modules/_json.py +18 -0
- scitex/io/_load_modules/_markdown.py +103 -0
- scitex/io/_load_modules/_matlab.py +37 -0
- scitex/io/_load_modules/_numpy.py +39 -0
- scitex/io/_load_modules/_optuna.py +155 -0
- scitex/io/_load_modules/_pandas.py +69 -0
- scitex/io/_load_modules/_pdf.py +31 -0
- scitex/io/_load_modules/_pickle.py +24 -0
- scitex/io/_load_modules/_torch.py +16 -0
- scitex/io/_load_modules/_txt.py +126 -0
- scitex/io/_load_modules/_xml.py +49 -0
- scitex/io/_load_modules/_yaml.py +23 -0
- scitex/io/_mv_to_tmp.py +19 -0
- scitex/io/_path.py +286 -0
- scitex/io/_reload.py +78 -0
- scitex/io/_save.py +539 -0
- scitex/io/_save_modules/__init__.py +66 -0
- scitex/io/_save_modules/_catboost.py +22 -0
- scitex/io/_save_modules/_csv.py +89 -0
- scitex/io/_save_modules/_excel.py +49 -0
- scitex/io/_save_modules/_hdf5.py +249 -0
- scitex/io/_save_modules/_html.py +48 -0
- scitex/io/_save_modules/_image.py +140 -0
- scitex/io/_save_modules/_joblib.py +25 -0
- scitex/io/_save_modules/_json.py +25 -0
- scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
- scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
- scitex/io/_save_modules/_matlab.py +24 -0
- scitex/io/_save_modules/_mp4.py +29 -0
- scitex/io/_save_modules/_numpy.py +57 -0
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
- scitex/io/_save_modules/_pickle.py +45 -0
- scitex/io/_save_modules/_plotly.py +27 -0
- scitex/io/_save_modules/_text.py +23 -0
- scitex/io/_save_modules/_torch.py +26 -0
- scitex/io/_save_modules/_yaml.py +29 -0
- scitex/life/__init__.py +10 -0
- scitex/life/_monitor_rain.py +49 -0
- scitex/linalg/__init__.py +17 -0
- scitex/linalg/_distance.py +63 -0
- scitex/linalg/_geometric_median.py +64 -0
- scitex/linalg/_misc.py +73 -0
- scitex/nn/_AxiswiseDropout.py +27 -0
- scitex/nn/_BNet.py +126 -0
- scitex/nn/_BNet_Res.py +164 -0
- scitex/nn/_ChannelGainChanger.py +44 -0
- scitex/nn/_DropoutChannels.py +50 -0
- scitex/nn/_Filters.py +489 -0
- scitex/nn/_FreqGainChanger.py +110 -0
- scitex/nn/_GaussianFilter.py +48 -0
- scitex/nn/_Hilbert.py +111 -0
- scitex/nn/_MNet_1000.py +157 -0
- scitex/nn/_ModulationIndex.py +221 -0
- scitex/nn/_PAC.py +414 -0
- scitex/nn/_PSD.py +40 -0
- scitex/nn/_ResNet1D.py +120 -0
- scitex/nn/_SpatialAttention.py +25 -0
- scitex/nn/_Spectrogram.py +161 -0
- scitex/nn/_SwapChannels.py +50 -0
- scitex/nn/_TransposeLayer.py +19 -0
- scitex/nn/_Wavelet.py +183 -0
- scitex/nn/__init__.py +63 -0
- scitex/os/__init__.py +8 -0
- scitex/os/_mv.py +50 -0
- scitex/parallel/__init__.py +8 -0
- scitex/parallel/_run.py +151 -0
- scitex/path/__init__.py +33 -0
- scitex/path/_clean.py +52 -0
- scitex/path/_find.py +108 -0
- scitex/path/_get_module_path.py +51 -0
- scitex/path/_get_spath.py +35 -0
- scitex/path/_getsize.py +18 -0
- scitex/path/_increment_version.py +87 -0
- scitex/path/_mk_spath.py +51 -0
- scitex/path/_path.py +19 -0
- scitex/path/_split.py +23 -0
- scitex/path/_this_path.py +19 -0
- scitex/path/_version.py +101 -0
- scitex/pd/__init__.py +41 -0
- scitex/pd/_find_indi.py +126 -0
- scitex/pd/_find_pval.py +113 -0
- scitex/pd/_force_df.py +154 -0
- scitex/pd/_from_xyz.py +71 -0
- scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
- scitex/pd/_melt_cols.py +81 -0
- scitex/pd/_merge_columns.py +221 -0
- scitex/pd/_mv.py +63 -0
- scitex/pd/_replace.py +62 -0
- scitex/pd/_round.py +93 -0
- scitex/pd/_slice.py +63 -0
- scitex/pd/_sort.py +91 -0
- scitex/pd/_to_numeric.py +53 -0
- scitex/pd/_to_xy.py +59 -0
- scitex/pd/_to_xyz.py +110 -0
- scitex/plt/__init__.py +36 -0
- scitex/plt/_subplots/_AxesWrapper.py +182 -0
- scitex/plt/_subplots/_AxisWrapper.py +249 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
- scitex/plt/_subplots/_FigWrapper.py +226 -0
- scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
- scitex/plt/_subplots/__init__.py +111 -0
- scitex/plt/_subplots/_export_as_csv.py +232 -0
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
- scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
- scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
- scitex/plt/_tpl.py +28 -0
- scitex/plt/ax/__init__.py +114 -0
- scitex/plt/ax/_plot/__init__.py +53 -0
- scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
- scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
- scitex/plt/ax/_plot/_plot_cube.py +57 -0
- scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
- scitex/plt/ax/_plot/_plot_fillv.py +55 -0
- scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
- scitex/plt/ax/_plot/_plot_image.py +94 -0
- scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
- scitex/plt/ax/_plot/_plot_raster.py +172 -0
- scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
- scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
- scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
- scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
- scitex/plt/ax/_plot/_plot_violin.py +343 -0
- scitex/plt/ax/_style/__init__.py +38 -0
- scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
- scitex/plt/ax/_style/_add_panel.py +92 -0
- scitex/plt/ax/_style/_extend.py +64 -0
- scitex/plt/ax/_style/_force_aspect.py +37 -0
- scitex/plt/ax/_style/_format_label.py +23 -0
- scitex/plt/ax/_style/_hide_spines.py +84 -0
- scitex/plt/ax/_style/_map_ticks.py +182 -0
- scitex/plt/ax/_style/_rotate_labels.py +215 -0
- scitex/plt/ax/_style/_sci_note.py +279 -0
- scitex/plt/ax/_style/_set_log_scale.py +299 -0
- scitex/plt/ax/_style/_set_meta.py +261 -0
- scitex/plt/ax/_style/_set_n_ticks.py +37 -0
- scitex/plt/ax/_style/_set_size.py +16 -0
- scitex/plt/ax/_style/_set_supxyt.py +116 -0
- scitex/plt/ax/_style/_set_ticks.py +276 -0
- scitex/plt/ax/_style/_set_xyt.py +121 -0
- scitex/plt/ax/_style/_share_axes.py +264 -0
- scitex/plt/ax/_style/_shift.py +139 -0
- scitex/plt/ax/_style/_show_spines.py +333 -0
- scitex/plt/color/_PARAMS.py +70 -0
- scitex/plt/color/__init__.py +52 -0
- scitex/plt/color/_add_hue_col.py +41 -0
- scitex/plt/color/_colors.py +205 -0
- scitex/plt/color/_get_colors_from_cmap.py +134 -0
- scitex/plt/color/_interpolate.py +29 -0
- scitex/plt/color/_vizualize_colors.py +54 -0
- scitex/plt/utils/__init__.py +44 -0
- scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
- scitex/plt/utils/_calc_nice_ticks.py +101 -0
- scitex/plt/utils/_close.py +68 -0
- scitex/plt/utils/_colorbar.py +96 -0
- scitex/plt/utils/_configure_mpl.py +295 -0
- scitex/plt/utils/_histogram_utils.py +132 -0
- scitex/plt/utils/_im2grid.py +70 -0
- scitex/plt/utils/_is_valid_axis.py +78 -0
- scitex/plt/utils/_mk_colorbar.py +65 -0
- scitex/plt/utils/_mk_patches.py +26 -0
- scitex/plt/utils/_scientific_captions.py +638 -0
- scitex/plt/utils/_scitex_config.py +223 -0
- scitex/reproduce/__init__.py +14 -0
- scitex/reproduce/_fix_seeds.py +45 -0
- scitex/reproduce/_gen_ID.py +55 -0
- scitex/reproduce/_gen_timestamp.py +35 -0
- scitex/res/__init__.py +5 -0
- scitex/resource/__init__.py +13 -0
- scitex/resource/_get_processor_usages.py +281 -0
- scitex/resource/_get_specs.py +280 -0
- scitex/resource/_log_processor_usages.py +190 -0
- scitex/resource/_utils/__init__.py +31 -0
- scitex/resource/_utils/_get_env_info.py +481 -0
- scitex/resource/limit_ram.py +33 -0
- scitex/scholar/__init__.py +24 -0
- scitex/scholar/_local_search.py +454 -0
- scitex/scholar/_paper.py +244 -0
- scitex/scholar/_pdf_downloader.py +325 -0
- scitex/scholar/_search.py +393 -0
- scitex/scholar/_vector_search.py +370 -0
- scitex/scholar/_web_sources.py +457 -0
- scitex/stats/__init__.py +31 -0
- scitex/stats/_calc_partial_corr.py +17 -0
- scitex/stats/_corr_test_multi.py +94 -0
- scitex/stats/_corr_test_wrapper.py +115 -0
- scitex/stats/_describe_wrapper.py +90 -0
- scitex/stats/_multiple_corrections.py +63 -0
- scitex/stats/_nan_stats.py +93 -0
- scitex/stats/_p2stars.py +116 -0
- scitex/stats/_p2stars_wrapper.py +56 -0
- scitex/stats/_statistical_tests.py +73 -0
- scitex/stats/desc/__init__.py +40 -0
- scitex/stats/desc/_describe.py +189 -0
- scitex/stats/desc/_nan.py +289 -0
- scitex/stats/desc/_real.py +94 -0
- scitex/stats/multiple/__init__.py +14 -0
- scitex/stats/multiple/_bonferroni_correction.py +72 -0
- scitex/stats/multiple/_fdr_correction.py +400 -0
- scitex/stats/multiple/_multicompair.py +28 -0
- scitex/stats/tests/__corr_test.py +277 -0
- scitex/stats/tests/__corr_test_multi.py +343 -0
- scitex/stats/tests/__corr_test_single.py +277 -0
- scitex/stats/tests/__init__.py +22 -0
- scitex/stats/tests/_brunner_munzel_test.py +192 -0
- scitex/stats/tests/_nocorrelation_test.py +28 -0
- scitex/stats/tests/_smirnov_grubbs.py +98 -0
- scitex/str/__init__.py +113 -0
- scitex/str/_clean_path.py +75 -0
- scitex/str/_color_text.py +52 -0
- scitex/str/_decapitalize.py +58 -0
- scitex/str/_factor_out_digits.py +281 -0
- scitex/str/_format_plot_text.py +498 -0
- scitex/str/_grep.py +48 -0
- scitex/str/_latex.py +155 -0
- scitex/str/_latex_fallback.py +471 -0
- scitex/str/_mask_api.py +39 -0
- scitex/str/_mask_api_key.py +8 -0
- scitex/str/_parse.py +158 -0
- scitex/str/_print_block.py +47 -0
- scitex/str/_print_debug.py +68 -0
- scitex/str/_printc.py +62 -0
- scitex/str/_readable_bytes.py +38 -0
- scitex/str/_remove_ansi.py +23 -0
- scitex/str/_replace.py +134 -0
- scitex/str/_search.py +125 -0
- scitex/str/_squeeze_space.py +36 -0
- scitex/tex/__init__.py +10 -0
- scitex/tex/_preview.py +103 -0
- scitex/tex/_to_vec.py +116 -0
- scitex/torch/__init__.py +18 -0
- scitex/torch/_apply_to.py +34 -0
- scitex/torch/_nan_funcs.py +77 -0
- scitex/types/_ArrayLike.py +44 -0
- scitex/types/_ColorLike.py +21 -0
- scitex/types/__init__.py +14 -0
- scitex/types/_is_listed_X.py +70 -0
- scitex/utils/__init__.py +22 -0
- scitex/utils/_compress_hdf5.py +116 -0
- scitex/utils/_email.py +120 -0
- scitex/utils/_grid.py +148 -0
- scitex/utils/_notify.py +247 -0
- scitex/utils/_search.py +121 -0
- scitex/web/__init__.py +38 -0
- scitex/web/_search_pubmed.py +438 -0
- scitex/web/_summarize_url.py +158 -0
- scitex-2.0.0.dist-info/METADATA +307 -0
- scitex-2.0.0.dist-info/RECORD +572 -0
- scitex-2.0.0.dist-info/WHEEL +6 -0
- scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
- scitex-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,638 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2025-06-04 11:17:00 (ywatanabe)"
|
|
4
|
+
# File: ./src/scitex/plt/utils/_scientific_captions.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Functionality:
|
|
8
|
+
Scientific figure caption system for publication-ready figures
|
|
9
|
+
Input:
|
|
10
|
+
Figure objects, caption text, and formatting parameters
|
|
11
|
+
Output:
|
|
12
|
+
Figures with properly formatted scientific captions
|
|
13
|
+
Prerequisites:
|
|
14
|
+
matplotlib, textwrap
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import matplotlib.pyplot as plt
|
|
18
|
+
import matplotlib.patches as patches
|
|
19
|
+
from matplotlib.patches import FancyBboxPatch
|
|
20
|
+
import textwrap
|
|
21
|
+
from typing import Union, List, Dict, Tuple, Optional
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ScientificCaption:
|
|
26
|
+
"""
|
|
27
|
+
A comprehensive caption system for scientific figures with support for:
|
|
28
|
+
- Figure-level captions
|
|
29
|
+
- Panel-level captions (A, B, C, etc.)
|
|
30
|
+
- Automatic numbering
|
|
31
|
+
- Cross-references
|
|
32
|
+
- Multiple formatting styles
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
self.figure_counter = 0
|
|
37
|
+
self.caption_registry = {}
|
|
38
|
+
self.panel_letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']
|
|
39
|
+
|
|
40
|
+
def add_figure_caption(
|
|
41
|
+
self,
|
|
42
|
+
fig,
|
|
43
|
+
caption: str,
|
|
44
|
+
figure_label: str = None,
|
|
45
|
+
style: str = "scientific",
|
|
46
|
+
position: str = "bottom",
|
|
47
|
+
width_ratio: float = 0.9,
|
|
48
|
+
font_size: Union[str, int] = "small",
|
|
49
|
+
wrap_width: int = 80,
|
|
50
|
+
save_to_file: bool = False,
|
|
51
|
+
file_path: str = None
|
|
52
|
+
) -> str:
|
|
53
|
+
"""
|
|
54
|
+
Add a scientific caption to a figure.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
fig : matplotlib.figure.Figure
|
|
59
|
+
The figure to add caption to
|
|
60
|
+
caption : str
|
|
61
|
+
The caption text
|
|
62
|
+
figure_label : str, optional
|
|
63
|
+
Custom figure label (e.g., "Figure 1"), auto-generated if None
|
|
64
|
+
style : str, optional
|
|
65
|
+
Caption style: "scientific", "nature", "ieee", "apa", by default "scientific"
|
|
66
|
+
position : str, optional
|
|
67
|
+
Caption position: "bottom", "top", by default "bottom"
|
|
68
|
+
width_ratio : float, optional
|
|
69
|
+
Width of caption relative to figure width, by default 0.9
|
|
70
|
+
font_size : Union[str, int], optional
|
|
71
|
+
Font size for caption, by default "small"
|
|
72
|
+
wrap_width : int, optional
|
|
73
|
+
Character width for text wrapping, by default 80
|
|
74
|
+
save_to_file : bool, optional
|
|
75
|
+
Whether to save caption to separate file, by default False
|
|
76
|
+
file_path : str, optional
|
|
77
|
+
Path for caption file, by default None
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
str
|
|
82
|
+
The formatted caption text
|
|
83
|
+
"""
|
|
84
|
+
# Generate figure label if not provided
|
|
85
|
+
if figure_label is None:
|
|
86
|
+
self.figure_counter += 1
|
|
87
|
+
figure_label = f"Figure {self.figure_counter}"
|
|
88
|
+
|
|
89
|
+
# Format caption according to style
|
|
90
|
+
formatted_caption = self._format_caption(caption, figure_label, style, wrap_width)
|
|
91
|
+
|
|
92
|
+
# Add caption to figure
|
|
93
|
+
self._add_caption_to_figure(fig, formatted_caption, position, width_ratio, font_size)
|
|
94
|
+
|
|
95
|
+
# Register caption
|
|
96
|
+
self.caption_registry[figure_label] = {
|
|
97
|
+
'text': caption,
|
|
98
|
+
'formatted': formatted_caption,
|
|
99
|
+
'style': style,
|
|
100
|
+
'figure': fig
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Save to file if requested
|
|
104
|
+
if save_to_file:
|
|
105
|
+
self._save_caption_to_file(formatted_caption, figure_label, file_path)
|
|
106
|
+
|
|
107
|
+
return formatted_caption
|
|
108
|
+
|
|
109
|
+
def add_panel_captions(
|
|
110
|
+
self,
|
|
111
|
+
fig,
|
|
112
|
+
axes,
|
|
113
|
+
panel_captions: Union[List[str], Dict[str, str]],
|
|
114
|
+
main_caption: str = "",
|
|
115
|
+
figure_label: str = None,
|
|
116
|
+
panel_style: str = "letter_bold",
|
|
117
|
+
position: str = "top_left",
|
|
118
|
+
font_size: Union[str, int] = "medium",
|
|
119
|
+
offset: Tuple[float, float] = (0.02, 0.98)
|
|
120
|
+
) -> Dict[str, str]:
|
|
121
|
+
"""
|
|
122
|
+
Add panel captions (A, B, C, etc.) to subplot panels.
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
fig : matplotlib.figure.Figure
|
|
127
|
+
The figure containing panels
|
|
128
|
+
axes : Union[matplotlib.axes.Axes, List, np.ndarray]
|
|
129
|
+
Axes objects for each panel
|
|
130
|
+
panel_captions : Union[List[str], Dict[str, str]]
|
|
131
|
+
Caption text for each panel, either list or dict with panel labels
|
|
132
|
+
main_caption : str, optional
|
|
133
|
+
Main figure caption, by default ""
|
|
134
|
+
figure_label : str, optional
|
|
135
|
+
Figure label, by default None
|
|
136
|
+
panel_style : str, optional
|
|
137
|
+
Panel label style: "letter_bold", "letter_italic", "number", by default "letter_bold"
|
|
138
|
+
position : str, optional
|
|
139
|
+
Panel label position: "top_left", "top_right", "bottom_left", "bottom_right", by default "top_left"
|
|
140
|
+
font_size : Union[str, int], optional
|
|
141
|
+
Font size for panel labels, by default "medium"
|
|
142
|
+
offset : Tuple[float, float], optional
|
|
143
|
+
Position offset for panel labels, by default (0.02, 0.98)
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
Dict[str, str]
|
|
148
|
+
Dictionary mapping panel labels to full caption text
|
|
149
|
+
"""
|
|
150
|
+
# Ensure axes is a list
|
|
151
|
+
if not isinstance(axes, (list, tuple)):
|
|
152
|
+
axes = [axes] if hasattr(axes, 'plot') else axes.flatten()
|
|
153
|
+
|
|
154
|
+
# Handle different input formats for panel_captions
|
|
155
|
+
if isinstance(panel_captions, list):
|
|
156
|
+
panel_dict = {self.panel_letters[i]: panel_captions[i]
|
|
157
|
+
for i in range(min(len(panel_captions), len(axes)))}
|
|
158
|
+
else:
|
|
159
|
+
panel_dict = panel_captions
|
|
160
|
+
|
|
161
|
+
# Add panel labels to axes
|
|
162
|
+
formatted_panels = {}
|
|
163
|
+
for i, ax in enumerate(axes):
|
|
164
|
+
if i < len(self.panel_letters):
|
|
165
|
+
panel_letter = self.panel_letters[i]
|
|
166
|
+
if panel_letter in panel_dict:
|
|
167
|
+
formatted_label = self._format_panel_label(panel_letter, panel_style)
|
|
168
|
+
panel_caption = panel_dict[panel_letter]
|
|
169
|
+
|
|
170
|
+
# Add label to axes
|
|
171
|
+
self._add_panel_label_to_axes(ax, formatted_label, position, font_size, offset)
|
|
172
|
+
|
|
173
|
+
formatted_panels[panel_letter] = f"{formatted_label} {panel_caption}"
|
|
174
|
+
|
|
175
|
+
# Add main caption if provided
|
|
176
|
+
if main_caption:
|
|
177
|
+
full_caption = self._combine_panel_and_main_captions(formatted_panels, main_caption)
|
|
178
|
+
self.add_figure_caption(fig, full_caption, figure_label)
|
|
179
|
+
|
|
180
|
+
return formatted_panels
|
|
181
|
+
|
|
182
|
+
def _format_caption(self, caption: str, figure_label: str, style: str, wrap_width: int) -> str:
|
|
183
|
+
"""Format caption according to specified style."""
|
|
184
|
+
# Wrap text
|
|
185
|
+
wrapped_text = textwrap.fill(caption, width=wrap_width)
|
|
186
|
+
|
|
187
|
+
if style == "scientific":
|
|
188
|
+
return f"**{figure_label}.** {wrapped_text}"
|
|
189
|
+
elif style == "nature":
|
|
190
|
+
return f"**{figure_label} |** {wrapped_text}"
|
|
191
|
+
elif style == "ieee":
|
|
192
|
+
return f"{figure_label}. {wrapped_text}"
|
|
193
|
+
elif style == "apa":
|
|
194
|
+
return f"*{figure_label}*\n{wrapped_text}"
|
|
195
|
+
else:
|
|
196
|
+
return f"{figure_label}. {wrapped_text}"
|
|
197
|
+
|
|
198
|
+
def _format_panel_label(self, letter: str, style: str) -> str:
|
|
199
|
+
"""Format panel label according to style."""
|
|
200
|
+
if style == "letter_bold":
|
|
201
|
+
return f"**{letter}**"
|
|
202
|
+
elif style == "letter_italic":
|
|
203
|
+
return f"*{letter}*"
|
|
204
|
+
elif style == "number":
|
|
205
|
+
return f"**{ord(letter) - ord('A') + 1}**"
|
|
206
|
+
else:
|
|
207
|
+
return f"**{letter}**"
|
|
208
|
+
|
|
209
|
+
def _add_caption_to_figure(self, fig, caption: str, position: str, width_ratio: float, font_size: Union[str, int]):
|
|
210
|
+
"""Add caption text to figure."""
|
|
211
|
+
# Calculate position
|
|
212
|
+
if position == "bottom":
|
|
213
|
+
y_pos = 0.02
|
|
214
|
+
va = 'bottom'
|
|
215
|
+
else: # top
|
|
216
|
+
y_pos = 0.98
|
|
217
|
+
va = 'top'
|
|
218
|
+
|
|
219
|
+
# Add caption text
|
|
220
|
+
fig.text(
|
|
221
|
+
0.5, y_pos, caption,
|
|
222
|
+
ha='center', va=va,
|
|
223
|
+
fontsize=font_size,
|
|
224
|
+
wrap=True,
|
|
225
|
+
bbox=dict(boxstyle="round,pad=0.5", facecolor='white', alpha=0.8)
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# Adjust layout to accommodate caption
|
|
229
|
+
if position == "bottom":
|
|
230
|
+
fig.subplots_adjust(bottom=0.15)
|
|
231
|
+
else:
|
|
232
|
+
fig.subplots_adjust(top=0.85)
|
|
233
|
+
|
|
234
|
+
def _add_panel_label_to_axes(self, ax, label: str, position: str, font_size: Union[str, int], offset: Tuple[float, float]):
|
|
235
|
+
"""Add panel label to individual axes."""
|
|
236
|
+
# Position mapping
|
|
237
|
+
positions = {
|
|
238
|
+
'top_left': (offset[0], offset[1]),
|
|
239
|
+
'top_right': (1 - offset[0], offset[1]),
|
|
240
|
+
'bottom_left': (offset[0], 1 - offset[1]),
|
|
241
|
+
'bottom_right': (1 - offset[0], 1 - offset[1])
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
x_pos, y_pos = positions.get(position, (offset[0], offset[1]))
|
|
245
|
+
|
|
246
|
+
# Determine alignment
|
|
247
|
+
ha = 'left' if 'left' in position else 'right'
|
|
248
|
+
va = 'top' if 'top' in position else 'bottom'
|
|
249
|
+
|
|
250
|
+
# Add label
|
|
251
|
+
ax.text(
|
|
252
|
+
x_pos, y_pos, label,
|
|
253
|
+
transform=ax.transAxes,
|
|
254
|
+
fontsize=font_size,
|
|
255
|
+
fontweight='bold',
|
|
256
|
+
ha=ha, va=va,
|
|
257
|
+
bbox=dict(boxstyle="round,pad=0.3", facecolor='white', alpha=0.9)
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def _combine_panel_and_main_captions(self, panel_dict: Dict[str, str], main_caption: str) -> str:
|
|
261
|
+
"""Combine panel captions with main caption."""
|
|
262
|
+
panel_descriptions = []
|
|
263
|
+
for letter in sorted(panel_dict.keys()):
|
|
264
|
+
panel_descriptions.append(f"({letter}) {panel_dict[letter].split(' ', 1)[1]}") # Remove the bold letter
|
|
265
|
+
|
|
266
|
+
combined = main_caption
|
|
267
|
+
if panel_descriptions:
|
|
268
|
+
combined += " " + " ".join(panel_descriptions)
|
|
269
|
+
|
|
270
|
+
return combined
|
|
271
|
+
|
|
272
|
+
def _save_caption_to_file(self, caption: str, figure_label: str, file_path: str = None):
|
|
273
|
+
"""Save caption to a text file."""
|
|
274
|
+
if file_path is None:
|
|
275
|
+
file_path = f"{figure_label.lower().replace(' ', '_')}_caption.txt"
|
|
276
|
+
|
|
277
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
278
|
+
f.write(caption)
|
|
279
|
+
|
|
280
|
+
def export_all_captions(self, file_path: str = "figure_captions.txt", style: str = "scientific"):
|
|
281
|
+
"""Export all registered captions to a file."""
|
|
282
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
283
|
+
f.write("Figure Captions\n")
|
|
284
|
+
f.write("=" * 50 + "\n\n")
|
|
285
|
+
|
|
286
|
+
for label, info in self.caption_registry.items():
|
|
287
|
+
f.write(f"{info['formatted']}\n\n")
|
|
288
|
+
|
|
289
|
+
def get_cross_reference(self, figure_label: str) -> str:
|
|
290
|
+
"""Get a cross-reference string for a figure."""
|
|
291
|
+
if figure_label in self.caption_registry:
|
|
292
|
+
return f"(see {figure_label})"
|
|
293
|
+
else:
|
|
294
|
+
return f"(see {figure_label} - not found)"
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# Global caption manager instance
|
|
298
|
+
caption_manager = ScientificCaption()
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
# Convenience functions
|
|
302
|
+
def add_figure_caption(fig, caption: str, **kwargs) -> str:
|
|
303
|
+
"""Convenience function to add figure caption."""
|
|
304
|
+
return caption_manager.add_figure_caption(fig, caption, **kwargs)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def add_panel_captions(fig, axes, panel_captions, **kwargs) -> Dict[str, str]:
|
|
308
|
+
"""Convenience function to add panel captions."""
|
|
309
|
+
return caption_manager.add_panel_captions(fig, axes, panel_captions, **kwargs)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def export_captions(file_path: str = "figure_captions.txt"):
|
|
313
|
+
"""Convenience function to export all captions."""
|
|
314
|
+
return caption_manager.export_all_captions(file_path)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def cross_ref(figure_label: str) -> str:
|
|
318
|
+
"""Convenience function for cross-references."""
|
|
319
|
+
return caption_manager.get_cross_reference(figure_label)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
# Integration with scitex save system
|
|
323
|
+
def save_with_caption(fig, filename: str, caption: str = None, **caption_kwargs):
|
|
324
|
+
"""
|
|
325
|
+
Save figure with caption integration.
|
|
326
|
+
|
|
327
|
+
This function saves the figure and optionally creates caption files
|
|
328
|
+
that can be used for manuscript preparation.
|
|
329
|
+
"""
|
|
330
|
+
import scitex
|
|
331
|
+
|
|
332
|
+
# Save the figure normally
|
|
333
|
+
scitex.io.save(fig, filename)
|
|
334
|
+
|
|
335
|
+
# Add caption if provided
|
|
336
|
+
if caption:
|
|
337
|
+
# Extract base filename
|
|
338
|
+
base_name = filename.split('.')[0]
|
|
339
|
+
|
|
340
|
+
# Save in multiple formats (like CSV system)
|
|
341
|
+
_save_caption_multiple_formats(caption, base_name, **caption_kwargs)
|
|
342
|
+
|
|
343
|
+
# Add caption to figure
|
|
344
|
+
formatted_caption = add_figure_caption(fig, caption, **caption_kwargs)
|
|
345
|
+
|
|
346
|
+
return formatted_caption
|
|
347
|
+
|
|
348
|
+
return None
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def _save_caption_multiple_formats(
|
|
352
|
+
caption: str,
|
|
353
|
+
base_filename: str,
|
|
354
|
+
figure_label: str = None,
|
|
355
|
+
style: str = "scientific",
|
|
356
|
+
save_txt: bool = True,
|
|
357
|
+
save_tex: bool = True,
|
|
358
|
+
save_md: bool = True,
|
|
359
|
+
wrap_width: int = 80
|
|
360
|
+
):
|
|
361
|
+
"""
|
|
362
|
+
Save caption in multiple formats (like how scitex saves CSV data).
|
|
363
|
+
|
|
364
|
+
Parameters
|
|
365
|
+
----------
|
|
366
|
+
caption : str
|
|
367
|
+
The caption text
|
|
368
|
+
base_filename : str
|
|
369
|
+
Base filename without extension
|
|
370
|
+
figure_label : str, optional
|
|
371
|
+
Figure label (auto-generated if None)
|
|
372
|
+
style : str, optional
|
|
373
|
+
Caption style, by default "scientific"
|
|
374
|
+
save_txt : bool, optional
|
|
375
|
+
Save as plain text, by default True
|
|
376
|
+
save_tex : bool, optional
|
|
377
|
+
Save as LaTeX, by default True
|
|
378
|
+
save_md : bool, optional
|
|
379
|
+
Save as Markdown, by default True
|
|
380
|
+
wrap_width : int, optional
|
|
381
|
+
Text wrapping width, by default 80
|
|
382
|
+
"""
|
|
383
|
+
# Generate figure label if not provided
|
|
384
|
+
if figure_label is None:
|
|
385
|
+
caption_manager.figure_counter += 1
|
|
386
|
+
figure_label = f"Figure {caption_manager.figure_counter}"
|
|
387
|
+
|
|
388
|
+
# Create formatted versions
|
|
389
|
+
txt_caption = _format_caption_for_txt(caption, figure_label, style, wrap_width)
|
|
390
|
+
tex_caption = _format_caption_for_tex(caption, figure_label, style, wrap_width)
|
|
391
|
+
md_caption = _format_caption_for_md(caption, figure_label, style, wrap_width)
|
|
392
|
+
|
|
393
|
+
# Save files (following scitex naming convention)
|
|
394
|
+
if save_txt:
|
|
395
|
+
txt_file = f"{base_filename}_caption.txt"
|
|
396
|
+
with open(txt_file, 'w', encoding='utf-8') as f:
|
|
397
|
+
f.write(txt_caption)
|
|
398
|
+
print(f"📝 Caption saved to: {txt_file}")
|
|
399
|
+
|
|
400
|
+
if save_tex:
|
|
401
|
+
tex_file = f"{base_filename}_caption.tex"
|
|
402
|
+
with open(tex_file, 'w', encoding='utf-8') as f:
|
|
403
|
+
f.write(tex_caption)
|
|
404
|
+
print(f"📝 LaTeX caption saved to: {tex_file}")
|
|
405
|
+
|
|
406
|
+
if save_md:
|
|
407
|
+
md_file = f"{base_filename}_caption.md"
|
|
408
|
+
with open(md_file, 'w', encoding='utf-8') as f:
|
|
409
|
+
f.write(md_caption)
|
|
410
|
+
print(f"📝 Markdown caption saved to: {md_file}")
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _format_caption_for_txt(caption: str, figure_label: str, style: str, wrap_width: int) -> str:
|
|
414
|
+
"""Format caption for plain text file."""
|
|
415
|
+
wrapped_text = textwrap.fill(caption, width=wrap_width)
|
|
416
|
+
|
|
417
|
+
if style == "scientific":
|
|
418
|
+
return f"{figure_label}. {wrapped_text}"
|
|
419
|
+
elif style == "nature":
|
|
420
|
+
return f"{figure_label} | {wrapped_text}"
|
|
421
|
+
elif style == "ieee":
|
|
422
|
+
return f"{figure_label}. {wrapped_text}"
|
|
423
|
+
elif style == "apa":
|
|
424
|
+
return f"{figure_label}\n{wrapped_text}"
|
|
425
|
+
else:
|
|
426
|
+
return f"{figure_label}. {wrapped_text}"
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def _format_caption_for_tex(caption: str, figure_label: str, style: str, wrap_width: int) -> str:
|
|
430
|
+
"""Format caption for LaTeX file."""
|
|
431
|
+
# Escape special LaTeX characters
|
|
432
|
+
tex_caption = _escape_latex(caption)
|
|
433
|
+
wrapped_text = textwrap.fill(tex_caption, width=wrap_width)
|
|
434
|
+
|
|
435
|
+
if style == "scientific":
|
|
436
|
+
latex_caption = f"""% {figure_label} caption
|
|
437
|
+
\\begin{{figure}}[htbp]
|
|
438
|
+
\\centering
|
|
439
|
+
% \\includegraphics{{figure_filename}}
|
|
440
|
+
\\caption{{\\textbf{{{figure_label}.}} {wrapped_text}}}
|
|
441
|
+
\\label{{fig:{figure_label.lower().replace(' ', '_')}}}
|
|
442
|
+
\\end{{figure}}
|
|
443
|
+
|
|
444
|
+
% For use in manuscript:
|
|
445
|
+
% \\textbf{{{figure_label}.}} {wrapped_text}
|
|
446
|
+
"""
|
|
447
|
+
elif style == "nature":
|
|
448
|
+
latex_caption = f"""% {figure_label} caption (Nature style)
|
|
449
|
+
\\begin{{figure}}[htbp]
|
|
450
|
+
\\centering
|
|
451
|
+
% \\includegraphics{{figure_filename}}
|
|
452
|
+
\\caption{{\\textbf{{{figure_label} |}} {wrapped_text}}}
|
|
453
|
+
\\label{{fig:{figure_label.lower().replace(' ', '_')}}}
|
|
454
|
+
\\end{{figure}}
|
|
455
|
+
"""
|
|
456
|
+
else:
|
|
457
|
+
latex_caption = f"""% {figure_label} caption
|
|
458
|
+
\\begin{{figure}}[htbp]
|
|
459
|
+
\\centering
|
|
460
|
+
% \\includegraphics{{figure_filename}}
|
|
461
|
+
\\caption{{{figure_label}. {wrapped_text}}}
|
|
462
|
+
\\label{{fig:{figure_label.lower().replace(' ', '_')}}}
|
|
463
|
+
\\end{{figure}}
|
|
464
|
+
"""
|
|
465
|
+
|
|
466
|
+
return latex_caption
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def _format_caption_for_md(caption: str, figure_label: str, style: str, wrap_width: int) -> str:
|
|
470
|
+
"""Format caption for Markdown file."""
|
|
471
|
+
wrapped_text = textwrap.fill(caption, width=wrap_width)
|
|
472
|
+
|
|
473
|
+
if style == "scientific":
|
|
474
|
+
return f"""# {figure_label}
|
|
475
|
+
|
|
476
|
+
**{figure_label}.** {wrapped_text}
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
*Generated by scitex scientific caption system*
|
|
481
|
+
"""
|
|
482
|
+
elif style == "nature":
|
|
483
|
+
return f"""# {figure_label}
|
|
484
|
+
|
|
485
|
+
**{figure_label} |** {wrapped_text}
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
*Generated by scitex scientific caption system*
|
|
490
|
+
"""
|
|
491
|
+
else:
|
|
492
|
+
return f"""# {figure_label}
|
|
493
|
+
|
|
494
|
+
{figure_label}. {wrapped_text}
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
*Generated by scitex scientific caption system*
|
|
499
|
+
"""
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def _escape_latex(text: str) -> str:
|
|
503
|
+
"""Escape special LaTeX characters."""
|
|
504
|
+
# Basic LaTeX character escaping
|
|
505
|
+
escapes = {
|
|
506
|
+
'&': r'\&',
|
|
507
|
+
'%': r'\%',
|
|
508
|
+
'$': r'\$',
|
|
509
|
+
'#': r'\#',
|
|
510
|
+
'^': r'\textasciicircum{}',
|
|
511
|
+
'_': r'\_',
|
|
512
|
+
'{': r'\{',
|
|
513
|
+
'}': r'\}',
|
|
514
|
+
'~': r'\textasciitilde{}',
|
|
515
|
+
'\\': r'\textbackslash{}'
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
result = text
|
|
519
|
+
for char, escape in escapes.items():
|
|
520
|
+
result = result.replace(char, escape)
|
|
521
|
+
|
|
522
|
+
return result
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
# Enhanced integration with scitex.io.save
|
|
526
|
+
def enhance_scitex_save_with_captions():
|
|
527
|
+
"""
|
|
528
|
+
Enhance the scitex.io.save system to automatically handle captions.
|
|
529
|
+
|
|
530
|
+
This can be called to monkey-patch scitex.io.save to include caption support.
|
|
531
|
+
"""
|
|
532
|
+
import scitex
|
|
533
|
+
|
|
534
|
+
# Store original save function
|
|
535
|
+
original_save = scitex.io.save
|
|
536
|
+
|
|
537
|
+
def enhanced_save(obj, filename, caption=None, **kwargs):
|
|
538
|
+
"""Enhanced save function with caption support."""
|
|
539
|
+
# Call original save
|
|
540
|
+
result = original_save(obj, filename, **kwargs)
|
|
541
|
+
|
|
542
|
+
# Handle captions if provided
|
|
543
|
+
if caption is not None and hasattr(obj, 'savefig'): # It's a figure
|
|
544
|
+
base_name = filename.split('.')[0]
|
|
545
|
+
_save_caption_multiple_formats(caption, base_name)
|
|
546
|
+
|
|
547
|
+
return result
|
|
548
|
+
|
|
549
|
+
# Replace the save function
|
|
550
|
+
scitex.io.save = enhanced_save
|
|
551
|
+
print("📝 scitex.io.save enhanced with caption support!")
|
|
552
|
+
print("Usage: scitex.io.save(fig, 'filename.png', caption='Your caption here')")
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
# Advanced caption utilities
|
|
556
|
+
def create_figure_list(output_file: str = "figure_list.txt", format: str = "txt"):
|
|
557
|
+
"""
|
|
558
|
+
Create a comprehensive list of all figures and their captions.
|
|
559
|
+
|
|
560
|
+
Parameters
|
|
561
|
+
----------
|
|
562
|
+
output_file : str, optional
|
|
563
|
+
Output filename, by default "figure_list.txt"
|
|
564
|
+
format : str, optional
|
|
565
|
+
Output format: "txt", "tex", "md", by default "txt"
|
|
566
|
+
"""
|
|
567
|
+
if not caption_manager.caption_registry:
|
|
568
|
+
print("No figures with captions found.")
|
|
569
|
+
return
|
|
570
|
+
|
|
571
|
+
if format == "tex":
|
|
572
|
+
_create_latex_figure_list(output_file)
|
|
573
|
+
elif format == "md":
|
|
574
|
+
_create_markdown_figure_list(output_file)
|
|
575
|
+
else:
|
|
576
|
+
_create_text_figure_list(output_file)
|
|
577
|
+
|
|
578
|
+
print(f"📋 Figure list saved to: {output_file}")
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
def _create_text_figure_list(output_file: str):
|
|
582
|
+
"""Create plain text figure list."""
|
|
583
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
584
|
+
f.write("Figure List\n")
|
|
585
|
+
f.write("=" * 50 + "\n\n")
|
|
586
|
+
|
|
587
|
+
for label, info in caption_manager.caption_registry.items():
|
|
588
|
+
f.write(f"{info['formatted']}\n\n")
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
def _create_latex_figure_list(output_file: str):
|
|
592
|
+
"""Create LaTeX figure list."""
|
|
593
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
594
|
+
f.write("% Figure List - Generated by scitex\n")
|
|
595
|
+
f.write("\\section{List of Figures}\n\n")
|
|
596
|
+
|
|
597
|
+
for label, info in caption_manager.caption_registry.items():
|
|
598
|
+
escaped_caption = _escape_latex(info['text'])
|
|
599
|
+
f.write(f"\\textbf{{{label}.}} {escaped_caption}\\\\\n\n")
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def _create_markdown_figure_list(output_file: str):
|
|
603
|
+
"""Create Markdown figure list."""
|
|
604
|
+
with open(output_file, 'w', encoding='utf-8') as f:
|
|
605
|
+
f.write("# Figure List\n\n")
|
|
606
|
+
f.write("*Generated by scitex scientific caption system*\n\n")
|
|
607
|
+
|
|
608
|
+
for label, info in caption_manager.caption_registry.items():
|
|
609
|
+
f.write(f"**{label}.** {info['text']}\n\n")
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
# Convenience function for quick caption addition
|
|
613
|
+
def quick_caption(fig, caption: str, save_path: str = None, **kwargs):
|
|
614
|
+
"""
|
|
615
|
+
Quick way to add caption and save all formats.
|
|
616
|
+
|
|
617
|
+
Parameters
|
|
618
|
+
----------
|
|
619
|
+
fig : matplotlib.figure.Figure
|
|
620
|
+
Figure to caption
|
|
621
|
+
caption : str
|
|
622
|
+
Caption text
|
|
623
|
+
save_path : str, optional
|
|
624
|
+
Base path for saving (uses figure number if None)
|
|
625
|
+
**kwargs
|
|
626
|
+
Additional arguments for caption formatting
|
|
627
|
+
"""
|
|
628
|
+
if save_path is None:
|
|
629
|
+
save_path = f"figure_{caption_manager.figure_counter + 1}"
|
|
630
|
+
|
|
631
|
+
# Save in all formats
|
|
632
|
+
_save_caption_multiple_formats(caption, save_path, **kwargs)
|
|
633
|
+
|
|
634
|
+
# Add visual caption to figure
|
|
635
|
+
return add_figure_caption(fig, caption, **kwargs)
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
# EOF
|