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,36 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/editor/_flask_editor.py
3
- """Web-based figure editor using Flask.
4
-
5
- This module re-exports from the flask_editor package for backward compatibility.
6
- The actual implementation is in the flask_editor/ subpackage.
7
- """
8
-
9
- from ._flask_editor import (
10
- WebEditor,
11
- check_port_available,
12
- find_available_port,
13
- kill_process_on_port,
14
- plot_from_csv,
15
- render_preview_with_bboxes,
16
- )
17
-
18
- # Legacy aliases for backward compatibility
19
- _find_available_port = find_available_port
20
- _kill_process_on_port = kill_process_on_port
21
-
22
-
23
- __all__ = [
24
- "WebEditor",
25
- "find_available_port",
26
- "kill_process_on_port",
27
- "check_port_available",
28
- "render_preview_with_bboxes",
29
- "plot_from_csv",
30
- # Legacy aliases
31
- "_find_available_port",
32
- "_kill_process_on_port",
33
- ]
34
-
35
-
36
- # EOF
@@ -1,115 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/model/annotations.py
3
- """Annotation JSON model for scitex.fig."""
4
-
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, Dict, Optional, Tuple
7
-
8
- from ._Styles import TextStyle
9
-
10
-
11
- @dataclass
12
- class AnnotationModel:
13
- """
14
- Annotation model for text, arrows, and shapes on plots.
15
-
16
- Separates structure from style properties for easier:
17
- - UI property panel generation
18
- - Style copy/paste
19
- - Batch style application
20
-
21
- Supports:
22
- - text: Simple text annotations
23
- - annotate: Text with optional arrows
24
- - arrow: Arrows without text
25
- """
26
-
27
- # Annotation type
28
- annotation_type: str # "text", "annotate", "arrow"
29
-
30
- # Text content
31
- text: Optional[str] = None
32
-
33
- # Position (data coordinates)
34
- x: float = 0.0
35
- y: float = 0.0
36
-
37
- # For annotate: arrow properties
38
- xytext: Optional[Tuple[float, float]] = None # Text position
39
-
40
- # Annotation ID for reference
41
- annotation_id: Optional[str] = None
42
-
43
- # Style properties (separated for clean UI/copy/paste)
44
- style: TextStyle = field(default_factory=TextStyle)
45
-
46
- def to_dict(self) -> Dict[str, Any]:
47
- """Convert to dictionary for JSON serialization."""
48
- d = asdict(self)
49
- # Convert tuples to lists for JSON compatibility
50
- if d.get("xytext") is not None:
51
- d["xytext"] = list(d["xytext"])
52
- d["style"] = self.style.to_dict()
53
- return d
54
-
55
- @classmethod
56
- def from_dict(cls, data: Dict[str, Any]) -> "AnnotationModel":
57
- """Create AnnotationModel from dictionary."""
58
- # Convert lists back to tuples
59
- if "xytext" in data and data["xytext"] is not None:
60
- data["xytext"] = tuple(data["xytext"])
61
-
62
- # Handle old format (backward compatibility)
63
- if "style" not in data:
64
- # Extract style properties from flat structure
65
- style_fields = TextStyle.__annotations__.keys()
66
- style_data = {k: v for k, v in data.items() if k in style_fields}
67
- data = {k: v for k, v in data.items() if k not in style_fields}
68
- data["style"] = style_data
69
-
70
- # Extract and parse style
71
- style_data = data.pop("style", {})
72
- obj = cls(**{k: v for k, v in data.items() if k in cls.__annotations__})
73
- obj.style = TextStyle.from_dict(style_data)
74
- return obj
75
-
76
- def validate(self) -> bool:
77
- """
78
- Validate the annotation model.
79
-
80
- Returns
81
- -------
82
- bool
83
- True if valid, raises ValueError otherwise
84
- """
85
- valid_annotation_types = ["text", "annotate", "arrow"]
86
-
87
- if self.annotation_type not in valid_annotation_types:
88
- raise ValueError(
89
- f"Invalid annotation_type: {self.annotation_type}. "
90
- f"Must be one of {valid_annotation_types}"
91
- )
92
-
93
- # Type-specific validation
94
- if self.annotation_type in ["text", "annotate"]:
95
- if not self.text:
96
- raise ValueError(f"{self.annotation_type} requires 'text' parameter")
97
-
98
- if self.annotation_type == "annotate":
99
- if self.xytext is None:
100
- raise ValueError("annotate requires 'xytext' parameter")
101
-
102
- # Validate alignment (now in style)
103
- valid_ha = ["left", "center", "right"]
104
- valid_va = ["top", "center", "bottom", "baseline"]
105
-
106
- if self.style.ha not in valid_ha:
107
- raise ValueError(f"Invalid ha: {self.style.ha}. Must be one of {valid_ha}")
108
-
109
- if self.style.va not in valid_va:
110
- raise ValueError(f"Invalid va: {self.style.va}. Must be one of {valid_va}")
111
-
112
- return True
113
-
114
-
115
- # EOF
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/model/axes.py
3
- """Axes JSON model for scitex.fig."""
4
-
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, Dict, List, Optional
7
-
8
- from ._Styles import AxesStyle
9
-
10
-
11
- @dataclass
12
- class AxesModel:
13
- """
14
- Axes model representing a single subplot.
15
-
16
- Separates structure/data from style properties for easier:
17
- - UI property panel generation
18
- - Style copy/paste
19
- - Batch style application
20
-
21
- Contains all configuration for one subplot including:
22
- - Plot data and type
23
- - Axis labels, limits, scales
24
- - Legends, titles
25
- - Annotations and guides
26
- """
27
-
28
- # Position in layout (0-based)
29
- row: int = 0
30
- col: int = 0
31
-
32
- # Plot configurations (list of PlotModel)
33
- plots: List[Dict[str, Any]] = field(default_factory=list)
34
-
35
- # Axis labels and titles (content, not style)
36
- xlabel: Optional[str] = None
37
- ylabel: Optional[str] = None
38
- title: Optional[str] = None
39
-
40
- # Axis limits
41
- xlim: Optional[List[float]] = None
42
- ylim: Optional[List[float]] = None
43
-
44
- # Axis scales
45
- xscale: str = "linear" # "linear", "log", "symlog", "logit"
46
- yscale: str = "linear"
47
-
48
- # Ticks
49
- xticks: Optional[List[float]] = None
50
- yticks: Optional[List[float]] = None
51
- xticklabels: Optional[List[str]] = None
52
- yticklabels: Optional[List[str]] = None
53
-
54
- # Annotations (list of AnnotationModel)
55
- annotations: List[Dict[str, Any]] = field(default_factory=list)
56
-
57
- # Guides (lines, spans, etc.)
58
- guides: List[Dict[str, Any]] = field(default_factory=list)
59
-
60
- # Axes ID for reference
61
- axes_id: Optional[str] = None
62
-
63
- # Style properties (separated for clean UI/copy/paste)
64
- style: AxesStyle = field(default_factory=AxesStyle)
65
-
66
- def to_dict(self) -> Dict[str, Any]:
67
- """Convert to dictionary for JSON serialization."""
68
- d = asdict(self)
69
- d["style"] = self.style.to_dict()
70
- return d
71
-
72
- @classmethod
73
- def from_dict(cls, data: Dict[str, Any]) -> "AxesModel":
74
- """Create AxesModel from dictionary."""
75
- # Handle old format (backward compatibility)
76
- if "style" not in data:
77
- # Extract style properties from flat structure
78
- style_fields = AxesStyle.__annotations__.keys()
79
- style_data = {k: v for k, v in data.items() if k in style_fields}
80
- data = {k: v for k, v in data.items() if k not in style_fields}
81
- data["style"] = style_data
82
-
83
- # Extract and parse style
84
- style_data = data.pop("style", {})
85
- obj = cls(**{k: v for k, v in data.items() if k in cls.__annotations__})
86
- obj.style = AxesStyle.from_dict(style_data)
87
- return obj
88
-
89
- def add_plot(self, plot_config: Dict[str, Any]) -> None:
90
- """
91
- Add a plot configuration to this axes.
92
-
93
- Parameters
94
- ----------
95
- plot_config : Dict[str, Any]
96
- Plot configuration dictionary
97
- """
98
- self.plots.append(plot_config)
99
-
100
- def add_annotation(self, annotation_config: Dict[str, Any]) -> None:
101
- """
102
- Add an annotation to this axes.
103
-
104
- Parameters
105
- ----------
106
- annotation_config : Dict[str, Any]
107
- Annotation configuration dictionary
108
- """
109
- self.annotations.append(annotation_config)
110
-
111
- def add_guide(self, guide_config: Dict[str, Any]) -> None:
112
- """
113
- Add a guide (line, span, etc.) to this axes.
114
-
115
- Parameters
116
- ----------
117
- guide_config : Dict[str, Any]
118
- Guide configuration dictionary
119
- """
120
- self.guides.append(guide_config)
121
-
122
- def validate(self) -> bool:
123
- """
124
- Validate the axes model.
125
-
126
- Returns
127
- -------
128
- bool
129
- True if valid, raises ValueError otherwise
130
- """
131
- if self.row < 0:
132
- raise ValueError(f"row must be non-negative, got {self.row}")
133
-
134
- if self.col < 0:
135
- raise ValueError(f"col must be non-negative, got {self.col}")
136
-
137
- if self.xscale not in ["linear", "log", "symlog", "logit"]:
138
- raise ValueError(f"Invalid xscale: {self.xscale}")
139
-
140
- if self.yscale not in ["linear", "log", "symlog", "logit"]:
141
- raise ValueError(f"Invalid yscale: {self.yscale}")
142
-
143
- if self.xlim is not None and len(self.xlim) != 2:
144
- raise ValueError(f"xlim must have 2 elements, got {len(self.xlim)}")
145
-
146
- if self.ylim is not None and len(self.ylim) != 2:
147
- raise ValueError(f"ylim must have 2 elements, got {len(self.ylim)}")
148
-
149
- return True
150
-
151
-
152
- # EOF
@@ -1,138 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/model/figure.py
3
- """Figure JSON model for scitex.fig."""
4
-
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, Dict, List, Optional
7
-
8
-
9
- @dataclass
10
- class FigureModel:
11
- """
12
- Top-level figure model representing a complete publication figure.
13
-
14
- This model captures all information needed to recreate a figure:
15
- - Physical dimensions (mm units)
16
- - Subplot layout
17
- - Individual axes configurations
18
- - Global figure properties
19
-
20
- All measurements use mm units for publication compatibility.
21
- """
22
-
23
- # Physical dimensions (mm)
24
- width_mm: float
25
- height_mm: float
26
-
27
- # Subplot layout
28
- nrows: int = 1
29
- ncols: int = 1
30
-
31
- # Axes configurations (list of AxesModel)
32
- axes: List[Dict[str, Any]] = field(default_factory=list)
33
-
34
- # Figure-level properties
35
- dpi: int = 300
36
- facecolor: str = "white"
37
- edgecolor: str = "none"
38
-
39
- # Spacing (mm)
40
- left_mm: Optional[float] = None
41
- right_mm: Optional[float] = None
42
- top_mm: Optional[float] = None
43
- bottom_mm: Optional[float] = None
44
- wspace_mm: Optional[float] = None
45
- hspace_mm: Optional[float] = None
46
-
47
- # Suptitle
48
- suptitle: Optional[str] = None
49
- suptitle_fontsize: Optional[float] = None
50
- suptitle_fontweight: Optional[str] = None
51
- suptitle_y: Optional[float] = None
52
-
53
- # Metadata
54
- metadata: Dict[str, Any] = field(default_factory=dict)
55
-
56
- # Figure ID for tracking
57
- figure_id: Optional[str] = None
58
-
59
- # Version for schema evolution
60
- schema_version: str = "1.0.0"
61
-
62
- def to_dict(self) -> Dict[str, Any]:
63
- """Convert to dictionary for JSON serialization."""
64
- return asdict(self)
65
-
66
- @classmethod
67
- def from_dict(cls, data: Dict[str, Any]) -> "FigureModel":
68
- """Create FigureModel from dictionary."""
69
- return cls(**data)
70
-
71
- def validate(self) -> bool:
72
- """
73
- Validate the figure model.
74
-
75
- Returns
76
- -------
77
- bool
78
- True if valid, raises ValueError otherwise
79
- """
80
- if self.width_mm <= 0:
81
- raise ValueError(f"width_mm must be positive, got {self.width_mm}")
82
-
83
- if self.height_mm <= 0:
84
- raise ValueError(f"height_mm must be positive, got {self.height_mm}")
85
-
86
- if self.nrows <= 0:
87
- raise ValueError(f"nrows must be positive, got {self.nrows}")
88
-
89
- if self.ncols <= 0:
90
- raise ValueError(f"ncols must be positive, got {self.ncols}")
91
-
92
- if self.dpi <= 0:
93
- raise ValueError(f"dpi must be positive, got {self.dpi}")
94
-
95
- # Validate that axes count matches layout
96
- expected_axes = self.nrows * self.ncols
97
- if len(self.axes) > expected_axes:
98
- raise ValueError(
99
- f"Too many axes: expected {expected_axes} for {self.nrows}x{self.ncols} layout, "
100
- f"got {len(self.axes)}"
101
- )
102
-
103
- return True
104
-
105
- def get_axes_by_position(self, row: int, col: int) -> Optional[Dict[str, Any]]:
106
- """
107
- Get axes configuration by subplot position.
108
-
109
- Parameters
110
- ----------
111
- row : int
112
- Row index (0-based)
113
- col : int
114
- Column index (0-based)
115
-
116
- Returns
117
- -------
118
- Optional[Dict[str, Any]]
119
- Axes configuration or None if not found
120
- """
121
- idx = row * self.ncols + col
122
- if idx < len(self.axes):
123
- return self.axes[idx]
124
- return None
125
-
126
- def add_axes(self, axes_config: Dict[str, Any]) -> None:
127
- """
128
- Add an axes configuration to the figure.
129
-
130
- Parameters
131
- ----------
132
- axes_config : Dict[str, Any]
133
- Axes configuration dictionary
134
- """
135
- self.axes.append(axes_config)
136
-
137
-
138
- # EOF
@@ -1,123 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/model/plot.py
3
- """Plot JSON model for scitex.fig."""
4
-
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, Dict, List, Optional
7
-
8
- from ._Styles import PlotStyle
9
-
10
-
11
- @dataclass
12
- class PlotModel:
13
- """
14
- Plot model representing a single data visualization within an axes.
15
-
16
- Separates data/structure from style properties for easier:
17
- - UI property panel generation
18
- - Style copy/paste
19
- - Batch style application
20
-
21
- Supports common plot types:
22
- - line, scatter, bar, barh, hist
23
- - errorbar, fill_between
24
- - heatmap, imshow, contour, contourf
25
- - box, violin
26
- """
27
-
28
- # Plot type
29
- plot_type: str # "line", "scatter", "bar", "errorbar", "heatmap", etc.
30
-
31
- # Data (can be embedded or referenced)
32
- data: Dict[str, Any] = field(default_factory=dict)
33
-
34
- # Human-readable identifiers
35
- plot_id: Optional[str] = None
36
- label: Optional[str] = None
37
- tags: List[str] = field(default_factory=list)
38
-
39
- # Style properties (separated for clean UI/copy/paste)
40
- style: PlotStyle = field(default_factory=PlotStyle)
41
-
42
- # Additional kwargs for matplotlib (for advanced use)
43
- extra_kwargs: Dict[str, Any] = field(default_factory=dict)
44
-
45
- def to_dict(self) -> Dict[str, Any]:
46
- """Convert to dictionary for JSON serialization."""
47
- d = asdict(self)
48
- d["style"] = self.style.to_dict()
49
- return d
50
-
51
- @classmethod
52
- def from_dict(cls, data: Dict[str, Any]) -> "PlotModel":
53
- """Create PlotModel from dictionary."""
54
- # Handle old format (backward compatibility)
55
- if "style" not in data:
56
- # Extract style properties from flat structure
57
- style_fields = PlotStyle.__annotations__.keys()
58
- style_data = {k: v for k, v in data.items() if k in style_fields}
59
- data = {k: v for k, v in data.items() if k not in style_fields}
60
- data["style"] = style_data
61
-
62
- # Extract and parse style
63
- style_data = data.pop("style", {})
64
- obj = cls(**{k: v for k, v in data.items() if k in cls.__annotations__})
65
- obj.style = PlotStyle.from_dict(style_data)
66
- return obj
67
-
68
- def validate(self) -> bool:
69
- """
70
- Validate the plot model.
71
-
72
- Returns
73
- -------
74
- bool
75
- True if valid, raises ValueError otherwise
76
- """
77
- # Currently implemented plot types
78
- # TODO: Add box, violin, step, stem when renderers are implemented
79
- valid_plot_types = [
80
- "line",
81
- "scatter",
82
- "bar",
83
- "barh",
84
- "hist",
85
- "errorbar",
86
- "fill_between",
87
- "heatmap",
88
- "imshow",
89
- "contour",
90
- "contourf",
91
- ]
92
-
93
- if self.plot_type not in valid_plot_types:
94
- raise ValueError(
95
- f"Invalid plot_type: {self.plot_type}. "
96
- f"Must be one of {valid_plot_types}"
97
- )
98
-
99
- # Validate data exists
100
- if not self.data:
101
- raise ValueError("Plot must have data")
102
-
103
- # Type-specific validation
104
- if self.plot_type in ["heatmap", "imshow"]:
105
- if "z" not in self.data and "img" not in self.data:
106
- raise ValueError(f"{self.plot_type} requires 'z' or 'img' in data")
107
-
108
- elif self.plot_type in ["line", "scatter", "errorbar"]:
109
- if "x" not in self.data or "y" not in self.data:
110
- raise ValueError(f"{self.plot_type} requires 'x' and 'y' in data")
111
-
112
- elif self.plot_type in ["bar", "barh"]:
113
- if "x" not in self.data or "height" not in self.data:
114
- # Allow alternative format with y instead of height
115
- if "y" not in self.data:
116
- raise ValueError(
117
- f"{self.plot_type} requires 'x' and 'height' (or 'y') in data"
118
- )
119
-
120
- return True
121
-
122
-
123
- # EOF