scitex 2.7.0__py3-none-any.whl → 2.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scitex/__init__.py +6 -2
- scitex/__version__.py +1 -1
- scitex/audio/README.md +52 -0
- scitex/audio/__init__.py +384 -0
- scitex/audio/__main__.py +129 -0
- scitex/audio/_tts.py +334 -0
- scitex/audio/engines/__init__.py +44 -0
- scitex/audio/engines/base.py +275 -0
- scitex/audio/engines/elevenlabs_engine.py +143 -0
- scitex/audio/engines/gtts_engine.py +162 -0
- scitex/audio/engines/pyttsx3_engine.py +131 -0
- scitex/audio/mcp_server.py +757 -0
- scitex/bridge/_helpers.py +1 -1
- scitex/bridge/_plt_vis.py +1 -1
- scitex/bridge/_stats_vis.py +1 -1
- scitex/dev/plt/__init__.py +272 -0
- scitex/dev/plt/plot_mpl_axhline.py +28 -0
- scitex/dev/plt/plot_mpl_axhspan.py +28 -0
- scitex/dev/plt/plot_mpl_axvline.py +28 -0
- scitex/dev/plt/plot_mpl_axvspan.py +28 -0
- scitex/dev/plt/plot_mpl_bar.py +29 -0
- scitex/dev/plt/plot_mpl_barh.py +29 -0
- scitex/dev/plt/plot_mpl_boxplot.py +28 -0
- scitex/dev/plt/plot_mpl_contour.py +31 -0
- scitex/dev/plt/plot_mpl_contourf.py +31 -0
- scitex/dev/plt/plot_mpl_errorbar.py +30 -0
- scitex/dev/plt/plot_mpl_eventplot.py +28 -0
- scitex/dev/plt/plot_mpl_fill.py +30 -0
- scitex/dev/plt/plot_mpl_fill_between.py +31 -0
- scitex/dev/plt/plot_mpl_hexbin.py +28 -0
- scitex/dev/plt/plot_mpl_hist.py +28 -0
- scitex/dev/plt/plot_mpl_hist2d.py +28 -0
- scitex/dev/plt/plot_mpl_imshow.py +29 -0
- scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
- scitex/dev/plt/plot_mpl_pie.py +29 -0
- scitex/dev/plt/plot_mpl_plot.py +29 -0
- scitex/dev/plt/plot_mpl_quiver.py +31 -0
- scitex/dev/plt/plot_mpl_scatter.py +28 -0
- scitex/dev/plt/plot_mpl_stackplot.py +31 -0
- scitex/dev/plt/plot_mpl_stem.py +29 -0
- scitex/dev/plt/plot_mpl_step.py +29 -0
- scitex/dev/plt/plot_mpl_violinplot.py +28 -0
- scitex/dev/plt/plot_sns_barplot.py +29 -0
- scitex/dev/plt/plot_sns_boxplot.py +29 -0
- scitex/dev/plt/plot_sns_heatmap.py +28 -0
- scitex/dev/plt/plot_sns_histplot.py +29 -0
- scitex/dev/plt/plot_sns_kdeplot.py +29 -0
- scitex/dev/plt/plot_sns_lineplot.py +31 -0
- scitex/dev/plt/plot_sns_scatterplot.py +29 -0
- scitex/dev/plt/plot_sns_stripplot.py +29 -0
- scitex/dev/plt/plot_sns_swarmplot.py +29 -0
- scitex/dev/plt/plot_sns_violinplot.py +29 -0
- scitex/dev/plt/plot_stx_bar.py +29 -0
- scitex/dev/plt/plot_stx_barh.py +29 -0
- scitex/dev/plt/plot_stx_box.py +28 -0
- scitex/dev/plt/plot_stx_boxplot.py +28 -0
- scitex/dev/plt/plot_stx_conf_mat.py +28 -0
- scitex/dev/plt/plot_stx_contour.py +31 -0
- scitex/dev/plt/plot_stx_ecdf.py +28 -0
- scitex/dev/plt/plot_stx_errorbar.py +30 -0
- scitex/dev/plt/plot_stx_fill_between.py +31 -0
- scitex/dev/plt/plot_stx_fillv.py +28 -0
- scitex/dev/plt/plot_stx_heatmap.py +28 -0
- scitex/dev/plt/plot_stx_image.py +28 -0
- scitex/dev/plt/plot_stx_imshow.py +28 -0
- scitex/dev/plt/plot_stx_joyplot.py +28 -0
- scitex/dev/plt/plot_stx_kde.py +28 -0
- scitex/dev/plt/plot_stx_line.py +28 -0
- scitex/dev/plt/plot_stx_mean_ci.py +28 -0
- scitex/dev/plt/plot_stx_mean_std.py +28 -0
- scitex/dev/plt/plot_stx_median_iqr.py +28 -0
- scitex/dev/plt/plot_stx_raster.py +28 -0
- scitex/dev/plt/plot_stx_rectangle.py +28 -0
- scitex/dev/plt/plot_stx_scatter.py +29 -0
- scitex/dev/plt/plot_stx_shaded_line.py +29 -0
- scitex/dev/plt/plot_stx_violin.py +28 -0
- scitex/dev/plt/plot_stx_violinplot.py +28 -0
- scitex/diagram/README.md +197 -0
- scitex/diagram/__init__.py +48 -0
- scitex/diagram/_compile.py +312 -0
- scitex/diagram/_diagram.py +355 -0
- scitex/diagram/_presets.py +173 -0
- scitex/diagram/_schema.py +182 -0
- scitex/diagram/_split.py +278 -0
- scitex/fig/__init__.py +352 -0
- scitex/{vis → fig}/backend/_parser.py +1 -1
- scitex/{vis → fig}/canvas.py +1 -1
- scitex/{vis → fig}/editor/__init__.py +5 -2
- scitex/{vis → fig}/editor/_dearpygui_editor.py +1 -1
- scitex/{vis → fig}/editor/_defaults.py +70 -5
- scitex/{vis → fig}/editor/_mpl_editor.py +1 -1
- scitex/{vis → fig}/editor/_qt_editor.py +182 -2
- scitex/{vis → fig}/editor/_tkinter_editor.py +1 -1
- scitex/fig/editor/edit/__init__.py +50 -0
- scitex/fig/editor/edit/backend_detector.py +109 -0
- scitex/fig/editor/edit/bundle_resolver.py +240 -0
- scitex/fig/editor/edit/editor_launcher.py +239 -0
- scitex/fig/editor/edit/manual_handler.py +53 -0
- scitex/fig/editor/edit/panel_loader.py +232 -0
- scitex/fig/editor/edit/path_resolver.py +67 -0
- scitex/fig/editor/flask_editor/_bbox.py +1299 -0
- scitex/fig/editor/flask_editor/_core.py +1429 -0
- scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
- scitex/fig/editor/flask_editor/_renderer.py +813 -0
- scitex/fig/editor/flask_editor/static/css/base/reset.css +41 -0
- scitex/fig/editor/flask_editor/static/css/base/typography.css +16 -0
- scitex/fig/editor/flask_editor/static/css/base/variables.css +85 -0
- scitex/fig/editor/flask_editor/static/css/components/buttons.css +217 -0
- scitex/fig/editor/flask_editor/static/css/components/context-menu.css +93 -0
- scitex/fig/editor/flask_editor/static/css/components/dropdown.css +57 -0
- scitex/fig/editor/flask_editor/static/css/components/forms.css +112 -0
- scitex/fig/editor/flask_editor/static/css/components/modal.css +59 -0
- scitex/fig/editor/flask_editor/static/css/components/sections.css +212 -0
- scitex/fig/editor/flask_editor/static/css/features/canvas.css +176 -0
- scitex/fig/editor/flask_editor/static/css/features/element-inspector.css +190 -0
- scitex/fig/editor/flask_editor/static/css/features/loading.css +59 -0
- scitex/fig/editor/flask_editor/static/css/features/overlay.css +45 -0
- scitex/fig/editor/flask_editor/static/css/features/panel-grid.css +95 -0
- scitex/fig/editor/flask_editor/static/css/features/selection.css +101 -0
- scitex/fig/editor/flask_editor/static/css/features/statistics.css +138 -0
- scitex/fig/editor/flask_editor/static/css/index.css +31 -0
- scitex/fig/editor/flask_editor/static/css/layout/container.css +7 -0
- scitex/fig/editor/flask_editor/static/css/layout/controls.css +56 -0
- scitex/fig/editor/flask_editor/static/css/layout/preview.css +78 -0
- scitex/fig/editor/flask_editor/static/js/alignment/axis.js +314 -0
- scitex/fig/editor/flask_editor/static/js/alignment/basic.js +107 -0
- scitex/fig/editor/flask_editor/static/js/alignment/distribute.js +54 -0
- scitex/fig/editor/flask_editor/static/js/canvas/canvas.js +172 -0
- scitex/fig/editor/flask_editor/static/js/canvas/dragging.js +258 -0
- scitex/fig/editor/flask_editor/static/js/canvas/resize.js +48 -0
- scitex/fig/editor/flask_editor/static/js/canvas/selection.js +71 -0
- scitex/fig/editor/flask_editor/static/js/core/api.js +288 -0
- scitex/fig/editor/flask_editor/static/js/core/state.js +143 -0
- scitex/fig/editor/flask_editor/static/js/core/utils.js +245 -0
- scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js +992 -0
- scitex/fig/editor/flask_editor/static/js/editor/bbox.js +339 -0
- scitex/fig/editor/flask_editor/static/js/editor/element-drag.js +286 -0
- scitex/fig/editor/flask_editor/static/js/editor/overlay.js +371 -0
- scitex/fig/editor/flask_editor/static/js/editor/preview.js +293 -0
- scitex/fig/editor/flask_editor/static/js/main.js +426 -0
- scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js +152 -0
- scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js +265 -0
- scitex/fig/editor/flask_editor/static/js/ui/controls.js +184 -0
- scitex/fig/editor/flask_editor/static/js/ui/download.js +57 -0
- scitex/fig/editor/flask_editor/static/js/ui/help.js +100 -0
- scitex/fig/editor/flask_editor/static/js/ui/theme.js +34 -0
- scitex/fig/editor/flask_editor/templates/__init__.py +123 -0
- scitex/fig/editor/flask_editor/templates/_html.py +852 -0
- scitex/fig/editor/flask_editor/templates/_scripts.py +4933 -0
- scitex/fig/editor/flask_editor/templates/_styles.py +1658 -0
- scitex/{vis → fig}/io/__init__.py +13 -1
- scitex/fig/io/_bundle.py +1058 -0
- scitex/{vis → fig}/io/_canvas.py +1 -1
- scitex/{vis → fig}/io/_data.py +1 -1
- scitex/{vis → fig}/io/_export.py +1 -1
- scitex/{vis → fig}/io/_load.py +1 -1
- scitex/{vis → fig}/io/_panel.py +1 -1
- scitex/{vis → fig}/io/_save.py +1 -1
- scitex/{vis → fig}/model/__init__.py +1 -1
- scitex/{vis → fig}/model/_annotations.py +1 -1
- scitex/{vis → fig}/model/_axes.py +1 -1
- scitex/{vis → fig}/model/_figure.py +1 -1
- scitex/{vis → fig}/model/_guides.py +1 -1
- scitex/{vis → fig}/model/_plot.py +1 -1
- scitex/{vis → fig}/model/_styles.py +1 -1
- scitex/{vis → fig}/utils/__init__.py +1 -1
- scitex/io/__init__.py +22 -26
- scitex/io/_bundle.py +493 -0
- scitex/io/_flush.py +5 -2
- scitex/io/_load.py +98 -0
- scitex/io/_load_modules/_H5Explorer.py +5 -2
- scitex/io/_load_modules/_canvas.py +2 -2
- scitex/io/_load_modules/_image.py +3 -4
- scitex/io/_load_modules/_txt.py +4 -2
- scitex/io/_metadata.py +34 -324
- scitex/io/_metadata_modules/__init__.py +46 -0
- scitex/io/_metadata_modules/_embed.py +70 -0
- scitex/io/_metadata_modules/_read.py +64 -0
- scitex/io/_metadata_modules/_utils.py +79 -0
- scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
- scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
- scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
- scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
- scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
- scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
- scitex/io/_metadata_modules/read_metadata_png.py +39 -0
- scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
- scitex/io/_qr_utils.py +5 -3
- scitex/io/_save.py +548 -30
- scitex/io/_save_modules/_canvas.py +3 -3
- scitex/io/_save_modules/_image.py +5 -9
- scitex/io/_save_modules/_tex.py +7 -4
- scitex/io/_zip_bundle.py +439 -0
- scitex/io/utils/h5_to_zarr.py +11 -9
- scitex/msword/__init__.py +255 -0
- scitex/msword/profiles.py +357 -0
- scitex/msword/reader.py +753 -0
- scitex/msword/utils.py +289 -0
- scitex/msword/writer.py +362 -0
- scitex/plt/__init__.py +5 -2
- scitex/plt/_subplots/_AxesWrapper.py +6 -6
- scitex/plt/_subplots/_AxisWrapper.py +15 -9
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
- scitex/plt/_subplots/_FigWrapper.py +6 -6
- scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
- scitex/plt/_subplots/_export_as_csv.py +35 -5
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
- scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
- scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
- scitex/plt/gallery/_generate.py +421 -14
- scitex/plt/io/__init__.py +53 -0
- scitex/plt/io/_bundle.py +490 -0
- scitex/plt/io/_layered_bundle.py +1343 -0
- scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
- scitex/plt/styles/__init__.py +14 -0
- scitex/plt/styles/presets.py +78 -0
- scitex/plt/utils/__init__.py +13 -1
- scitex/plt/utils/_collect_figure_metadata.py +10 -14
- scitex/plt/utils/_configure_mpl.py +6 -18
- scitex/plt/utils/_crop.py +32 -14
- scitex/plt/utils/_csv_column_naming.py +54 -0
- scitex/plt/utils/_figure_mm.py +116 -1
- scitex/plt/utils/_hitmap.py +1643 -0
- scitex/plt/utils/metadata/__init__.py +25 -0
- scitex/plt/utils/metadata/_core.py +9 -10
- scitex/plt/utils/metadata/_dimensions.py +6 -3
- scitex/plt/utils/metadata/_editable_export.py +405 -0
- scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
- scitex/schema/__init__.py +109 -16
- scitex/schema/_canvas.py +1 -1
- scitex/schema/_plot.py +1015 -0
- scitex/schema/_stats.py +2 -2
- scitex/stats/__init__.py +117 -0
- scitex/stats/io/__init__.py +29 -0
- scitex/stats/io/_bundle.py +156 -0
- scitex/tex/__init__.py +4 -0
- scitex/tex/_export.py +890 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/METADATA +11 -1
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/RECORD +294 -170
- scitex/io/memo.md +0 -2827
- scitex/plt/REQUESTS.md +0 -191
- scitex/plt/_subplots/TODO.md +0 -53
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
- scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
- scitex/vis/__init__.py +0 -177
- scitex/vis/editor/_edit.py +0 -390
- scitex/vis/editor/flask_editor/_bbox.py +0 -529
- scitex/vis/editor/flask_editor/_core.py +0 -168
- scitex/vis/editor/flask_editor/_renderer.py +0 -393
- scitex/vis/editor/flask_editor/templates/__init__.py +0 -33
- scitex/vis/editor/flask_editor/templates/_html.py +0 -513
- scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
- scitex/vis/editor/flask_editor/templates/_styles.py +0 -739
- /scitex/{vis → fig}/README.md +0 -0
- /scitex/{vis → fig}/backend/__init__.py +0 -0
- /scitex/{vis → fig}/backend/_export.py +0 -0
- /scitex/{vis → fig}/backend/_render.py +0 -0
- /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
- /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
- /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
- /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
- /scitex/{vis → fig}/io/_directory.py +0 -0
- /scitex/{vis → fig}/model/_plot_types.py +0 -0
- /scitex/{vis → fig}/utils/_defaults.py +0 -0
- /scitex/{vis → fig}/utils/_validate.py +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/WHEEL +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/entry_points.txt +0 -0
- {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-12-11 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/audio/engines/elevenlabs_engine.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
ElevenLabs TTS backend - High quality, requires API key and payment.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import List, Optional
|
|
16
|
+
|
|
17
|
+
from .base import BaseTTS
|
|
18
|
+
|
|
19
|
+
__all__ = ["ElevenLabsTTS"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ElevenLabsTTS(BaseTTS):
|
|
23
|
+
"""ElevenLabs TTS backend.
|
|
24
|
+
|
|
25
|
+
High-quality voices but requires API key and has usage costs.
|
|
26
|
+
|
|
27
|
+
Environment:
|
|
28
|
+
ELEVENLABS_API_KEY: Your ElevenLabs API key
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
VOICES = {
|
|
32
|
+
"rachel": "21m00Tcm4TlvDq8ikWAM",
|
|
33
|
+
"adam": "pNInz6obpgDQGcFmaJgB",
|
|
34
|
+
"antoni": "ErXwobaYiN019PkySvjV",
|
|
35
|
+
"bella": "EXAVITQu4vr4xnSDxMaL",
|
|
36
|
+
"domi": "AZnzlk1XvdvUeBnXmlld",
|
|
37
|
+
"elli": "MF3mGyEYCl7XYWbV9V6O",
|
|
38
|
+
"josh": "TxGEqnHWrfWFTfGW9XjX",
|
|
39
|
+
"sam": "yoZ06aMxZJJ28mfd3POQ",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
api_key: Optional[str] = None,
|
|
45
|
+
voice: str = "rachel",
|
|
46
|
+
model_id: str = "eleven_multilingual_v2",
|
|
47
|
+
stability: float = 0.5,
|
|
48
|
+
similarity_boost: float = 0.75,
|
|
49
|
+
speed: float = 1.0,
|
|
50
|
+
**kwargs,
|
|
51
|
+
):
|
|
52
|
+
super().__init__(**kwargs)
|
|
53
|
+
self.api_key = api_key or os.environ.get("ELEVENLABS_API_KEY")
|
|
54
|
+
self.voice = voice
|
|
55
|
+
self.model_id = model_id
|
|
56
|
+
self.stability = stability
|
|
57
|
+
self.similarity_boost = similarity_boost
|
|
58
|
+
self.speed = speed
|
|
59
|
+
self._client = None
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def name(self) -> str:
|
|
63
|
+
return "elevenlabs"
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def requires_api_key(self) -> bool:
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def requires_internet(self) -> bool:
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def client(self):
|
|
75
|
+
"""Lazy-load ElevenLabs client."""
|
|
76
|
+
if self._client is None:
|
|
77
|
+
try:
|
|
78
|
+
from elevenlabs.client import ElevenLabs
|
|
79
|
+
|
|
80
|
+
self._client = ElevenLabs(api_key=self.api_key)
|
|
81
|
+
except ImportError:
|
|
82
|
+
raise ImportError(
|
|
83
|
+
"elevenlabs package not installed. "
|
|
84
|
+
"Install with: pip install elevenlabs"
|
|
85
|
+
)
|
|
86
|
+
return self._client
|
|
87
|
+
|
|
88
|
+
def _get_voice_id(self, voice: Optional[str] = None) -> str:
|
|
89
|
+
"""Get voice ID from name or return as-is if already an ID."""
|
|
90
|
+
v = voice or self.voice
|
|
91
|
+
normalized = v.lower()
|
|
92
|
+
return self.VOICES.get(normalized, v)
|
|
93
|
+
|
|
94
|
+
def synthesize(self, text: str, output_path: str) -> Path:
|
|
95
|
+
"""Synthesize text using ElevenLabs API."""
|
|
96
|
+
voice_id = self._get_voice_id(self.config.get("voice"))
|
|
97
|
+
|
|
98
|
+
audio = self.client.text_to_speech.convert(
|
|
99
|
+
text=text,
|
|
100
|
+
voice_id=voice_id,
|
|
101
|
+
model_id=self.model_id,
|
|
102
|
+
voice_settings={
|
|
103
|
+
"stability": self.stability,
|
|
104
|
+
"similarity_boost": self.similarity_boost,
|
|
105
|
+
"speed": self.speed,
|
|
106
|
+
},
|
|
107
|
+
output_format="mp3_44100_128",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
out_path = Path(output_path)
|
|
111
|
+
with open(out_path, "wb") as f:
|
|
112
|
+
for chunk in audio:
|
|
113
|
+
f.write(chunk)
|
|
114
|
+
|
|
115
|
+
return out_path
|
|
116
|
+
|
|
117
|
+
def get_voices(self) -> List[dict]:
|
|
118
|
+
"""Get available voices."""
|
|
119
|
+
# Start with preset voices
|
|
120
|
+
voices = [
|
|
121
|
+
{"name": name, "id": vid, "type": "preset"}
|
|
122
|
+
for name, vid in self.VOICES.items()
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
# Try to get custom voices
|
|
126
|
+
try:
|
|
127
|
+
response = self.client.voices.get_all()
|
|
128
|
+
for v in response.voices:
|
|
129
|
+
voices.append(
|
|
130
|
+
{
|
|
131
|
+
"name": v.name,
|
|
132
|
+
"id": v.voice_id,
|
|
133
|
+
"type": "custom",
|
|
134
|
+
"labels": v.labels,
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
except Exception:
|
|
138
|
+
pass
|
|
139
|
+
|
|
140
|
+
return voices
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# EOF
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-12-11 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/audio/engines/gtts_engine.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
Google Text-to-Speech (gTTS) backend - Free, requires internet.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import io
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import List, Optional
|
|
16
|
+
|
|
17
|
+
from .base import BaseTTS
|
|
18
|
+
|
|
19
|
+
__all__ = ["GoogleTTS"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GoogleTTS(BaseTTS):
|
|
23
|
+
"""Google Text-to-Speech backend using gTTS.
|
|
24
|
+
|
|
25
|
+
Free to use, requires internet connection.
|
|
26
|
+
Good quality voices with multi-language support.
|
|
27
|
+
Supports speed control via pydub (requires ffmpeg).
|
|
28
|
+
|
|
29
|
+
Install: pip install gTTS pydub
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# Supported languages (subset of most common)
|
|
33
|
+
LANGUAGES = {
|
|
34
|
+
"en": "English",
|
|
35
|
+
"es": "Spanish",
|
|
36
|
+
"fr": "French",
|
|
37
|
+
"de": "German",
|
|
38
|
+
"it": "Italian",
|
|
39
|
+
"pt": "Portuguese",
|
|
40
|
+
"ru": "Russian",
|
|
41
|
+
"ja": "Japanese",
|
|
42
|
+
"ko": "Korean",
|
|
43
|
+
"zh-CN": "Chinese (Simplified)",
|
|
44
|
+
"zh-TW": "Chinese (Traditional)",
|
|
45
|
+
"ar": "Arabic",
|
|
46
|
+
"hi": "Hindi",
|
|
47
|
+
"nl": "Dutch",
|
|
48
|
+
"pl": "Polish",
|
|
49
|
+
"sv": "Swedish",
|
|
50
|
+
"tr": "Turkish",
|
|
51
|
+
"vi": "Vietnamese",
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
lang: str = "en",
|
|
57
|
+
slow: bool = False,
|
|
58
|
+
speed: float = 1.5,
|
|
59
|
+
**kwargs,
|
|
60
|
+
):
|
|
61
|
+
super().__init__(**kwargs)
|
|
62
|
+
self.lang = lang
|
|
63
|
+
self.slow = slow
|
|
64
|
+
self.speed = speed # 1.0 = normal, >1.0 = faster, <1.0 = slower
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def name(self) -> str:
|
|
68
|
+
return "gtts"
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def requires_internet(self) -> bool:
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
def synthesize(self, text: str, output_path: str) -> Path:
|
|
75
|
+
"""Synthesize text using Google TTS with optional speed control."""
|
|
76
|
+
try:
|
|
77
|
+
from gtts import gTTS
|
|
78
|
+
except ImportError:
|
|
79
|
+
raise ImportError(
|
|
80
|
+
"gTTS package not installed. Install with: pip install gTTS"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Get language from config or use default
|
|
84
|
+
lang = self.config.get("voice", self.lang)
|
|
85
|
+
if lang in self.LANGUAGES:
|
|
86
|
+
pass # Valid language code
|
|
87
|
+
elif lang.lower() in [l.lower() for l in self.LANGUAGES.values()]:
|
|
88
|
+
# Convert language name to code
|
|
89
|
+
for code, name in self.LANGUAGES.items():
|
|
90
|
+
if name.lower() == lang.lower():
|
|
91
|
+
lang = code
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
# Get speed from config or use instance default
|
|
95
|
+
speed = self.config.get("speed", self.speed)
|
|
96
|
+
|
|
97
|
+
out_path = Path(output_path)
|
|
98
|
+
|
|
99
|
+
if speed != 1.0:
|
|
100
|
+
# Use pydub for speed control
|
|
101
|
+
audio_data = self._synthesize_with_speed(text, lang, speed)
|
|
102
|
+
audio_data.export(str(out_path), format="mp3")
|
|
103
|
+
else:
|
|
104
|
+
# Direct save without speed modification
|
|
105
|
+
tts = gTTS(text=text, lang=lang, slow=self.slow)
|
|
106
|
+
tts.save(str(out_path))
|
|
107
|
+
|
|
108
|
+
return out_path
|
|
109
|
+
|
|
110
|
+
def _synthesize_with_speed(self, text: str, lang: str, speed: float):
|
|
111
|
+
"""Synthesize with speed control using pydub.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
text: Text to synthesize.
|
|
115
|
+
lang: Language code.
|
|
116
|
+
speed: Speed multiplier (>1.0 faster, <1.0 slower).
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
AudioSegment with adjusted speed.
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
from gtts import gTTS
|
|
123
|
+
from pydub import AudioSegment
|
|
124
|
+
except ImportError as e:
|
|
125
|
+
raise ImportError(
|
|
126
|
+
"pydub package required for speed control. "
|
|
127
|
+
"Install with: pip install pydub"
|
|
128
|
+
) from e
|
|
129
|
+
|
|
130
|
+
# Generate speech to memory buffer
|
|
131
|
+
with io.BytesIO() as buffer:
|
|
132
|
+
gTTS(text=text, lang=lang, slow=self.slow).write_to_fp(buffer)
|
|
133
|
+
buffer.seek(0)
|
|
134
|
+
sound = AudioSegment.from_file(buffer, format="mp3")
|
|
135
|
+
|
|
136
|
+
# Apply speed adjustment
|
|
137
|
+
if speed > 1.0:
|
|
138
|
+
# speedup() for faster playback
|
|
139
|
+
sound = sound.speedup(
|
|
140
|
+
playback_speed=speed,
|
|
141
|
+
chunk_size=150,
|
|
142
|
+
crossfade=25
|
|
143
|
+
)
|
|
144
|
+
elif speed < 1.0:
|
|
145
|
+
# For slower playback, adjust frame rate
|
|
146
|
+
new_frame_rate = int(sound.frame_rate * speed)
|
|
147
|
+
sound = sound._spawn(
|
|
148
|
+
sound.raw_data,
|
|
149
|
+
overrides={"frame_rate": new_frame_rate}
|
|
150
|
+
).set_frame_rate(sound.frame_rate)
|
|
151
|
+
|
|
152
|
+
return sound
|
|
153
|
+
|
|
154
|
+
def get_voices(self) -> List[dict]:
|
|
155
|
+
"""Get available languages as 'voices'."""
|
|
156
|
+
return [
|
|
157
|
+
{"name": name, "id": code, "type": "language"}
|
|
158
|
+
for code, name in self.LANGUAGES.items()
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# EOF
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-12-11 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/audio/engines/pyttsx3_engine.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
System TTS backend using pyttsx3 - Offline, uses system voices.
|
|
9
|
+
|
|
10
|
+
Requirements:
|
|
11
|
+
- pip install pyttsx3
|
|
12
|
+
- Linux: sudo apt install espeak-ng libespeak1
|
|
13
|
+
- Windows: Uses SAPI5 (built-in)
|
|
14
|
+
- macOS: Uses NSSpeechSynthesizer (built-in)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import List, Optional
|
|
21
|
+
|
|
22
|
+
from .base import BaseTTS
|
|
23
|
+
|
|
24
|
+
__all__ = ["SystemTTS"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SystemTTS(BaseTTS):
|
|
28
|
+
"""System TTS backend using pyttsx3.
|
|
29
|
+
|
|
30
|
+
Works offline using system's built-in TTS engine.
|
|
31
|
+
Quality varies by platform and available voices.
|
|
32
|
+
|
|
33
|
+
Platforms:
|
|
34
|
+
- Linux: espeak/espeak-ng
|
|
35
|
+
- Windows: SAPI5
|
|
36
|
+
- macOS: NSSpeechSynthesizer
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
rate: int = 150, # Words per minute
|
|
42
|
+
volume: float = 1.0, # 0.0 to 1.0
|
|
43
|
+
voice: Optional[str] = None,
|
|
44
|
+
**kwargs,
|
|
45
|
+
):
|
|
46
|
+
super().__init__(**kwargs)
|
|
47
|
+
self.rate = rate
|
|
48
|
+
self.volume = volume
|
|
49
|
+
self.voice = voice
|
|
50
|
+
self._engine = None
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def name(self) -> str:
|
|
54
|
+
return "pyttsx3"
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def engine(self):
|
|
58
|
+
"""Lazy-load pyttsx3 engine."""
|
|
59
|
+
if self._engine is None:
|
|
60
|
+
try:
|
|
61
|
+
import pyttsx3
|
|
62
|
+
|
|
63
|
+
self._engine = pyttsx3.init()
|
|
64
|
+
self._engine.setProperty("rate", self.rate)
|
|
65
|
+
self._engine.setProperty("volume", self.volume)
|
|
66
|
+
|
|
67
|
+
if self.voice:
|
|
68
|
+
self._set_voice(self.voice)
|
|
69
|
+
except ImportError:
|
|
70
|
+
raise ImportError(
|
|
71
|
+
"pyttsx3 package not installed. "
|
|
72
|
+
"Install with: pip install pyttsx3\n"
|
|
73
|
+
"Linux also requires: sudo apt install espeak-ng libespeak1"
|
|
74
|
+
)
|
|
75
|
+
except RuntimeError as e:
|
|
76
|
+
if "eSpeak" in str(e):
|
|
77
|
+
raise RuntimeError(
|
|
78
|
+
"espeak not installed. "
|
|
79
|
+
"Install with: sudo apt install espeak-ng libespeak1"
|
|
80
|
+
)
|
|
81
|
+
raise
|
|
82
|
+
return self._engine
|
|
83
|
+
|
|
84
|
+
def _set_voice(self, voice_name: str):
|
|
85
|
+
"""Set voice by name or ID."""
|
|
86
|
+
voices = self.engine.getProperty("voices")
|
|
87
|
+
for v in voices:
|
|
88
|
+
if voice_name.lower() in v.name.lower() or voice_name == v.id:
|
|
89
|
+
self.engine.setProperty("voice", v.id)
|
|
90
|
+
return
|
|
91
|
+
# If not found, keep default
|
|
92
|
+
|
|
93
|
+
def synthesize(self, text: str, output_path: str) -> Path:
|
|
94
|
+
"""Synthesize text using system TTS."""
|
|
95
|
+
# Set voice if specified in config
|
|
96
|
+
voice = self.config.get("voice")
|
|
97
|
+
if voice:
|
|
98
|
+
self._set_voice(voice)
|
|
99
|
+
|
|
100
|
+
out_path = Path(output_path)
|
|
101
|
+
|
|
102
|
+
# pyttsx3 can save to file
|
|
103
|
+
self.engine.save_to_file(text, str(out_path))
|
|
104
|
+
self.engine.runAndWait()
|
|
105
|
+
|
|
106
|
+
return out_path
|
|
107
|
+
|
|
108
|
+
def speak_direct(self, text: str):
|
|
109
|
+
"""Speak directly without saving to file (faster)."""
|
|
110
|
+
voice = self.config.get("voice")
|
|
111
|
+
if voice:
|
|
112
|
+
self._set_voice(voice)
|
|
113
|
+
|
|
114
|
+
self.engine.say(text)
|
|
115
|
+
self.engine.runAndWait()
|
|
116
|
+
|
|
117
|
+
def get_voices(self) -> List[dict]:
|
|
118
|
+
"""Get available system voices."""
|
|
119
|
+
voices = self.engine.getProperty("voices")
|
|
120
|
+
return [
|
|
121
|
+
{
|
|
122
|
+
"name": v.name,
|
|
123
|
+
"id": v.id,
|
|
124
|
+
"type": "system",
|
|
125
|
+
"languages": getattr(v, "languages", []),
|
|
126
|
+
}
|
|
127
|
+
for v in voices
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# EOF
|