scitex 2.10.3__py3-none-any.whl → 2.11.0__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 +1 -4
- scitex/__version__.py +1 -1
- scitex/_install_guide.py +14 -2
- scitex/bridge/_figrecipe.py +1 -1
- scitex/bridge/_helpers.py +1 -1
- scitex/bridge/_plt_vis.py +1 -1
- scitex/bridge/_stats_plt.py +1 -1
- scitex/bridge/_stats_vis.py +2 -2
- scitex/{fig → canvas}/__init__.py +84 -96
- scitex/{fig → canvas}/backend/_parser.py +1 -1
- scitex/{fig → canvas}/canvas.py +13 -14
- scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
- scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
- scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
- scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
- scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
- scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
- scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
- scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
- scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
- scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
- scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
- scitex/{fig → canvas}/io/__init__.py +32 -38
- scitex/{fig → canvas}/io/_bundle.py +217 -154
- scitex/{fig → canvas}/io/_canvas.py +1 -1
- scitex/{fig → canvas}/io/_data.py +1 -1
- scitex/{fig → canvas}/io/_export.py +1 -1
- scitex/{fig → canvas}/io/_load.py +1 -1
- scitex/{fig → canvas}/io/_panel.py +1 -1
- scitex/{fig → canvas}/io/_save.py +1 -1
- scitex/{fig → canvas}/model/__init__.py +1 -1
- scitex/{fig → canvas}/model/_annotations.py +1 -1
- scitex/{fig → canvas}/model/_axes.py +1 -1
- scitex/{fig → canvas}/model/_figure.py +1 -1
- scitex/{fig → canvas}/model/_guides.py +1 -1
- scitex/{fig → canvas}/model/_plot.py +1 -1
- scitex/{fig → canvas}/model/_styles.py +1 -1
- scitex/{fig → canvas}/utils/__init__.py +1 -1
- scitex/cli/convert.py +10 -6
- scitex/diagram/README.md +7 -7
- scitex/io/__init__.py +7 -19
- scitex/io/_load.py +15 -19
- scitex/io/_load_modules/_canvas.py +2 -2
- scitex/io/_load_modules/_con.py +5 -5
- scitex/io/_load_modules/_eeg.py +16 -12
- scitex/io/_save.py +11 -16
- scitex/io/_save_modules/__init__.py +6 -10
- scitex/io/_save_modules/_canvas.py +3 -3
- scitex/io/_save_modules/_plot_bundle.py +112 -0
- scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
- scitex/io/_save_modules/_stx_bundle.py +16 -16
- scitex/io/bundle/README.md +89 -80
- scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
- scitex/io/bundle/__init__.py +67 -35
- scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
- scitex/io/bundle/_core.py +184 -97
- scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
- scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
- scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
- scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
- scitex/io/bundle/_manifest.py +99 -0
- scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
- scitex/io/bundle/_nested.py +113 -100
- scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
- scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
- scitex/io/bundle/_types.py +41 -16
- scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
- scitex/io/bundle/_zip.py +21 -31
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
- scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
- scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
- scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
- scitex/io/bundle/schemas/__init__.py +30 -0
- scitex/parallel/_run.py +5 -4
- scitex/path/_find.py +60 -83
- scitex/path/_get_module_path.py +23 -21
- scitex/path/_get_spath.py +6 -27
- scitex/path/_getsize.py +23 -9
- scitex/path/_increment_version.py +31 -38
- scitex/path/_mk_spath.py +26 -29
- scitex/path/_path.py +5 -12
- scitex/path/_split.py +27 -15
- scitex/path/_this_path.py +23 -9
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
- scitex/plt/gallery/_generate.py +76 -50
- scitex/plt/io/__init__.py +17 -19
- scitex/plt/io/_bundle.py +99 -52
- scitex/plt/io/_layered_bundle.py +303 -168
- scitex/plt/utils/_csv_column_naming.py +250 -118
- scitex/schema/__init__.py +69 -73
- scitex/schema/_canvas.py +1 -1
- scitex/schema/_stats.py +2 -2
- scitex/stats/__init__.py +30 -33
- scitex/stats/_schema.py +1 -1
- scitex/stats/io/__init__.py +10 -11
- scitex/stats/io/_bundle.py +16 -16
- {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/METADATA +190 -73
- {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/RECORD +237 -360
- scitex/fig/editor/_defaults.py +0 -300
- scitex/fig/editor/edit/panel_loader.py +0 -232
- scitex/fig/editor/flask_editor/_bbox.py +0 -1299
- scitex/fig/editor/flask_editor/_core.py +0 -1429
- scitex/fig/editor/flask_editor/_renderer.py +0 -813
- scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
- scitex/fts/README.md +0 -262
- scitex/fts/TODO.md +0 -66
- scitex/fts/__init__.py +0 -90
- scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
- scitex/fts/_bundle/__init__.py +0 -38
- scitex/fts/_bundle/_utils/__init__.py +0 -55
- scitex/fts/_bundle/_utils/_const.py +0 -26
- scitex/fts/_bundle/_utils/_errors.py +0 -73
- scitex/fts/_bundle/_utils/_generate.py +0 -21
- scitex/fts/_bundle/_utils/_types.py +0 -76
- scitex/fts/_bundle/_zipbundle.py +0 -165
- scitex/fts/_fig/__init__.py +0 -22
- scitex/fts/_fig/_backend/_parser.py +0 -188
- scitex/fts/_fig/_editor/__init__.py +0 -14
- scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
- scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
- scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
- scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
- scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
- scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
- scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
- scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
- scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
- scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
- scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
- scitex/fts/_fig/_models/_Annotations.py +0 -115
- scitex/fts/_fig/_models/_Axes.py +0 -152
- scitex/fts/_fig/_models/_Figure.py +0 -138
- scitex/fts/_fig/_models/_Plot.py +0 -123
- scitex/fts/_fig/_utils/_plot_layout.py +0 -397
- scitex/fts/_kinds/_figure/_composite.py +0 -345
- scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
- scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
- scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
- scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
- scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
- scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
- scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
- scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
- scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
- scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
- scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
- scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
- scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
- scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
- scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
- scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
- scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
- scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
- scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
- scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
- scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
- scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
- scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
- scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
- scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
- scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
- scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
- scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
- scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
- scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
- scitex/fts/_kinds/_table/_latex/_export.py +0 -279
- scitex/fts/_stats/__init__.py +0 -48
- scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
- scitex/fts/_stats/_dataclasses/__init__.py +0 -48
- scitex/fts/_tables/__init__.py +0 -65
- scitex/fts/_tables/_latex/__init__.py +0 -93
- scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
- scitex/fts/_tables/_latex/_editor/_app.py +0 -725
- scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
- scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
- scitex/fts/_tables/_latex/_table_exporter.py +0 -362
- scitex/fts/_tables/_latex/_utils.py +0 -369
- scitex/fts/_tables/_latex/_validator.py +0 -445
- scitex/io/_save_modules/_pltz_bundle.py +0 -356
- /scitex/{fig → canvas}/README.md +0 -0
- /scitex/{fig → canvas}/backend/__init__.py +0 -0
- /scitex/{fig → canvas}/backend/_export.py +0 -0
- /scitex/{fig → canvas}/backend/_render.py +0 -0
- /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
- /scitex/{fig → canvas}/editor/__init__.py +0 -0
- /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
- /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
- /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
- /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
- /scitex/{fig → canvas}/io/_directory.py +0 -0
- /scitex/{fig → canvas}/model/_plot_types.py +0 -0
- /scitex/{fig → canvas}/utils/_defaults.py +0 -0
- /scitex/{fig → canvas}/utils/_validate.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
- {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/WHEEL +0 -0
- {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/entry_points.txt +0 -0
- {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2025-12-20
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_utils/_const_sizes.py
|
|
4
|
-
|
|
5
|
-
"""Journal and publication figure size constants (mm)."""
|
|
6
|
-
|
|
7
|
-
# Nature
|
|
8
|
-
NATURE_SINGLE_COLUMN_MM = 89
|
|
9
|
-
NATURE_DOUBLE_COLUMN_MM = 183
|
|
10
|
-
NATURE_FULL_PAGE_MM = 247
|
|
11
|
-
|
|
12
|
-
# Science
|
|
13
|
-
SCIENCE_SINGLE_COLUMN_MM = 84
|
|
14
|
-
SCIENCE_DOUBLE_COLUMN_MM = 174
|
|
15
|
-
|
|
16
|
-
# Cell
|
|
17
|
-
CELL_SINGLE_COLUMN_MM = 85
|
|
18
|
-
CELL_DOUBLE_COLUMN_MM = 174
|
|
19
|
-
|
|
20
|
-
# PNAS
|
|
21
|
-
PNAS_SINGLE_COLUMN_MM = 87
|
|
22
|
-
PNAS_DOUBLE_COLUMN_MM = 178
|
|
23
|
-
|
|
24
|
-
# A4 page
|
|
25
|
-
A4_WIDTH_MM = 210
|
|
26
|
-
A4_HEIGHT_MM = 297
|
|
27
|
-
|
|
28
|
-
# Default spacing
|
|
29
|
-
DEFAULT_MARGIN_MM = 5
|
|
30
|
-
DEFAULT_SPACING_MM = 3
|
|
31
|
-
|
|
32
|
-
__all__ = [
|
|
33
|
-
"NATURE_SINGLE_COLUMN_MM",
|
|
34
|
-
"NATURE_DOUBLE_COLUMN_MM",
|
|
35
|
-
"NATURE_FULL_PAGE_MM",
|
|
36
|
-
"SCIENCE_SINGLE_COLUMN_MM",
|
|
37
|
-
"SCIENCE_DOUBLE_COLUMN_MM",
|
|
38
|
-
"CELL_SINGLE_COLUMN_MM",
|
|
39
|
-
"CELL_DOUBLE_COLUMN_MM",
|
|
40
|
-
"PNAS_SINGLE_COLUMN_MM",
|
|
41
|
-
"PNAS_DOUBLE_COLUMN_MM",
|
|
42
|
-
"A4_WIDTH_MM",
|
|
43
|
-
"A4_HEIGHT_MM",
|
|
44
|
-
"DEFAULT_MARGIN_MM",
|
|
45
|
-
"DEFAULT_SPACING_MM",
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
# EOF
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2025-12-20
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_utils/_convert_coords.py
|
|
4
|
-
|
|
5
|
-
"""Coordinate conversion utilities for FTS layout.
|
|
6
|
-
|
|
7
|
-
Coordinate System:
|
|
8
|
-
- Origin (0,0) is at TOP-LEFT corner
|
|
9
|
-
- x_mm increases to the RIGHT
|
|
10
|
-
- y_mm increases DOWNWARD
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from typing import Dict, Optional
|
|
14
|
-
|
|
15
|
-
from ._normalize import normalize_position
|
|
16
|
-
|
|
17
|
-
# Type alias
|
|
18
|
-
Position = Dict[str, float] # {"x_mm": float, "y_mm": float}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def to_absolute(
|
|
22
|
-
local_pos: Position,
|
|
23
|
-
parent_pos: Optional[Position] = None,
|
|
24
|
-
) -> Position:
|
|
25
|
-
"""Convert local position to absolute (figure-level) coordinates.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
local_pos: Position relative to parent's origin
|
|
29
|
-
parent_pos: Parent's absolute position (None = root level)
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
Absolute position in figure coordinates
|
|
33
|
-
|
|
34
|
-
Example:
|
|
35
|
-
>>> to_absolute({"x_mm": 5, "y_mm": 3}, {"x_mm": 10, "y_mm": 10})
|
|
36
|
-
{"x_mm": 15.0, "y_mm": 13.0}
|
|
37
|
-
"""
|
|
38
|
-
local = normalize_position(local_pos)
|
|
39
|
-
|
|
40
|
-
if parent_pos is None:
|
|
41
|
-
return local
|
|
42
|
-
|
|
43
|
-
parent = normalize_position(parent_pos)
|
|
44
|
-
return {
|
|
45
|
-
"x_mm": parent["x_mm"] + local["x_mm"],
|
|
46
|
-
"y_mm": parent["y_mm"] + local["y_mm"],
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def to_relative(
|
|
51
|
-
absolute_pos: Position,
|
|
52
|
-
parent_pos: Position,
|
|
53
|
-
) -> Position:
|
|
54
|
-
"""Convert absolute position to local (parent-relative) coordinates.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
absolute_pos: Absolute position in figure coordinates
|
|
58
|
-
parent_pos: Parent's absolute position
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
Position relative to parent's origin
|
|
62
|
-
|
|
63
|
-
Example:
|
|
64
|
-
>>> to_relative({"x_mm": 15, "y_mm": 13}, {"x_mm": 10, "y_mm": 10})
|
|
65
|
-
{"x_mm": 5.0, "y_mm": 3.0}
|
|
66
|
-
"""
|
|
67
|
-
absolute = normalize_position(absolute_pos)
|
|
68
|
-
parent = normalize_position(parent_pos)
|
|
69
|
-
return {
|
|
70
|
-
"x_mm": absolute["x_mm"] - parent["x_mm"],
|
|
71
|
-
"y_mm": absolute["y_mm"] - parent["y_mm"],
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
__all__ = ["to_absolute", "to_relative", "Position"]
|
|
76
|
-
|
|
77
|
-
# EOF
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2025-12-20
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_utils/_get_template.py
|
|
4
|
-
|
|
5
|
-
"""Figure template getter functions for publications."""
|
|
6
|
-
|
|
7
|
-
from typing import Any, Dict
|
|
8
|
-
|
|
9
|
-
from ._const_sizes import (
|
|
10
|
-
DEFAULT_MARGIN_MM,
|
|
11
|
-
DEFAULT_SPACING_MM,
|
|
12
|
-
NATURE_DOUBLE_COLUMN_MM,
|
|
13
|
-
NATURE_SINGLE_COLUMN_MM,
|
|
14
|
-
SCIENCE_SINGLE_COLUMN_MM,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def get_nature_single_column(
|
|
19
|
-
height_mm: float = 89, nrows: int = 1, ncols: int = 1
|
|
20
|
-
) -> Dict[str, Any]:
|
|
21
|
-
"""Get Nature single column figure template."""
|
|
22
|
-
return {
|
|
23
|
-
"width_mm": NATURE_SINGLE_COLUMN_MM,
|
|
24
|
-
"height_mm": height_mm,
|
|
25
|
-
"nrows": nrows,
|
|
26
|
-
"ncols": ncols,
|
|
27
|
-
"dpi": 300,
|
|
28
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
29
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
30
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
31
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
32
|
-
"wspace_mm": DEFAULT_SPACING_MM,
|
|
33
|
-
"hspace_mm": DEFAULT_SPACING_MM,
|
|
34
|
-
"metadata": {"template": "nature_single_column", "journal": "Nature"},
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def get_nature_double_column(
|
|
39
|
-
height_mm: float = 120, nrows: int = 1, ncols: int = 1
|
|
40
|
-
) -> Dict[str, Any]:
|
|
41
|
-
"""Get Nature double column figure template."""
|
|
42
|
-
return {
|
|
43
|
-
"width_mm": NATURE_DOUBLE_COLUMN_MM,
|
|
44
|
-
"height_mm": height_mm,
|
|
45
|
-
"nrows": nrows,
|
|
46
|
-
"ncols": ncols,
|
|
47
|
-
"dpi": 300,
|
|
48
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
49
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
50
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
51
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
52
|
-
"wspace_mm": DEFAULT_SPACING_MM,
|
|
53
|
-
"hspace_mm": DEFAULT_SPACING_MM,
|
|
54
|
-
"metadata": {"template": "nature_double_column", "journal": "Nature"},
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def get_science_single_column(
|
|
59
|
-
height_mm: float = 84, nrows: int = 1, ncols: int = 1
|
|
60
|
-
) -> Dict[str, Any]:
|
|
61
|
-
"""Get Science single column figure template."""
|
|
62
|
-
return {
|
|
63
|
-
"width_mm": SCIENCE_SINGLE_COLUMN_MM,
|
|
64
|
-
"height_mm": height_mm,
|
|
65
|
-
"nrows": nrows,
|
|
66
|
-
"ncols": ncols,
|
|
67
|
-
"dpi": 300,
|
|
68
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
69
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
70
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
71
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
72
|
-
"wspace_mm": DEFAULT_SPACING_MM,
|
|
73
|
-
"hspace_mm": DEFAULT_SPACING_MM,
|
|
74
|
-
"metadata": {"template": "science_single_column", "journal": "Science"},
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def get_a4_figure(
|
|
79
|
-
width_mm: float = 180, height_mm: float = 120, nrows: int = 1, ncols: int = 1
|
|
80
|
-
) -> Dict[str, Any]:
|
|
81
|
-
"""Get A4-sized figure template."""
|
|
82
|
-
return {
|
|
83
|
-
"width_mm": width_mm,
|
|
84
|
-
"height_mm": height_mm,
|
|
85
|
-
"nrows": nrows,
|
|
86
|
-
"ncols": ncols,
|
|
87
|
-
"dpi": 300,
|
|
88
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
89
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
90
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
91
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
92
|
-
"wspace_mm": DEFAULT_SPACING_MM,
|
|
93
|
-
"hspace_mm": DEFAULT_SPACING_MM,
|
|
94
|
-
"metadata": {"template": "a4_figure"},
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def get_square_figure(
|
|
99
|
-
size_mm: float = 120, nrows: int = 1, ncols: int = 1
|
|
100
|
-
) -> Dict[str, Any]:
|
|
101
|
-
"""Get square figure template."""
|
|
102
|
-
return {
|
|
103
|
-
"width_mm": size_mm,
|
|
104
|
-
"height_mm": size_mm,
|
|
105
|
-
"nrows": nrows,
|
|
106
|
-
"ncols": ncols,
|
|
107
|
-
"dpi": 300,
|
|
108
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
109
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
110
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
111
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
112
|
-
"wspace_mm": DEFAULT_SPACING_MM,
|
|
113
|
-
"hspace_mm": DEFAULT_SPACING_MM,
|
|
114
|
-
"metadata": {"template": "square_figure"},
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def get_presentation_slide(
|
|
119
|
-
aspect_ratio: str = "16:9", width_mm: float = 254
|
|
120
|
-
) -> Dict[str, Any]:
|
|
121
|
-
"""Get presentation slide figure template."""
|
|
122
|
-
if aspect_ratio == "16:9":
|
|
123
|
-
height_mm = width_mm * 9 / 16
|
|
124
|
-
elif aspect_ratio == "4:3":
|
|
125
|
-
height_mm = width_mm * 3 / 4
|
|
126
|
-
else:
|
|
127
|
-
raise ValueError(f"Unsupported aspect ratio: {aspect_ratio}")
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
"width_mm": width_mm,
|
|
131
|
-
"height_mm": height_mm,
|
|
132
|
-
"nrows": 1,
|
|
133
|
-
"ncols": 1,
|
|
134
|
-
"dpi": 150,
|
|
135
|
-
"left_mm": DEFAULT_MARGIN_MM,
|
|
136
|
-
"right_mm": DEFAULT_MARGIN_MM,
|
|
137
|
-
"top_mm": DEFAULT_MARGIN_MM,
|
|
138
|
-
"bottom_mm": DEFAULT_MARGIN_MM,
|
|
139
|
-
"metadata": {"template": "presentation_slide", "aspect_ratio": aspect_ratio},
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# Template registry
|
|
144
|
-
TEMPLATES = {
|
|
145
|
-
"nature_single": get_nature_single_column,
|
|
146
|
-
"nature_double": get_nature_double_column,
|
|
147
|
-
"science_single": get_science_single_column,
|
|
148
|
-
"a4": get_a4_figure,
|
|
149
|
-
"square": get_square_figure,
|
|
150
|
-
"presentation": get_presentation_slide,
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def get_template(name: str, **kwargs) -> Dict[str, Any]:
|
|
155
|
-
"""Get a figure template by name."""
|
|
156
|
-
if name not in TEMPLATES:
|
|
157
|
-
raise ValueError(f"Unknown template: {name}. Available: {list(TEMPLATES.keys())}")
|
|
158
|
-
return TEMPLATES[name](**kwargs)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def list_templates() -> list:
|
|
162
|
-
"""List available template names."""
|
|
163
|
-
return list(TEMPLATES.keys())
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
__all__ = [
|
|
167
|
-
"get_nature_single_column",
|
|
168
|
-
"get_nature_double_column",
|
|
169
|
-
"get_science_single_column",
|
|
170
|
-
"get_a4_figure",
|
|
171
|
-
"get_square_figure",
|
|
172
|
-
"get_presentation_slide",
|
|
173
|
-
"get_template",
|
|
174
|
-
"list_templates",
|
|
175
|
-
"TEMPLATES",
|
|
176
|
-
]
|
|
177
|
-
|
|
178
|
-
# EOF
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# Timestamp: 2025-12-20
|
|
3
|
-
# File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_fig/_utils/_normalize.py
|
|
4
|
-
|
|
5
|
-
"""Normalization utilities for position and size values."""
|
|
6
|
-
|
|
7
|
-
from typing import Any, Dict, Optional
|
|
8
|
-
|
|
9
|
-
# Type aliases
|
|
10
|
-
Position = Dict[str, float] # {"x_mm": float, "y_mm": float}
|
|
11
|
-
Size = Dict[str, float] # {"width_mm": float, "height_mm": float}
|
|
12
|
-
|
|
13
|
-
# Default values
|
|
14
|
-
DEFAULT_POSITION: Position = {"x_mm": 0.0, "y_mm": 0.0}
|
|
15
|
-
DEFAULT_SIZE: Size = {"width_mm": 80.0, "height_mm": 60.0}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def normalize_position(pos: Optional[Dict[str, Any]]) -> Position:
|
|
19
|
-
"""Normalize position to standard format {"x_mm", "y_mm"}.
|
|
20
|
-
|
|
21
|
-
Handles various input formats:
|
|
22
|
-
- {"x_mm": 10, "y_mm": 20} -> as-is
|
|
23
|
-
- {"x": 10, "y": 20} -> convert keys
|
|
24
|
-
- None -> default (0, 0)
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
pos: Position dict or None
|
|
28
|
-
|
|
29
|
-
Returns:
|
|
30
|
-
Normalized position with x_mm and y_mm keys
|
|
31
|
-
"""
|
|
32
|
-
if pos is None:
|
|
33
|
-
return DEFAULT_POSITION.copy()
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
"x_mm": float(pos.get("x_mm", pos.get("x", 0.0))),
|
|
37
|
-
"y_mm": float(pos.get("y_mm", pos.get("y", 0.0))),
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def normalize_size(size: Optional[Dict[str, Any]]) -> Size:
|
|
42
|
-
"""Normalize size to standard format {"width_mm", "height_mm"}.
|
|
43
|
-
|
|
44
|
-
Handles various input formats:
|
|
45
|
-
- {"width_mm": 80, "height_mm": 60} -> as-is
|
|
46
|
-
- {"width": 80, "height": 60} -> convert keys
|
|
47
|
-
- None -> default size
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
size: Size dict or None
|
|
51
|
-
|
|
52
|
-
Returns:
|
|
53
|
-
Normalized size with width_mm and height_mm keys
|
|
54
|
-
"""
|
|
55
|
-
if size is None:
|
|
56
|
-
return DEFAULT_SIZE.copy()
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
"width_mm": float(size.get("width_mm", size.get("width", 80.0))),
|
|
60
|
-
"height_mm": float(size.get("height_mm", size.get("height", 60.0))),
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
__all__ = [
|
|
65
|
-
"normalize_position",
|
|
66
|
-
"normalize_size",
|
|
67
|
-
"Position",
|
|
68
|
-
"Size",
|
|
69
|
-
"DEFAULT_POSITION",
|
|
70
|
-
"DEFAULT_SIZE",
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
# EOF
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# File: ./src/scitex/vis/utils/validate.py
|
|
3
|
-
"""Validation utilities for figure JSON specifications."""
|
|
4
|
-
|
|
5
|
-
from typing import Any, Dict
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def validate_json_structure(fig_json: Dict[str, Any]) -> bool:
|
|
9
|
-
"""
|
|
10
|
-
Validate basic JSON structure requirements.
|
|
11
|
-
|
|
12
|
-
Parameters
|
|
13
|
-
----------
|
|
14
|
-
fig_json : Dict[str, Any]
|
|
15
|
-
Figure JSON to validate
|
|
16
|
-
|
|
17
|
-
Returns
|
|
18
|
-
-------
|
|
19
|
-
bool
|
|
20
|
-
True if valid, raises ValueError otherwise
|
|
21
|
-
|
|
22
|
-
Raises
|
|
23
|
-
------
|
|
24
|
-
ValueError
|
|
25
|
-
If JSON structure is invalid
|
|
26
|
-
"""
|
|
27
|
-
# Required fields
|
|
28
|
-
required_fields = ["width_mm", "height_mm"]
|
|
29
|
-
|
|
30
|
-
for field in required_fields:
|
|
31
|
-
if field not in fig_json:
|
|
32
|
-
raise ValueError(f"Missing required field: {field}")
|
|
33
|
-
|
|
34
|
-
# Type validation
|
|
35
|
-
if not isinstance(fig_json["width_mm"], (int, float)):
|
|
36
|
-
raise ValueError("width_mm must be a number")
|
|
37
|
-
|
|
38
|
-
if not isinstance(fig_json["height_mm"], (int, float)):
|
|
39
|
-
raise ValueError("height_mm must be a number")
|
|
40
|
-
|
|
41
|
-
# Value validation
|
|
42
|
-
if fig_json["width_mm"] <= 0:
|
|
43
|
-
raise ValueError(f"width_mm must be positive, got {fig_json['width_mm']}")
|
|
44
|
-
|
|
45
|
-
if fig_json["height_mm"] <= 0:
|
|
46
|
-
raise ValueError(f"height_mm must be positive, got {fig_json['height_mm']}")
|
|
47
|
-
|
|
48
|
-
# Optional fields validation
|
|
49
|
-
if "nrows" in fig_json:
|
|
50
|
-
if not isinstance(fig_json["nrows"], int) or fig_json["nrows"] <= 0:
|
|
51
|
-
raise ValueError("nrows must be a positive integer")
|
|
52
|
-
|
|
53
|
-
if "ncols" in fig_json:
|
|
54
|
-
if not isinstance(fig_json["ncols"], int) or fig_json["ncols"] <= 0:
|
|
55
|
-
raise ValueError("ncols must be a positive integer")
|
|
56
|
-
|
|
57
|
-
if "dpi" in fig_json:
|
|
58
|
-
if not isinstance(fig_json["dpi"], int) or fig_json["dpi"] <= 0:
|
|
59
|
-
raise ValueError("dpi must be a positive integer")
|
|
60
|
-
|
|
61
|
-
if "axes" in fig_json:
|
|
62
|
-
if not isinstance(fig_json["axes"], list):
|
|
63
|
-
raise ValueError("axes must be a list")
|
|
64
|
-
|
|
65
|
-
return True
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def validate_plot_data(plot_data: Dict[str, Any]) -> bool:
|
|
69
|
-
"""
|
|
70
|
-
Validate plot data contains required fields for plot type.
|
|
71
|
-
|
|
72
|
-
Parameters
|
|
73
|
-
----------
|
|
74
|
-
plot_data : Dict[str, Any]
|
|
75
|
-
Plot configuration with data
|
|
76
|
-
|
|
77
|
-
Returns
|
|
78
|
-
-------
|
|
79
|
-
bool
|
|
80
|
-
True if valid, raises ValueError otherwise
|
|
81
|
-
|
|
82
|
-
Raises
|
|
83
|
-
------
|
|
84
|
-
ValueError
|
|
85
|
-
If plot data is invalid
|
|
86
|
-
"""
|
|
87
|
-
if "plot_type" not in plot_data:
|
|
88
|
-
raise ValueError("Plot must specify plot_type")
|
|
89
|
-
|
|
90
|
-
plot_type = plot_data["plot_type"]
|
|
91
|
-
data = plot_data.get("data", {})
|
|
92
|
-
|
|
93
|
-
# Type-specific requirements
|
|
94
|
-
if plot_type in ["line", "scatter", "errorbar"]:
|
|
95
|
-
if "x" not in data or "y" not in data:
|
|
96
|
-
raise ValueError(f"{plot_type} requires 'x' and 'y' data")
|
|
97
|
-
|
|
98
|
-
# Validate arrays have same length
|
|
99
|
-
x_len = len(data["x"]) if hasattr(data["x"], "__len__") else 1
|
|
100
|
-
y_len = len(data["y"]) if hasattr(data["y"], "__len__") else 1
|
|
101
|
-
|
|
102
|
-
if x_len != y_len:
|
|
103
|
-
raise ValueError(f"x and y data must have same length: {x_len} != {y_len}")
|
|
104
|
-
|
|
105
|
-
elif plot_type in ["bar", "barh"]:
|
|
106
|
-
if "x" not in data:
|
|
107
|
-
raise ValueError(f"{plot_type} requires 'x' data")
|
|
108
|
-
|
|
109
|
-
if "height" not in data and "y" not in data:
|
|
110
|
-
raise ValueError(f"{plot_type} requires 'height' or 'y' data")
|
|
111
|
-
|
|
112
|
-
elif plot_type == "hist":
|
|
113
|
-
if "x" not in data:
|
|
114
|
-
raise ValueError("hist requires 'x' data")
|
|
115
|
-
|
|
116
|
-
elif plot_type in ["heatmap", "imshow"]:
|
|
117
|
-
if "z" not in data and "img" not in data:
|
|
118
|
-
raise ValueError(f"{plot_type} requires 'z' or 'img' data")
|
|
119
|
-
|
|
120
|
-
elif plot_type in ["contour", "contourf"]:
|
|
121
|
-
if "x" not in data or "y" not in data or "z" not in data:
|
|
122
|
-
raise ValueError(f"{plot_type} requires 'x', 'y', and 'z' data")
|
|
123
|
-
|
|
124
|
-
return True
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def check_schema_version(fig_json: Dict[str, Any]) -> str:
|
|
128
|
-
"""
|
|
129
|
-
Check and return schema version.
|
|
130
|
-
|
|
131
|
-
Parameters
|
|
132
|
-
----------
|
|
133
|
-
fig_json : Dict[str, Any]
|
|
134
|
-
Figure JSON
|
|
135
|
-
|
|
136
|
-
Returns
|
|
137
|
-
-------
|
|
138
|
-
str
|
|
139
|
-
Schema version (defaults to "1.0.0" if not specified)
|
|
140
|
-
"""
|
|
141
|
-
return fig_json.get("schema_version", "1.0.0")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def validate_color(color: str) -> bool:
|
|
145
|
-
"""
|
|
146
|
-
Validate color specification.
|
|
147
|
-
|
|
148
|
-
Parameters
|
|
149
|
-
----------
|
|
150
|
-
color : str
|
|
151
|
-
Color specification (name, hex, rgb, etc.)
|
|
152
|
-
|
|
153
|
-
Returns
|
|
154
|
-
-------
|
|
155
|
-
bool
|
|
156
|
-
True if valid, raises ValueError otherwise
|
|
157
|
-
"""
|
|
158
|
-
if not isinstance(color, str):
|
|
159
|
-
raise ValueError(f"Color must be a string, got {type(color)}")
|
|
160
|
-
|
|
161
|
-
# Basic validation - matplotlib will do deeper validation
|
|
162
|
-
if not color:
|
|
163
|
-
raise ValueError("Color cannot be empty string")
|
|
164
|
-
|
|
165
|
-
return True
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def validate_axes_layout(nrows: int, ncols: int, num_axes: int) -> bool:
|
|
169
|
-
"""
|
|
170
|
-
Validate axes layout is consistent.
|
|
171
|
-
|
|
172
|
-
Parameters
|
|
173
|
-
----------
|
|
174
|
-
nrows : int
|
|
175
|
-
Number of rows
|
|
176
|
-
ncols : int
|
|
177
|
-
Number of columns
|
|
178
|
-
num_axes : int
|
|
179
|
-
Number of axes configurations
|
|
180
|
-
|
|
181
|
-
Returns
|
|
182
|
-
-------
|
|
183
|
-
bool
|
|
184
|
-
True if valid, raises ValueError otherwise
|
|
185
|
-
"""
|
|
186
|
-
max_axes = nrows * ncols
|
|
187
|
-
|
|
188
|
-
if num_axes > max_axes:
|
|
189
|
-
raise ValueError(
|
|
190
|
-
f"Too many axes: {num_axes} axes for {nrows}x{ncols} layout "
|
|
191
|
-
f"(max {max_axes})"
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
return True
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# EOF
|