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.
Files changed (363) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__version__.py +1 -1
  3. scitex/_install_guide.py +14 -2
  4. scitex/bridge/_figrecipe.py +1 -1
  5. scitex/bridge/_helpers.py +1 -1
  6. scitex/bridge/_plt_vis.py +1 -1
  7. scitex/bridge/_stats_plt.py +1 -1
  8. scitex/bridge/_stats_vis.py +2 -2
  9. scitex/{fig → canvas}/__init__.py +84 -96
  10. scitex/{fig → canvas}/backend/_parser.py +1 -1
  11. scitex/{fig → canvas}/canvas.py +13 -14
  12. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  13. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  14. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  15. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  16. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  17. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  18. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  19. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  20. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  21. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  22. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  23. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  24. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  25. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  26. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  27. scitex/{fig → canvas}/io/__init__.py +32 -38
  28. scitex/{fig → canvas}/io/_bundle.py +217 -154
  29. scitex/{fig → canvas}/io/_canvas.py +1 -1
  30. scitex/{fig → canvas}/io/_data.py +1 -1
  31. scitex/{fig → canvas}/io/_export.py +1 -1
  32. scitex/{fig → canvas}/io/_load.py +1 -1
  33. scitex/{fig → canvas}/io/_panel.py +1 -1
  34. scitex/{fig → canvas}/io/_save.py +1 -1
  35. scitex/{fig → canvas}/model/__init__.py +1 -1
  36. scitex/{fig → canvas}/model/_annotations.py +1 -1
  37. scitex/{fig → canvas}/model/_axes.py +1 -1
  38. scitex/{fig → canvas}/model/_figure.py +1 -1
  39. scitex/{fig → canvas}/model/_guides.py +1 -1
  40. scitex/{fig → canvas}/model/_plot.py +1 -1
  41. scitex/{fig → canvas}/model/_styles.py +1 -1
  42. scitex/{fig → canvas}/utils/__init__.py +1 -1
  43. scitex/cli/convert.py +10 -6
  44. scitex/diagram/README.md +7 -7
  45. scitex/io/__init__.py +7 -19
  46. scitex/io/_load.py +15 -19
  47. scitex/io/_load_modules/_canvas.py +2 -2
  48. scitex/io/_load_modules/_con.py +5 -5
  49. scitex/io/_load_modules/_eeg.py +16 -12
  50. scitex/io/_save.py +11 -16
  51. scitex/io/_save_modules/__init__.py +6 -10
  52. scitex/io/_save_modules/_canvas.py +3 -3
  53. scitex/io/_save_modules/_plot_bundle.py +112 -0
  54. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  55. scitex/io/_save_modules/_stx_bundle.py +16 -16
  56. scitex/io/bundle/README.md +89 -80
  57. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  58. scitex/io/bundle/__init__.py +67 -35
  59. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  60. scitex/io/bundle/_core.py +184 -97
  61. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  62. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  63. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  64. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  65. scitex/io/bundle/_manifest.py +99 -0
  66. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  67. scitex/io/bundle/_nested.py +113 -100
  68. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  69. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  70. scitex/io/bundle/_types.py +41 -16
  71. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  72. scitex/io/bundle/_zip.py +21 -31
  73. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  74. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  75. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  76. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  77. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  78. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  79. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  80. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  81. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  82. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  83. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  84. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  85. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  86. scitex/io/bundle/schemas/__init__.py +30 -0
  87. scitex/parallel/_run.py +5 -4
  88. scitex/path/_find.py +60 -83
  89. scitex/path/_get_module_path.py +23 -21
  90. scitex/path/_get_spath.py +6 -27
  91. scitex/path/_getsize.py +23 -9
  92. scitex/path/_increment_version.py +31 -38
  93. scitex/path/_mk_spath.py +26 -29
  94. scitex/path/_path.py +5 -12
  95. scitex/path/_split.py +27 -15
  96. scitex/path/_this_path.py +23 -9
  97. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  98. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  99. scitex/plt/gallery/_generate.py +76 -50
  100. scitex/plt/io/__init__.py +17 -19
  101. scitex/plt/io/_bundle.py +99 -52
  102. scitex/plt/io/_layered_bundle.py +303 -168
  103. scitex/plt/utils/_csv_column_naming.py +250 -118
  104. scitex/schema/__init__.py +69 -73
  105. scitex/schema/_canvas.py +1 -1
  106. scitex/schema/_stats.py +2 -2
  107. scitex/stats/__init__.py +30 -33
  108. scitex/stats/_schema.py +1 -1
  109. scitex/stats/io/__init__.py +10 -11
  110. scitex/stats/io/_bundle.py +16 -16
  111. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/METADATA +190 -73
  112. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/RECORD +237 -360
  113. scitex/fig/editor/_defaults.py +0 -300
  114. scitex/fig/editor/edit/panel_loader.py +0 -232
  115. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  116. scitex/fig/editor/flask_editor/_core.py +0 -1429
  117. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  118. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  119. scitex/fts/README.md +0 -262
  120. scitex/fts/TODO.md +0 -66
  121. scitex/fts/__init__.py +0 -90
  122. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  123. scitex/fts/_bundle/__init__.py +0 -38
  124. scitex/fts/_bundle/_utils/__init__.py +0 -55
  125. scitex/fts/_bundle/_utils/_const.py +0 -26
  126. scitex/fts/_bundle/_utils/_errors.py +0 -73
  127. scitex/fts/_bundle/_utils/_generate.py +0 -21
  128. scitex/fts/_bundle/_utils/_types.py +0 -76
  129. scitex/fts/_bundle/_zipbundle.py +0 -165
  130. scitex/fts/_fig/__init__.py +0 -22
  131. scitex/fts/_fig/_backend/_parser.py +0 -188
  132. scitex/fts/_fig/_editor/__init__.py +0 -14
  133. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  134. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  135. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  136. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  137. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  138. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  139. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  140. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  141. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  142. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  143. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  144. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  145. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  146. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  147. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  148. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  149. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  150. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  151. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  152. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  153. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  154. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  155. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  156. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  157. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  158. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  159. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  160. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  161. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  162. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  163. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  164. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  165. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  166. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  167. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  168. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  169. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  170. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  171. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  172. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  188. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  189. scitex/fts/_fig/_models/_Annotations.py +0 -115
  190. scitex/fts/_fig/_models/_Axes.py +0 -152
  191. scitex/fts/_fig/_models/_Figure.py +0 -138
  192. scitex/fts/_fig/_models/_Plot.py +0 -123
  193. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  194. scitex/fts/_kinds/_figure/_composite.py +0 -345
  195. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  196. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  197. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  198. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  199. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  200. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  201. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  202. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  203. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  204. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  205. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  206. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  207. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  208. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  209. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  210. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  211. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  212. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  213. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  214. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  215. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  216. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  217. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  218. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  219. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  220. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  221. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  222. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  223. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  224. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  225. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  226. scitex/fts/_stats/__init__.py +0 -48
  227. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  228. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  229. scitex/fts/_tables/__init__.py +0 -65
  230. scitex/fts/_tables/_latex/__init__.py +0 -93
  231. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  232. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  233. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  234. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  235. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  236. scitex/fts/_tables/_latex/_utils.py +0 -369
  237. scitex/fts/_tables/_latex/_validator.py +0 -445
  238. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  239. /scitex/{fig → canvas}/README.md +0 -0
  240. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  241. /scitex/{fig → canvas}/backend/_export.py +0 -0
  242. /scitex/{fig → canvas}/backend/_render.py +0 -0
  243. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  244. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  245. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  246. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  247. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  248. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  249. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  250. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  251. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  252. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  253. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  254. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  255. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  256. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  257. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  258. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  259. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  260. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  261. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  262. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  263. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  264. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  265. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  266. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  267. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  268. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  269. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  270. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  271. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  272. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  273. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  274. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  275. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  276. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  277. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  278. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  279. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  280. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  281. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  282. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  283. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  284. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  285. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  286. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  287. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  288. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  289. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  290. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  291. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  292. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  293. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  294. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  295. /scitex/{fig → canvas}/io/_directory.py +0 -0
  296. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  297. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  298. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  299. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  300. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  301. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  302. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  303. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  304. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  305. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  306. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  307. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  308. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  309. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  310. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  311. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  312. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  313. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  314. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  315. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  316. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  317. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  318. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  319. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  320. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  321. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  322. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  323. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  324. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  325. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  326. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  327. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  328. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  329. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  330. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  331. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  332. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  333. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  334. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  335. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  336. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  337. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  338. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  339. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  340. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  341. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  342. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  343. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  344. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  345. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  346. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  347. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  348. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  349. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  350. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  351. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  352. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  353. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  354. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  355. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  356. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  357. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  358. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  359. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  360. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  361. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/WHEEL +0 -0
  362. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/entry_points.txt +0 -0
  363. {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