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,664 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/editor/flask_editor/plotter.py
3
- """CSV plotting functionality for Flask editor."""
4
-
5
- from typing import Any, Dict, Optional
6
-
7
- import numpy as np
8
- import pandas as pd
9
-
10
-
11
- def _apply_element_overrides(
12
- kwargs: Dict[str, Any],
13
- element_key: str,
14
- element_overrides: Dict[str, Any],
15
- element_type: str,
16
- ) -> Dict[str, Any]:
17
- """Apply element-specific overrides to kwargs.
18
-
19
- Args:
20
- kwargs: Original kwargs dict
21
- element_key: Key to look up in element_overrides (e.g., 'ax_00_scatter_0')
22
- element_overrides: Dict mapping element keys to their override values
23
- element_type: Type of element ('trace', 'scatter', 'fill', 'bar')
24
-
25
- Returns:
26
- Updated kwargs dict with overrides applied
27
- """
28
- if not element_key or element_key not in element_overrides:
29
- return kwargs
30
-
31
- overrides = element_overrides[element_key]
32
- result = kwargs.copy()
33
-
34
- if element_type == "trace":
35
- # Line/trace overrides: color, linewidth, linestyle, marker, markersize, alpha
36
- if "color" in overrides:
37
- result["color"] = overrides["color"]
38
- if "linewidth" in overrides:
39
- result["linewidth"] = overrides["linewidth"]
40
- if "linestyle" in overrides:
41
- result["linestyle"] = overrides["linestyle"]
42
- if "marker" in overrides and overrides["marker"]:
43
- result["marker"] = overrides["marker"]
44
- if "markersize" in overrides:
45
- result["markersize"] = overrides["markersize"]
46
- if "alpha" in overrides:
47
- result["alpha"] = overrides["alpha"]
48
- if "label" in overrides and overrides["label"]:
49
- result["label"] = overrides["label"]
50
-
51
- elif element_type == "scatter":
52
- # Scatter overrides: color (c), size (s), marker, alpha, edgecolor
53
- if "color" in overrides:
54
- result["c"] = overrides["color"]
55
- # Remove facecolors if present (conflicts with c)
56
- result.pop("facecolors", None)
57
- if "size" in overrides:
58
- result["s"] = overrides["size"]
59
- if "marker" in overrides:
60
- result["marker"] = overrides["marker"]
61
- if "alpha" in overrides:
62
- result["alpha"] = overrides["alpha"]
63
- if "edgecolor" in overrides:
64
- result["edgecolors"] = overrides["edgecolor"]
65
-
66
- elif element_type == "fill":
67
- # Fill overrides: color, alpha
68
- if "color" in overrides:
69
- result["color"] = overrides["color"]
70
- if "alpha" in overrides:
71
- result["alpha"] = overrides["alpha"]
72
-
73
- elif element_type == "bar":
74
- # Bar overrides: facecolor (color), edgecolor, alpha
75
- if "facecolor" in overrides:
76
- result["color"] = overrides["facecolor"]
77
- if "edgecolor" in overrides:
78
- result["edgecolor"] = overrides["edgecolor"]
79
- if "alpha" in overrides:
80
- result["alpha"] = overrides["alpha"]
81
-
82
- return result
83
-
84
-
85
- def plot_from_csv(
86
- ax,
87
- csv_data: Optional[pd.DataFrame],
88
- overrides: Dict[str, Any],
89
- linewidth: float = 1.0,
90
- ):
91
- """Reconstruct plot from CSV data using trace info from overrides.
92
-
93
- Args:
94
- ax: Matplotlib axes object
95
- csv_data: DataFrame containing CSV data
96
- overrides: Dictionary with override settings including traces
97
- linewidth: Default line width in points
98
- """
99
- if csv_data is None or not isinstance(csv_data, pd.DataFrame):
100
- return
101
-
102
- df = csv_data
103
- o = overrides
104
-
105
- # Get legend settings from overrides
106
- legend_fontsize = o.get("legend_fontsize", 6)
107
- legend_visible = o.get("legend_visible", True)
108
- legend_frameon = o.get("legend_frameon", False)
109
- legend_loc = o.get("legend_loc", "best")
110
- legend_x = o.get("legend_x", 0.5)
111
- legend_y = o.get("legend_y", 0.5)
112
-
113
- # Get traces from overrides (which may have been edited by user)
114
- traces = o.get("traces", [])
115
-
116
- if traces:
117
- _plot_with_traces(
118
- ax,
119
- df,
120
- traces,
121
- linewidth,
122
- legend_fontsize,
123
- legend_visible,
124
- legend_frameon,
125
- legend_loc,
126
- legend_x,
127
- legend_y,
128
- )
129
- else:
130
- _plot_fallback(
131
- ax,
132
- df,
133
- linewidth,
134
- legend_fontsize,
135
- legend_visible,
136
- legend_frameon,
137
- legend_loc,
138
- legend_x,
139
- legend_y,
140
- )
141
-
142
-
143
- def plot_from_recipe(
144
- ax,
145
- csv_data: Optional[pd.DataFrame],
146
- ax_spec: Dict[str, Any],
147
- overrides: Dict[str, Any],
148
- linewidth: float = 1.0,
149
- ax_id: str = "",
150
- ):
151
- """Plot from new recipe schema (scitex.plt.figure.recipe).
152
-
153
- Args:
154
- ax: Matplotlib axes object
155
- csv_data: DataFrame containing CSV data
156
- ax_spec: Axis specification from recipe JSON (includes 'calls' list)
157
- overrides: Dictionary with override settings
158
- linewidth: Default line width in points
159
- ax_id: Axis identifier (e.g., 'ax_00') for element override lookup
160
- """
161
- if csv_data is None or not isinstance(csv_data, pd.DataFrame):
162
- return
163
-
164
- df = csv_data
165
- calls = ax_spec.get("calls", [])
166
-
167
- # Get element overrides from overrides dict
168
- element_overrides = overrides.get("element_overrides", {})
169
-
170
- # Track element indices per type for this axis
171
- element_counts = {"trace": 0, "scatter": 0, "fill": 0, "bar": 0}
172
-
173
- for call in calls:
174
- method = call.get("method", "")
175
- data_ref = call.get("data_ref", {})
176
- kwargs = call.get("kwargs", {}).copy() # Copy to avoid modifying original
177
- call_id = call.get("id", "")
178
-
179
- # Build element key for override lookup
180
- element_key = None
181
-
182
- try:
183
- if method == "plot":
184
- element_key = (
185
- f"{ax_id}_trace_{element_counts['trace']}"
186
- if ax_id
187
- else f"trace_{element_counts['trace']}"
188
- )
189
- kwargs = _apply_element_overrides(
190
- kwargs, element_key, element_overrides, "trace"
191
- )
192
- _render_plot(ax, df, data_ref, kwargs, linewidth)
193
- element_counts["trace"] += 1
194
- elif method == "scatter":
195
- element_key = (
196
- f"{ax_id}_scatter_{element_counts['scatter']}"
197
- if ax_id
198
- else f"scatter_{element_counts['scatter']}"
199
- )
200
- kwargs = _apply_element_overrides(
201
- kwargs, element_key, element_overrides, "scatter"
202
- )
203
- _render_scatter(ax, df, data_ref, kwargs)
204
- element_counts["scatter"] += 1
205
- elif method == "bar":
206
- element_key = (
207
- f"{ax_id}_bar_{element_counts['bar']}"
208
- if ax_id
209
- else f"bar_{element_counts['bar']}"
210
- )
211
- kwargs = _apply_element_overrides(
212
- kwargs, element_key, element_overrides, "bar"
213
- )
214
- _render_bar(ax, df, data_ref, kwargs)
215
- element_counts["bar"] += 1
216
- elif method == "fill_between":
217
- element_key = (
218
- f"{ax_id}_fill_{element_counts['fill']}"
219
- if ax_id
220
- else f"fill_{element_counts['fill']}"
221
- )
222
- kwargs = _apply_element_overrides(
223
- kwargs, element_key, element_overrides, "fill"
224
- )
225
- _render_fill_between(ax, df, data_ref, kwargs)
226
- element_counts["fill"] += 1
227
- elif method == "errorbar":
228
- _render_errorbar(ax, df, data_ref, kwargs, linewidth)
229
- elif method == "imshow":
230
- _render_imshow(ax, df, data_ref, kwargs)
231
- elif method == "contour":
232
- _render_contour(ax, df, data_ref, kwargs)
233
- elif method == "contourf":
234
- _render_contourf(ax, df, data_ref, kwargs)
235
- elif method in (
236
- "stx_shaded_line",
237
- "stx_fillv",
238
- "stx_violin",
239
- "stx_box",
240
- "stx_rectangle",
241
- "stx_raster",
242
- ):
243
- _render_stx_method(ax, df, method, data_ref, kwargs)
244
- elif method == "hist":
245
- _render_hist(ax, df, data_ref, kwargs)
246
- elif method == "text":
247
- _render_text(ax, df, data_ref, kwargs)
248
- else:
249
- # Try generic approach for unknown methods
250
- _render_generic(ax, df, method, data_ref, kwargs, linewidth)
251
- except Exception as e:
252
- print(f"Error rendering {method} for {call_id}: {e}")
253
-
254
- # Handle legend
255
- legend_fontsize = overrides.get("legend_fontsize", 6)
256
- legend_visible = overrides.get("legend_visible", True)
257
- legend_frameon = overrides.get("legend_frameon", False)
258
-
259
- if legend_visible:
260
- handles, labels = ax.get_legend_handles_labels()
261
- if handles:
262
- ax.legend(fontsize=legend_fontsize, frameon=legend_frameon)
263
-
264
-
265
- def _get_column_data(df, col_ref: str) -> Optional[np.ndarray]:
266
- """Get column data from DataFrame, handling missing columns gracefully.
267
-
268
- Handles the naming mismatch between JSON data_ref and CSV columns:
269
- - JSON: ax-row-0-col-0_trace-id-ax_00_ch1_variable-x
270
- - CSV: ax-row-0-col-0_trace-id-ch1_variable-x
271
- """
272
- if not col_ref:
273
- return None
274
-
275
- # Direct match
276
- if col_ref in df.columns:
277
- return df[col_ref].dropna().values
278
-
279
- # Try removing ax_XX_ prefix from trace-id portion
280
- # Pattern: ax-row-X-col-Y_trace-id-ax_XX_NAME_variable-Z
281
- # Should become: ax-row-X-col-Y_trace-id-NAME_variable-Z
282
- import re
283
-
284
- simplified = re.sub(r"(trace-id-)ax_\d+_", r"\1", col_ref)
285
- if simplified in df.columns:
286
- return df[simplified].dropna().values
287
-
288
- # Try case variations (lowercase the trace-id part)
289
- simplified_lower = re.sub(
290
- r"(trace-id-)[^_]+", lambda m: m.group(0).lower(), simplified
291
- )
292
- if simplified_lower in df.columns:
293
- return df[simplified_lower].dropna().values
294
-
295
- # Try matching by suffix (variable-x, variable-y, etc.)
296
- suffix_match = re.search(r"_variable-(\w+)$", col_ref)
297
- if suffix_match:
298
- var_suffix = suffix_match.group(0)
299
- # Extract trace-id pattern
300
- trace_match = re.search(r"trace-id-(?:ax_\d+_)?([^_]+)", col_ref)
301
- if trace_match:
302
- trace_name = trace_match.group(1).lower()
303
- for col in df.columns:
304
- if f"trace-id-{trace_name}" in col.lower() and col.endswith(var_suffix):
305
- return df[col].dropna().values
306
-
307
- # Last resort: fuzzy match by ending
308
- for col in df.columns:
309
- # Match if same variable suffix and similar trace pattern
310
- if col_ref.split("_variable-")[-1] == col.split("_variable-")[-1]:
311
- # Check if trace-id portion is similar
312
- ref_trace = re.search(r"trace-id-(?:ax_\d+_)?(.+?)_variable", col_ref)
313
- col_trace = re.search(r"trace-id-(.+?)_variable", col)
314
- if ref_trace and col_trace:
315
- if ref_trace.group(1).lower() == col_trace.group(1).lower():
316
- return df[col].dropna().values
317
-
318
- return None
319
-
320
-
321
- def _render_plot(ax, df, data_ref, kwargs, linewidth):
322
- """Render line plot."""
323
- x_col = data_ref.get("x", "")
324
- y_col = data_ref.get("y", "")
325
-
326
- x = _get_column_data(df, x_col)
327
- y = _get_column_data(df, y_col)
328
-
329
- if x is not None and y is not None and len(x) == len(y):
330
- lw = kwargs.pop("linewidth", linewidth)
331
- ax.plot(x, y, linewidth=lw, **kwargs)
332
-
333
-
334
- def _render_scatter(ax, df, data_ref, kwargs):
335
- """Render scatter plot."""
336
- x_col = data_ref.get("x", "")
337
- y_col = data_ref.get("y", "")
338
-
339
- x = _get_column_data(df, x_col)
340
- y = _get_column_data(df, y_col)
341
-
342
- if x is not None and y is not None and len(x) == len(y):
343
- ax.scatter(x, y, **kwargs)
344
-
345
-
346
- def _render_bar(ax, df, data_ref, kwargs):
347
- """Render bar plot."""
348
- x_col = data_ref.get("x", "")
349
- y_col = data_ref.get("y", "")
350
-
351
- x = _get_column_data(df, x_col)
352
- y = _get_column_data(df, y_col)
353
-
354
- if x is not None and y is not None and len(x) == len(y):
355
- ax.bar(x, y, **kwargs)
356
-
357
-
358
- def _render_fill_between(ax, df, data_ref, kwargs):
359
- """Render fill_between."""
360
- x_col = data_ref.get("x", "")
361
- y1_col = data_ref.get("y1", "")
362
- y2_col = data_ref.get("y2", "")
363
-
364
- x = _get_column_data(df, x_col)
365
- y1 = _get_column_data(df, y1_col)
366
- y2 = _get_column_data(df, y2_col)
367
-
368
- if x is not None and y1 is not None and y2 is not None:
369
- min_len = min(len(x), len(y1), len(y2))
370
- ax.fill_between(x[:min_len], y1[:min_len], y2[:min_len], **kwargs)
371
-
372
-
373
- def _render_errorbar(ax, df, data_ref, kwargs, linewidth):
374
- """Render errorbar plot."""
375
- x_col = data_ref.get("x", "")
376
- y_col = data_ref.get("y", "")
377
- yerr_col = data_ref.get("yerr", "")
378
-
379
- x = _get_column_data(df, x_col)
380
- y = _get_column_data(df, y_col)
381
- yerr = _get_column_data(df, yerr_col) if yerr_col else None
382
-
383
- if x is not None and y is not None and len(x) == len(y):
384
- ax.errorbar(x, y, yerr=yerr, linewidth=linewidth, **kwargs)
385
-
386
-
387
- def _render_imshow(ax, df, data_ref, kwargs):
388
- """Render imshow (heatmap)."""
389
- data_col = data_ref.get("data", "")
390
- # For imshow, data is typically in a special format - try to reconstruct
391
- # Look for row/col/value columns
392
- row_col = data_ref.get("row", "")
393
- col_col = data_ref.get("col", "")
394
- value_col = data_ref.get("value", "")
395
-
396
- if row_col and col_col and value_col:
397
- rows = _get_column_data(df, row_col)
398
- cols = _get_column_data(df, col_col)
399
- values = _get_column_data(df, value_col)
400
-
401
- if rows is not None and cols is not None and values is not None:
402
- # Reconstruct 2D array
403
- n_rows = int(rows.max()) + 1
404
- n_cols = int(cols.max()) + 1
405
- data = np.zeros((n_rows, n_cols))
406
- for r, c, v in zip(rows.astype(int), cols.astype(int), values):
407
- data[r, c] = v
408
- ax.imshow(data, **kwargs)
409
-
410
-
411
- def _render_contour(ax, df, data_ref, kwargs):
412
- """Render contour plot."""
413
- x_col = data_ref.get("x", "")
414
- y_col = data_ref.get("y", "")
415
- z_col = data_ref.get("z", "")
416
-
417
- x = _get_column_data(df, x_col)
418
- y = _get_column_data(df, y_col)
419
- z = _get_column_data(df, z_col)
420
-
421
- if x is not None and y is not None and z is not None:
422
- # Assume data is on a grid - reconstruct
423
- n = int(np.sqrt(len(x)))
424
- if n * n == len(x):
425
- X = x.reshape(n, n)
426
- Y = y.reshape(n, n)
427
- Z = z.reshape(n, n)
428
- ax.contour(X, Y, Z, **kwargs)
429
-
430
-
431
- def _render_contourf(ax, df, data_ref, kwargs):
432
- """Render filled contour plot."""
433
- x_col = data_ref.get("x", "")
434
- y_col = data_ref.get("y", "")
435
- z_col = data_ref.get("z", "")
436
-
437
- x = _get_column_data(df, x_col)
438
- y = _get_column_data(df, y_col)
439
- z = _get_column_data(df, z_col)
440
-
441
- if x is not None and y is not None and z is not None:
442
- # Assume data is on a grid - reconstruct
443
- n = int(np.sqrt(len(x)))
444
- if n * n == len(x):
445
- X = x.reshape(n, n)
446
- Y = y.reshape(n, n)
447
- Z = z.reshape(n, n)
448
- ax.contourf(X, Y, Z, **kwargs)
449
-
450
-
451
- def _render_stx_method(ax, df, method, data_ref, kwargs):
452
- """Render scitex-specific methods (shaded_line, fillv, etc.)."""
453
- # These are custom methods - for now, skip or implement basic versions
454
- if method == "stx_shaded_line":
455
- x_col = data_ref.get("x", "")
456
- y_lower_col = data_ref.get("y_lower", "")
457
- y_middle_col = data_ref.get("y_middle", "")
458
- y_upper_col = data_ref.get("y_upper", "")
459
-
460
- x = _get_column_data(df, x_col)
461
- y_lower = _get_column_data(df, y_lower_col)
462
- y_middle = _get_column_data(df, y_middle_col)
463
- y_upper = _get_column_data(df, y_upper_col)
464
-
465
- if all(v is not None for v in [x, y_lower, y_middle, y_upper]):
466
- min_len = min(len(x), len(y_lower), len(y_middle), len(y_upper))
467
- ax.fill_between(
468
- x[:min_len],
469
- y_lower[:min_len],
470
- y_upper[:min_len],
471
- alpha=0.3,
472
- **{k: v for k, v in kwargs.items() if k not in ["linewidth"]},
473
- )
474
- ax.plot(x[:min_len], y_middle[:min_len], **kwargs)
475
-
476
-
477
- def _render_hist(ax, df, data_ref, kwargs):
478
- """Render histogram."""
479
- data_col = data_ref.get("data", data_ref.get("x", ""))
480
- data = _get_column_data(df, data_col)
481
- if data is not None:
482
- ax.hist(data, **kwargs)
483
-
484
-
485
- def _render_text(ax, df, data_ref, kwargs):
486
- """Render text annotation."""
487
- x_col = data_ref.get("x", "")
488
- y_col = data_ref.get("y", "")
489
- content_col = data_ref.get("content", "")
490
-
491
- x = _get_column_data(df, x_col)
492
- y = _get_column_data(df, y_col)
493
-
494
- if x is not None and y is not None and len(x) > 0:
495
- # Get text content from CSV or kwargs
496
- text = kwargs.pop("text", "")
497
- if not text and content_col:
498
- content = _get_column_data(df, content_col)
499
- if content is not None and len(content) > 0:
500
- text = str(content[0])
501
- ax.text(x[0], y[0], text, **kwargs)
502
-
503
-
504
- def _render_generic(ax, df, method, data_ref, kwargs, linewidth):
505
- """Try to render using generic approach."""
506
- # For unknown methods, try to get x/y data and plot as line
507
- x_col = data_ref.get("x", "")
508
- y_col = data_ref.get("y", "")
509
-
510
- x = _get_column_data(df, x_col)
511
- y = _get_column_data(df, y_col)
512
-
513
- if x is not None and y is not None and len(x) == len(y):
514
- # Filter out kwargs that are not valid for ax.plot()
515
- invalid_plot_kwargs = {
516
- "levels",
517
- "extend",
518
- "origin",
519
- "extent",
520
- "aspect",
521
- "norm",
522
- "vmin",
523
- "vmax",
524
- "interpolation",
525
- "filternorm",
526
- "filterrad",
527
- "resample",
528
- "bins",
529
- "range",
530
- "density",
531
- "weights",
532
- "cumulative",
533
- "bottom",
534
- "histtype",
535
- "align",
536
- "orientation",
537
- "rwidth",
538
- "log",
539
- "stacked",
540
- "data",
541
- "width",
542
- "height",
543
- "edgecolors",
544
- "s",
545
- "c",
546
- "facecolors",
547
- }
548
- filtered_kwargs = {
549
- k: v for k, v in kwargs.items() if k not in invalid_plot_kwargs
550
- }
551
- ax.plot(x, y, linewidth=linewidth, **filtered_kwargs)
552
-
553
-
554
- def _plot_with_traces(
555
- ax,
556
- df,
557
- traces,
558
- linewidth,
559
- legend_fontsize,
560
- legend_visible,
561
- legend_frameon,
562
- legend_loc,
563
- legend_x,
564
- legend_y,
565
- ):
566
- """Plot using trace information from overrides."""
567
- for trace in traces:
568
- # Support both old format (csv_columns.x/y) and new format (x_col/y_col)
569
- csv_cols = trace.get("csv_columns", {})
570
- x_col = csv_cols.get("x") or trace.get("x_col")
571
- y_col = csv_cols.get("y") or trace.get("y_col")
572
-
573
- if x_col and y_col and x_col in df.columns and y_col in df.columns:
574
- ax.plot(
575
- df[x_col],
576
- df[y_col],
577
- label=trace.get("label", trace.get("id", "")),
578
- color=trace.get("color"),
579
- linestyle=trace.get("linestyle", "-"),
580
- linewidth=trace.get("linewidth", linewidth),
581
- marker=trace.get("marker", None),
582
- markersize=trace.get("markersize", 6),
583
- )
584
-
585
- # Add legend if there are labeled traces
586
- if legend_visible and any(t.get("label") for t in traces):
587
- _add_legend(ax, legend_fontsize, legend_frameon, legend_loc, legend_x, legend_y)
588
-
589
-
590
- def _plot_fallback(
591
- ax,
592
- df,
593
- linewidth,
594
- legend_fontsize,
595
- legend_visible,
596
- legend_frameon,
597
- legend_loc,
598
- legend_x,
599
- legend_y,
600
- ):
601
- """Fallback plotting when no trace info available - smart parsing of column names."""
602
- cols = df.columns.tolist()
603
-
604
- # Group columns by trace ID
605
- trace_groups = {}
606
- for col in cols:
607
- if col.endswith("_x"):
608
- trace_id = col[:-2] # Remove '_x'
609
- y_col = trace_id + "_y"
610
- if y_col in cols:
611
- # Extract label from column name (e.g., ax_00_sine_plot -> sine)
612
- parts = trace_id.split("_")
613
- label = parts[2] if len(parts) > 2 else trace_id
614
- trace_groups[trace_id] = {
615
- "x_col": col,
616
- "y_col": y_col,
617
- "label": label,
618
- }
619
-
620
- if trace_groups:
621
- for trace_id, info in trace_groups.items():
622
- ax.plot(
623
- df[info["x_col"]],
624
- df[info["y_col"]],
625
- label=info["label"],
626
- linewidth=linewidth,
627
- )
628
- if legend_visible:
629
- _add_legend(
630
- ax, legend_fontsize, legend_frameon, legend_loc, legend_x, legend_y
631
- )
632
-
633
- elif len(cols) >= 2:
634
- # Last resort: assume first column is x, rest are y
635
- x_col = cols[0]
636
- for y_col in cols[1:]:
637
- try:
638
- ax.plot(df[x_col], df[y_col], label=str(y_col), linewidth=linewidth)
639
- except Exception:
640
- pass
641
- if len(cols) > 2 and legend_visible:
642
- _add_legend(
643
- ax, legend_fontsize, legend_frameon, legend_loc, legend_x, legend_y
644
- )
645
-
646
-
647
- def _add_legend(ax, fontsize, frameon, loc, x, y):
648
- """Add legend to axes with specified settings."""
649
- if loc == "custom":
650
- ax.legend(
651
- fontsize=fontsize,
652
- frameon=frameon,
653
- loc="upper left",
654
- bbox_to_anchor=(x, y),
655
- )
656
- else:
657
- ax.legend(
658
- fontsize=fontsize,
659
- frameon=frameon,
660
- loc=loc,
661
- )
662
-
663
-
664
- # EOF