scitex 2.7.0__py3-none-any.whl → 2.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. scitex/__init__.py +6 -2
  2. scitex/__version__.py +1 -1
  3. scitex/audio/README.md +52 -0
  4. scitex/audio/__init__.py +384 -0
  5. scitex/audio/__main__.py +129 -0
  6. scitex/audio/_tts.py +334 -0
  7. scitex/audio/engines/__init__.py +44 -0
  8. scitex/audio/engines/base.py +275 -0
  9. scitex/audio/engines/elevenlabs_engine.py +143 -0
  10. scitex/audio/engines/gtts_engine.py +162 -0
  11. scitex/audio/engines/pyttsx3_engine.py +131 -0
  12. scitex/audio/mcp_server.py +757 -0
  13. scitex/bridge/_helpers.py +1 -1
  14. scitex/bridge/_plt_vis.py +1 -1
  15. scitex/bridge/_stats_vis.py +1 -1
  16. scitex/dev/plt/__init__.py +272 -0
  17. scitex/dev/plt/plot_mpl_axhline.py +28 -0
  18. scitex/dev/plt/plot_mpl_axhspan.py +28 -0
  19. scitex/dev/plt/plot_mpl_axvline.py +28 -0
  20. scitex/dev/plt/plot_mpl_axvspan.py +28 -0
  21. scitex/dev/plt/plot_mpl_bar.py +29 -0
  22. scitex/dev/plt/plot_mpl_barh.py +29 -0
  23. scitex/dev/plt/plot_mpl_boxplot.py +28 -0
  24. scitex/dev/plt/plot_mpl_contour.py +31 -0
  25. scitex/dev/plt/plot_mpl_contourf.py +31 -0
  26. scitex/dev/plt/plot_mpl_errorbar.py +30 -0
  27. scitex/dev/plt/plot_mpl_eventplot.py +28 -0
  28. scitex/dev/plt/plot_mpl_fill.py +30 -0
  29. scitex/dev/plt/plot_mpl_fill_between.py +31 -0
  30. scitex/dev/plt/plot_mpl_hexbin.py +28 -0
  31. scitex/dev/plt/plot_mpl_hist.py +28 -0
  32. scitex/dev/plt/plot_mpl_hist2d.py +28 -0
  33. scitex/dev/plt/plot_mpl_imshow.py +29 -0
  34. scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
  35. scitex/dev/plt/plot_mpl_pie.py +29 -0
  36. scitex/dev/plt/plot_mpl_plot.py +29 -0
  37. scitex/dev/plt/plot_mpl_quiver.py +31 -0
  38. scitex/dev/plt/plot_mpl_scatter.py +28 -0
  39. scitex/dev/plt/plot_mpl_stackplot.py +31 -0
  40. scitex/dev/plt/plot_mpl_stem.py +29 -0
  41. scitex/dev/plt/plot_mpl_step.py +29 -0
  42. scitex/dev/plt/plot_mpl_violinplot.py +28 -0
  43. scitex/dev/plt/plot_sns_barplot.py +29 -0
  44. scitex/dev/plt/plot_sns_boxplot.py +29 -0
  45. scitex/dev/plt/plot_sns_heatmap.py +28 -0
  46. scitex/dev/plt/plot_sns_histplot.py +29 -0
  47. scitex/dev/plt/plot_sns_kdeplot.py +29 -0
  48. scitex/dev/plt/plot_sns_lineplot.py +31 -0
  49. scitex/dev/plt/plot_sns_scatterplot.py +29 -0
  50. scitex/dev/plt/plot_sns_stripplot.py +29 -0
  51. scitex/dev/plt/plot_sns_swarmplot.py +29 -0
  52. scitex/dev/plt/plot_sns_violinplot.py +29 -0
  53. scitex/dev/plt/plot_stx_bar.py +29 -0
  54. scitex/dev/plt/plot_stx_barh.py +29 -0
  55. scitex/dev/plt/plot_stx_box.py +28 -0
  56. scitex/dev/plt/plot_stx_boxplot.py +28 -0
  57. scitex/dev/plt/plot_stx_conf_mat.py +28 -0
  58. scitex/dev/plt/plot_stx_contour.py +31 -0
  59. scitex/dev/plt/plot_stx_ecdf.py +28 -0
  60. scitex/dev/plt/plot_stx_errorbar.py +30 -0
  61. scitex/dev/plt/plot_stx_fill_between.py +31 -0
  62. scitex/dev/plt/plot_stx_fillv.py +28 -0
  63. scitex/dev/plt/plot_stx_heatmap.py +28 -0
  64. scitex/dev/plt/plot_stx_image.py +28 -0
  65. scitex/dev/plt/plot_stx_imshow.py +28 -0
  66. scitex/dev/plt/plot_stx_joyplot.py +28 -0
  67. scitex/dev/plt/plot_stx_kde.py +28 -0
  68. scitex/dev/plt/plot_stx_line.py +28 -0
  69. scitex/dev/plt/plot_stx_mean_ci.py +28 -0
  70. scitex/dev/plt/plot_stx_mean_std.py +28 -0
  71. scitex/dev/plt/plot_stx_median_iqr.py +28 -0
  72. scitex/dev/plt/plot_stx_raster.py +28 -0
  73. scitex/dev/plt/plot_stx_rectangle.py +28 -0
  74. scitex/dev/plt/plot_stx_scatter.py +29 -0
  75. scitex/dev/plt/plot_stx_shaded_line.py +29 -0
  76. scitex/dev/plt/plot_stx_violin.py +28 -0
  77. scitex/dev/plt/plot_stx_violinplot.py +28 -0
  78. scitex/diagram/README.md +197 -0
  79. scitex/diagram/__init__.py +48 -0
  80. scitex/diagram/_compile.py +312 -0
  81. scitex/diagram/_diagram.py +355 -0
  82. scitex/diagram/_presets.py +173 -0
  83. scitex/diagram/_schema.py +182 -0
  84. scitex/diagram/_split.py +278 -0
  85. scitex/fig/__init__.py +352 -0
  86. scitex/{vis → fig}/backend/_parser.py +1 -1
  87. scitex/{vis → fig}/canvas.py +1 -1
  88. scitex/{vis → fig}/editor/__init__.py +5 -2
  89. scitex/{vis → fig}/editor/_dearpygui_editor.py +1 -1
  90. scitex/{vis → fig}/editor/_defaults.py +70 -5
  91. scitex/{vis → fig}/editor/_mpl_editor.py +1 -1
  92. scitex/{vis → fig}/editor/_qt_editor.py +182 -2
  93. scitex/{vis → fig}/editor/_tkinter_editor.py +1 -1
  94. scitex/fig/editor/edit/__init__.py +50 -0
  95. scitex/fig/editor/edit/backend_detector.py +109 -0
  96. scitex/fig/editor/edit/bundle_resolver.py +240 -0
  97. scitex/fig/editor/edit/editor_launcher.py +239 -0
  98. scitex/fig/editor/edit/manual_handler.py +53 -0
  99. scitex/fig/editor/edit/panel_loader.py +232 -0
  100. scitex/fig/editor/edit/path_resolver.py +67 -0
  101. scitex/fig/editor/flask_editor/_bbox.py +1299 -0
  102. scitex/fig/editor/flask_editor/_core.py +1429 -0
  103. scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
  104. scitex/fig/editor/flask_editor/_renderer.py +813 -0
  105. scitex/fig/editor/flask_editor/static/css/base/reset.css +41 -0
  106. scitex/fig/editor/flask_editor/static/css/base/typography.css +16 -0
  107. scitex/fig/editor/flask_editor/static/css/base/variables.css +85 -0
  108. scitex/fig/editor/flask_editor/static/css/components/buttons.css +217 -0
  109. scitex/fig/editor/flask_editor/static/css/components/context-menu.css +93 -0
  110. scitex/fig/editor/flask_editor/static/css/components/dropdown.css +57 -0
  111. scitex/fig/editor/flask_editor/static/css/components/forms.css +112 -0
  112. scitex/fig/editor/flask_editor/static/css/components/modal.css +59 -0
  113. scitex/fig/editor/flask_editor/static/css/components/sections.css +212 -0
  114. scitex/fig/editor/flask_editor/static/css/features/canvas.css +176 -0
  115. scitex/fig/editor/flask_editor/static/css/features/element-inspector.css +190 -0
  116. scitex/fig/editor/flask_editor/static/css/features/loading.css +59 -0
  117. scitex/fig/editor/flask_editor/static/css/features/overlay.css +45 -0
  118. scitex/fig/editor/flask_editor/static/css/features/panel-grid.css +95 -0
  119. scitex/fig/editor/flask_editor/static/css/features/selection.css +101 -0
  120. scitex/fig/editor/flask_editor/static/css/features/statistics.css +138 -0
  121. scitex/fig/editor/flask_editor/static/css/index.css +31 -0
  122. scitex/fig/editor/flask_editor/static/css/layout/container.css +7 -0
  123. scitex/fig/editor/flask_editor/static/css/layout/controls.css +56 -0
  124. scitex/fig/editor/flask_editor/static/css/layout/preview.css +78 -0
  125. scitex/fig/editor/flask_editor/static/js/alignment/axis.js +314 -0
  126. scitex/fig/editor/flask_editor/static/js/alignment/basic.js +107 -0
  127. scitex/fig/editor/flask_editor/static/js/alignment/distribute.js +54 -0
  128. scitex/fig/editor/flask_editor/static/js/canvas/canvas.js +172 -0
  129. scitex/fig/editor/flask_editor/static/js/canvas/dragging.js +258 -0
  130. scitex/fig/editor/flask_editor/static/js/canvas/resize.js +48 -0
  131. scitex/fig/editor/flask_editor/static/js/canvas/selection.js +71 -0
  132. scitex/fig/editor/flask_editor/static/js/core/api.js +288 -0
  133. scitex/fig/editor/flask_editor/static/js/core/state.js +143 -0
  134. scitex/fig/editor/flask_editor/static/js/core/utils.js +245 -0
  135. scitex/fig/editor/flask_editor/static/js/dev/element-inspector.js +992 -0
  136. scitex/fig/editor/flask_editor/static/js/editor/bbox.js +339 -0
  137. scitex/fig/editor/flask_editor/static/js/editor/element-drag.js +286 -0
  138. scitex/fig/editor/flask_editor/static/js/editor/overlay.js +371 -0
  139. scitex/fig/editor/flask_editor/static/js/editor/preview.js +293 -0
  140. scitex/fig/editor/flask_editor/static/js/main.js +426 -0
  141. scitex/fig/editor/flask_editor/static/js/shortcuts/context-menu.js +152 -0
  142. scitex/fig/editor/flask_editor/static/js/shortcuts/keyboard.js +265 -0
  143. scitex/fig/editor/flask_editor/static/js/ui/controls.js +184 -0
  144. scitex/fig/editor/flask_editor/static/js/ui/download.js +57 -0
  145. scitex/fig/editor/flask_editor/static/js/ui/help.js +100 -0
  146. scitex/fig/editor/flask_editor/static/js/ui/theme.js +34 -0
  147. scitex/fig/editor/flask_editor/templates/__init__.py +123 -0
  148. scitex/fig/editor/flask_editor/templates/_html.py +852 -0
  149. scitex/fig/editor/flask_editor/templates/_scripts.py +4933 -0
  150. scitex/fig/editor/flask_editor/templates/_styles.py +1658 -0
  151. scitex/{vis → fig}/io/__init__.py +13 -1
  152. scitex/fig/io/_bundle.py +1058 -0
  153. scitex/{vis → fig}/io/_canvas.py +1 -1
  154. scitex/{vis → fig}/io/_data.py +1 -1
  155. scitex/{vis → fig}/io/_export.py +1 -1
  156. scitex/{vis → fig}/io/_load.py +1 -1
  157. scitex/{vis → fig}/io/_panel.py +1 -1
  158. scitex/{vis → fig}/io/_save.py +1 -1
  159. scitex/{vis → fig}/model/__init__.py +1 -1
  160. scitex/{vis → fig}/model/_annotations.py +1 -1
  161. scitex/{vis → fig}/model/_axes.py +1 -1
  162. scitex/{vis → fig}/model/_figure.py +1 -1
  163. scitex/{vis → fig}/model/_guides.py +1 -1
  164. scitex/{vis → fig}/model/_plot.py +1 -1
  165. scitex/{vis → fig}/model/_styles.py +1 -1
  166. scitex/{vis → fig}/utils/__init__.py +1 -1
  167. scitex/io/__init__.py +22 -26
  168. scitex/io/_bundle.py +493 -0
  169. scitex/io/_flush.py +5 -2
  170. scitex/io/_load.py +98 -0
  171. scitex/io/_load_modules/_H5Explorer.py +5 -2
  172. scitex/io/_load_modules/_canvas.py +2 -2
  173. scitex/io/_load_modules/_image.py +3 -4
  174. scitex/io/_load_modules/_txt.py +4 -2
  175. scitex/io/_metadata.py +34 -324
  176. scitex/io/_metadata_modules/__init__.py +46 -0
  177. scitex/io/_metadata_modules/_embed.py +70 -0
  178. scitex/io/_metadata_modules/_read.py +64 -0
  179. scitex/io/_metadata_modules/_utils.py +79 -0
  180. scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
  181. scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
  182. scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
  183. scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
  184. scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
  185. scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
  186. scitex/io/_metadata_modules/read_metadata_png.py +39 -0
  187. scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
  188. scitex/io/_qr_utils.py +5 -3
  189. scitex/io/_save.py +548 -30
  190. scitex/io/_save_modules/_canvas.py +3 -3
  191. scitex/io/_save_modules/_image.py +5 -9
  192. scitex/io/_save_modules/_tex.py +7 -4
  193. scitex/io/_zip_bundle.py +439 -0
  194. scitex/io/utils/h5_to_zarr.py +11 -9
  195. scitex/msword/__init__.py +255 -0
  196. scitex/msword/profiles.py +357 -0
  197. scitex/msword/reader.py +753 -0
  198. scitex/msword/utils.py +289 -0
  199. scitex/msword/writer.py +362 -0
  200. scitex/plt/__init__.py +5 -2
  201. scitex/plt/_subplots/_AxesWrapper.py +6 -6
  202. scitex/plt/_subplots/_AxisWrapper.py +15 -9
  203. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
  204. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
  205. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
  206. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
  207. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
  208. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
  209. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
  210. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
  211. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
  212. scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
  213. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
  214. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
  215. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
  216. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
  217. scitex/plt/_subplots/_FigWrapper.py +6 -6
  218. scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
  219. scitex/plt/_subplots/_export_as_csv.py +35 -5
  220. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
  221. scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
  222. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
  223. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
  224. scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
  225. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
  226. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
  227. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
  228. scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
  229. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
  230. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
  231. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
  232. scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
  233. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
  234. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
  235. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
  236. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
  237. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
  238. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
  239. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
  240. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
  241. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
  242. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
  243. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
  244. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
  245. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
  246. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
  247. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
  248. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
  249. scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
  250. scitex/plt/gallery/_generate.py +421 -14
  251. scitex/plt/io/__init__.py +53 -0
  252. scitex/plt/io/_bundle.py +490 -0
  253. scitex/plt/io/_layered_bundle.py +1343 -0
  254. scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
  255. scitex/plt/styles/__init__.py +14 -0
  256. scitex/plt/styles/presets.py +78 -0
  257. scitex/plt/utils/__init__.py +13 -1
  258. scitex/plt/utils/_collect_figure_metadata.py +10 -14
  259. scitex/plt/utils/_configure_mpl.py +6 -18
  260. scitex/plt/utils/_crop.py +32 -14
  261. scitex/plt/utils/_csv_column_naming.py +54 -0
  262. scitex/plt/utils/_figure_mm.py +116 -1
  263. scitex/plt/utils/_hitmap.py +1643 -0
  264. scitex/plt/utils/metadata/__init__.py +25 -0
  265. scitex/plt/utils/metadata/_core.py +9 -10
  266. scitex/plt/utils/metadata/_dimensions.py +6 -3
  267. scitex/plt/utils/metadata/_editable_export.py +405 -0
  268. scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
  269. scitex/schema/__init__.py +109 -16
  270. scitex/schema/_canvas.py +1 -1
  271. scitex/schema/_plot.py +1015 -0
  272. scitex/schema/_stats.py +2 -2
  273. scitex/stats/__init__.py +117 -0
  274. scitex/stats/io/__init__.py +29 -0
  275. scitex/stats/io/_bundle.py +156 -0
  276. scitex/tex/__init__.py +4 -0
  277. scitex/tex/_export.py +890 -0
  278. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/METADATA +11 -1
  279. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/RECORD +294 -170
  280. scitex/io/memo.md +0 -2827
  281. scitex/plt/REQUESTS.md +0 -191
  282. scitex/plt/_subplots/TODO.md +0 -53
  283. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
  284. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
  285. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
  286. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
  287. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
  288. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
  289. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
  290. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
  291. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
  292. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
  293. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
  294. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
  295. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
  296. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
  297. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
  298. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
  299. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
  300. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
  301. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
  302. scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
  303. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
  304. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
  305. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
  306. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
  307. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
  308. scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
  309. scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
  310. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
  311. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
  312. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
  313. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
  314. scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
  315. scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
  316. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
  317. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
  318. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
  319. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
  320. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
  321. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
  322. scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
  323. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
  324. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
  325. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
  326. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
  327. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
  328. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
  329. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
  330. scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
  331. scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
  332. scitex/vis/__init__.py +0 -177
  333. scitex/vis/editor/_edit.py +0 -390
  334. scitex/vis/editor/flask_editor/_bbox.py +0 -529
  335. scitex/vis/editor/flask_editor/_core.py +0 -168
  336. scitex/vis/editor/flask_editor/_renderer.py +0 -393
  337. scitex/vis/editor/flask_editor/templates/__init__.py +0 -33
  338. scitex/vis/editor/flask_editor/templates/_html.py +0 -513
  339. scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
  340. scitex/vis/editor/flask_editor/templates/_styles.py +0 -739
  341. /scitex/{vis → fig}/README.md +0 -0
  342. /scitex/{vis → fig}/backend/__init__.py +0 -0
  343. /scitex/{vis → fig}/backend/_export.py +0 -0
  344. /scitex/{vis → fig}/backend/_render.py +0 -0
  345. /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
  346. /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
  347. /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
  348. /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
  349. /scitex/{vis → fig}/io/_directory.py +0 -0
  350. /scitex/{vis → fig}/model/_plot_types.py +0 -0
  351. /scitex/{vis → fig}/utils/_defaults.py +0 -0
  352. /scitex/{vis → fig}/utils/_validate.py +0 -0
  353. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/WHEEL +0 -0
  354. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/entry_points.txt +0 -0
  355. {scitex-2.7.0.dist-info → scitex-2.8.1.dist-info}/licenses/LICENSE +0 -0
scitex/io/_bundle.py ADDED
@@ -0,0 +1,493 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/_bundle.py
5
+
6
+ """
7
+ SciTeX Bundle I/O - Shared utilities for .figz, .pltz, and .statsz formats.
8
+
9
+ This module provides common bundle operations. Domain-specific logic is in:
10
+ - scitex.plt.io._bundle (pltz: hitmap, CSV, overview)
11
+ - scitex.fig.io._bundle (figz: panel composition, nested pltz)
12
+ - scitex.stats.io._bundle (statsz: comparison metadata)
13
+
14
+ Bundle formats:
15
+ .figz - Publication Figure Bundle (panels + layout)
16
+ .pltz - Reproducible Plot Bundle (data + spec + exports)
17
+ .statsz - Statistical Results Bundle (stats + metadata)
18
+
19
+ Each bundle can be:
20
+ - Directory form: Figure1.figz.d/
21
+ - ZIP archive form: Figure1.figz
22
+ """
23
+
24
+ import json
25
+ import shutil
26
+ import zipfile
27
+ from pathlib import Path
28
+ from typing import Any, Dict, List, Optional, Union
29
+
30
+ __all__ = [
31
+ "is_bundle",
32
+ "load_bundle",
33
+ "save_bundle",
34
+ "pack_bundle",
35
+ "unpack_bundle",
36
+ "validate_bundle",
37
+ "validate_spec",
38
+ "BundleType",
39
+ "BundleValidationError",
40
+ "BUNDLE_EXTENSIONS",
41
+ "get_bundle_type",
42
+ "dir_to_zip_path",
43
+ "zip_to_dir_path",
44
+ ]
45
+
46
+ # Bundle extensions
47
+ BUNDLE_EXTENSIONS = (".figz", ".pltz", ".statsz")
48
+
49
+
50
+ class BundleValidationError(ValueError):
51
+ """Error raised when bundle validation fails."""
52
+ pass
53
+
54
+
55
+ class BundleType:
56
+ """Bundle type constants."""
57
+ FIGZ = "figz"
58
+ PLTZ = "pltz"
59
+ STATSZ = "statsz"
60
+
61
+
62
+ def get_bundle_type(path: Union[str, Path]) -> Optional[str]:
63
+ """Get bundle type from path.
64
+
65
+ Args:
66
+ path: Path to bundle (directory or ZIP).
67
+
68
+ Returns:
69
+ Bundle type string or None if not a bundle.
70
+ """
71
+ p = Path(path)
72
+
73
+ # Directory bundle: ends with .figz.d, .pltz.d, .statsz.d
74
+ if p.is_dir() and p.suffix == ".d":
75
+ stem = p.stem # e.g., "Figure1.figz"
76
+ for ext in BUNDLE_EXTENSIONS:
77
+ if stem.endswith(ext):
78
+ return ext[1:] # Remove leading dot
79
+ return None
80
+
81
+ # ZIP bundle: ends with .figz, .pltz, .statsz
82
+ if p.suffix in BUNDLE_EXTENSIONS:
83
+ return p.suffix[1:] # Remove leading dot
84
+
85
+ return None
86
+
87
+
88
+ def is_bundle(path: Union[str, Path]) -> bool:
89
+ """Check if path is a SciTeX bundle (directory or ZIP).
90
+
91
+ Args:
92
+ path: Path to check.
93
+
94
+ Returns:
95
+ True if path is a bundle.
96
+ """
97
+ return get_bundle_type(path) is not None
98
+
99
+
100
+ def dir_to_zip_path(dir_path: Path) -> Path:
101
+ """Convert directory path to ZIP path.
102
+
103
+ Example: Figure1.figz.d/ -> Figure1.figz
104
+ """
105
+ if dir_path.suffix == ".d":
106
+ return dir_path.with_suffix("")
107
+ return dir_path
108
+
109
+
110
+ def zip_to_dir_path(zip_path: Path) -> Path:
111
+ """Convert ZIP path to directory path.
112
+
113
+ Example: Figure1.figz -> Figure1.figz.d/
114
+ """
115
+ return Path(str(zip_path) + ".d")
116
+
117
+
118
+ def pack_bundle(
119
+ dir_path: Union[str, Path], output_path: Optional[Union[str, Path]] = None
120
+ ) -> Path:
121
+ """Pack a bundle directory into a ZIP archive.
122
+
123
+ The ZIP archive includes the .d directory as a top-level folder so that
124
+ standard unzip extracts to: fname.pltz.d/fname.csv, fname.pltz.d/fname.json, etc.
125
+
126
+ Args:
127
+ dir_path: Path to bundle directory (e.g., Figure1.figz.d/).
128
+ output_path: Output ZIP path. Auto-generated if None.
129
+
130
+ Returns:
131
+ Path to created ZIP archive.
132
+ """
133
+ dir_path = Path(dir_path)
134
+
135
+ if not dir_path.is_dir():
136
+ raise ValueError(f"Not a directory: {dir_path}")
137
+
138
+ if output_path is None:
139
+ output_path = dir_to_zip_path(dir_path)
140
+ else:
141
+ output_path = Path(output_path)
142
+
143
+ # Get the directory name to use as top-level folder in ZIP
144
+ # e.g., "stx_line.pltz.d" for path "/path/to/stx_line.pltz.d"
145
+ dir_name = dir_path.name
146
+
147
+ # Create ZIP archive with directory structure preserved
148
+ with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
149
+ for file_path in dir_path.rglob("*"):
150
+ if file_path.is_file():
151
+ # Include directory name in archive path
152
+ # e.g., "stx_line.pltz.d/stx_line.csv"
153
+ rel_path = file_path.relative_to(dir_path)
154
+ arcname = Path(dir_name) / rel_path
155
+ zf.write(file_path, arcname)
156
+
157
+ return output_path
158
+
159
+
160
+ def unpack_bundle(
161
+ zip_path: Union[str, Path], output_path: Optional[Union[str, Path]] = None
162
+ ) -> Path:
163
+ """Unpack a bundle ZIP archive into a directory.
164
+
165
+ The ZIP archive contains a top-level .d directory, so extraction goes to
166
+ the parent directory. E.g., stx_line.pltz extracts to create stx_line.pltz.d/
167
+
168
+ Args:
169
+ zip_path: Path to bundle ZIP (e.g., Figure1.figz).
170
+ output_path: Output directory path. Auto-generated if None.
171
+
172
+ Returns:
173
+ Path to created directory.
174
+ """
175
+ zip_path = Path(zip_path)
176
+
177
+ if not zip_path.is_file():
178
+ raise ValueError(f"Not a file: {zip_path}")
179
+
180
+ # Determine extraction target
181
+ if output_path is None:
182
+ # Extract to same directory as ZIP file (ZIP contains .d folder structure)
183
+ extract_to = zip_path.parent
184
+ expected_dir = zip_to_dir_path(zip_path)
185
+ else:
186
+ output_path = Path(output_path)
187
+ extract_to = output_path.parent
188
+ expected_dir = output_path
189
+
190
+ # Extract ZIP archive (contains .d directory structure)
191
+ with zipfile.ZipFile(zip_path, "r") as zf:
192
+ zf.extractall(extract_to)
193
+
194
+ return expected_dir
195
+
196
+
197
+ def validate_spec(
198
+ spec: Dict[str, Any], bundle_type: str, strict: bool = False
199
+ ) -> List[str]:
200
+ """Validate a bundle specification against its schema.
201
+
202
+ Args:
203
+ spec: The specification dictionary to validate.
204
+ bundle_type: Bundle type ('figz', 'pltz', 'statsz').
205
+ strict: If True, raise BundleValidationError on failure.
206
+
207
+ Returns:
208
+ List of validation warning/error messages (empty if valid).
209
+
210
+ Raises:
211
+ BundleValidationError: If strict=True and validation fails.
212
+ """
213
+ errors = []
214
+
215
+ # Basic schema validation
216
+ if "schema" not in spec:
217
+ errors.append("Missing required field: schema")
218
+ elif not isinstance(spec["schema"], dict):
219
+ errors.append("'schema' field must be a dictionary")
220
+ else:
221
+ schema = spec["schema"]
222
+ if "name" not in schema:
223
+ errors.append("schema.name is required")
224
+ if "version" not in schema:
225
+ errors.append("schema.version is required")
226
+
227
+ # Delegate to domain-specific validators
228
+ if bundle_type == BundleType.FIGZ:
229
+ from scitex.fig.io._bundle import validate_figz_spec
230
+ errors.extend(validate_figz_spec(spec))
231
+ elif bundle_type == BundleType.PLTZ:
232
+ from scitex.plt.io._bundle import validate_pltz_spec
233
+ errors.extend(validate_pltz_spec(spec))
234
+ elif bundle_type == BundleType.STATSZ:
235
+ from scitex.stats.io._bundle import validate_statsz_spec
236
+ errors.extend(validate_statsz_spec(spec))
237
+ else:
238
+ errors.append(f"Unknown bundle type: {bundle_type}")
239
+
240
+ if strict and errors:
241
+ raise BundleValidationError("; ".join(errors))
242
+
243
+ return errors
244
+
245
+
246
+ def validate_bundle(
247
+ path: Union[str, Path], strict: bool = False
248
+ ) -> Dict[str, Any]:
249
+ """Validate a bundle and return validation results.
250
+
251
+ Args:
252
+ path: Path to bundle (directory or ZIP).
253
+ strict: If True, raise BundleValidationError on failure.
254
+
255
+ Returns:
256
+ Dictionary with:
257
+ - 'valid': bool
258
+ - 'errors': list of error messages
259
+ - 'bundle_type': detected bundle type
260
+ - 'spec': parsed spec (if available)
261
+
262
+ Raises:
263
+ BundleValidationError: If strict=True and validation fails.
264
+ """
265
+ result = {
266
+ "valid": True,
267
+ "errors": [],
268
+ "bundle_type": None,
269
+ "spec": None,
270
+ }
271
+
272
+ p = Path(path)
273
+
274
+ # Check bundle type
275
+ bundle_type = get_bundle_type(p)
276
+ if bundle_type is None:
277
+ result["valid"] = False
278
+ result["errors"].append(f"Not a valid bundle path: {path}")
279
+ if strict:
280
+ raise BundleValidationError(result["errors"][0])
281
+ return result
282
+
283
+ result["bundle_type"] = bundle_type
284
+
285
+ # Try to load and validate
286
+ try:
287
+ bundle = load_bundle(path)
288
+ spec = bundle.get("spec")
289
+ result["spec"] = spec
290
+
291
+ if spec is not None:
292
+ errors = validate_spec(spec, bundle_type, strict=False)
293
+ if errors:
294
+ result["valid"] = False
295
+ result["errors"].extend(errors)
296
+ else:
297
+ result["valid"] = False
298
+ result["errors"].append("Bundle has no spec")
299
+
300
+ except Exception as e:
301
+ result["valid"] = False
302
+ result["errors"].append(f"Failed to load bundle: {e}")
303
+
304
+ if strict and not result["valid"]:
305
+ raise BundleValidationError("; ".join(result["errors"]))
306
+
307
+ return result
308
+
309
+
310
+ def load_bundle(path: Union[str, Path], in_memory: bool = True) -> Dict[str, Any]:
311
+ """Load bundle from directory or ZIP transparently.
312
+
313
+ Args:
314
+ path: Path to bundle (directory or ZIP).
315
+ in_memory: If True, load ZIP contents in-memory without extracting.
316
+ If False, extract to temp directory (legacy behavior).
317
+
318
+ Returns:
319
+ Bundle data as dictionary with:
320
+ - 'type': Bundle type ('figz', 'pltz', 'statsz')
321
+ - 'spec': Parsed JSON specification
322
+ - 'path': Original path
323
+ - 'is_zip': Whether loaded from ZIP
324
+ - Additional fields based on bundle type
325
+ """
326
+ p = Path(path)
327
+ bundle_type = get_bundle_type(p)
328
+
329
+ if bundle_type is None:
330
+ raise ValueError(f"Not a valid bundle: {path}")
331
+
332
+ result = {
333
+ "type": bundle_type,
334
+ "path": p,
335
+ "is_zip": False,
336
+ }
337
+
338
+ # Handle ZIP vs directory
339
+ if p.is_file() and p.suffix in BUNDLE_EXTENSIONS:
340
+ result["is_zip"] = True
341
+
342
+ if in_memory:
343
+ # In-memory loading using ZipBundle
344
+ from ._zip_bundle import ZipBundle
345
+ with ZipBundle(p, mode="r") as zb:
346
+ result["_zip_bundle"] = zb
347
+ # Load common files in-memory
348
+ try:
349
+ result["spec"] = zb.read_json("spec.json")
350
+ except FileNotFoundError:
351
+ result["spec"] = None
352
+ try:
353
+ result["style"] = zb.read_json("style.json")
354
+ except FileNotFoundError:
355
+ result["style"] = None
356
+ try:
357
+ result["data"] = zb.read_csv("data.csv")
358
+ except FileNotFoundError:
359
+ result["data"] = None
360
+
361
+ # Get file list
362
+ result["files"] = zb.namelist()
363
+
364
+ return result
365
+ else:
366
+ # Legacy: extract to temp and load
367
+ import tempfile
368
+ temp_dir = Path(tempfile.mkdtemp())
369
+ with zipfile.ZipFile(p, "r") as zf:
370
+ zf.extractall(temp_dir)
371
+ bundle_dir = temp_dir
372
+ else:
373
+ bundle_dir = p
374
+
375
+ # Delegate to domain-specific loaders (for directory bundles or legacy mode)
376
+ if bundle_type == BundleType.FIGZ:
377
+ from scitex.fig.io._bundle import load_figz_bundle
378
+ result.update(load_figz_bundle(bundle_dir))
379
+ elif bundle_type == BundleType.PLTZ:
380
+ from scitex.plt.io import load_layered_pltz_bundle
381
+ result.update(load_layered_pltz_bundle(bundle_dir))
382
+ elif bundle_type == BundleType.STATSZ:
383
+ from scitex.stats.io._bundle import load_statsz_bundle
384
+ result.update(load_statsz_bundle(bundle_dir))
385
+
386
+ return result
387
+
388
+
389
+ def save_bundle(
390
+ data: Dict[str, Any],
391
+ path: Union[str, Path],
392
+ bundle_type: Optional[str] = None,
393
+ as_zip: bool = False,
394
+ atomic: bool = True,
395
+ ) -> Path:
396
+ """Save data as a bundle.
397
+
398
+ Args:
399
+ data: Bundle data dictionary.
400
+ path: Output path (with or without .d suffix).
401
+ bundle_type: Bundle type ('figz', 'pltz', 'statsz'). Auto-detected if None.
402
+ as_zip: If True, save as ZIP archive.
403
+ atomic: If True, use atomic write (temp file + rename) for ZIP.
404
+
405
+ Returns:
406
+ Path to saved bundle.
407
+ """
408
+ p = Path(path)
409
+
410
+ # Determine bundle type
411
+ if bundle_type is None:
412
+ bundle_type = get_bundle_type(p)
413
+ if bundle_type is None:
414
+ raise ValueError(f"Cannot determine bundle type from path: {path}")
415
+
416
+ # Determine if saving as directory or ZIP
417
+ if as_zip or (p.suffix in BUNDLE_EXTENSIONS and not str(p).endswith(".d")):
418
+ save_as_zip = True
419
+ if p.suffix == ".d":
420
+ zip_path = dir_to_zip_path(p)
421
+ else:
422
+ zip_path = p
423
+ dir_path = zip_to_dir_path(zip_path)
424
+ else:
425
+ save_as_zip = False
426
+ if not str(p).endswith(".d"):
427
+ dir_path = Path(str(p) + ".d")
428
+ else:
429
+ dir_path = p
430
+
431
+ # For direct ZIP saving with atomic writes, use ZipBundle
432
+ # Note: figz bundles need special handling for nested pltz panels,
433
+ # so they go through the directory-based save_figz_bundle path
434
+ if save_as_zip and atomic and bundle_type != BundleType.FIGZ:
435
+ from ._zip_bundle import ZipBundle
436
+
437
+ with ZipBundle(zip_path, mode="w") as zb:
438
+ # Write spec
439
+ if "spec" in data:
440
+ zb.write_json("spec.json", data["spec"])
441
+
442
+ # Write style
443
+ if "style" in data:
444
+ zb.write_json("style.json", data["style"])
445
+
446
+ # Write CSV data
447
+ if "data" in data and data["data"] is not None:
448
+ import pandas as pd
449
+ if isinstance(data["data"], pd.DataFrame):
450
+ zb.write_csv("data.csv", data["data"])
451
+
452
+ # Write exports (PNG, SVG, etc.)
453
+ for key in ["png", "svg", "pdf"]:
454
+ if key in data and data[key] is not None:
455
+ export_data = data[key]
456
+ if isinstance(export_data, bytes):
457
+ zb.write_bytes(f"exports/figure.{key}", export_data)
458
+
459
+ return zip_path
460
+
461
+ # Create directory for non-ZIP or non-atomic saves
462
+ dir_path.mkdir(parents=True, exist_ok=True)
463
+
464
+ # Delegate to domain-specific savers
465
+ if bundle_type == BundleType.FIGZ:
466
+ from scitex.fig.io._bundle import save_figz_bundle
467
+ save_figz_bundle(data, dir_path)
468
+ elif bundle_type == BundleType.PLTZ:
469
+ # Note: This path is only reached when calling save_bundle() directly
470
+ # The main stx.io.save() flow uses _save_pltz_bundle() which handles layered format
471
+ from scitex.plt.io._bundle import save_pltz_bundle
472
+ save_pltz_bundle(data, dir_path)
473
+ elif bundle_type == BundleType.STATSZ:
474
+ from scitex.stats.io._bundle import save_statsz_bundle
475
+ save_statsz_bundle(data, dir_path)
476
+ else:
477
+ raise ValueError(f"Unknown bundle type: {bundle_type}")
478
+
479
+ # Pack to ZIP if requested (non-atomic path)
480
+ if save_as_zip:
481
+ pack_bundle(dir_path, zip_path)
482
+ shutil.rmtree(dir_path) # Remove temp directory
483
+ return zip_path
484
+
485
+ return dir_path
486
+
487
+
488
+ # Backward compatibility aliases
489
+ _get_bundle_type = get_bundle_type
490
+ _dir_to_zip_path = dir_to_zip_path
491
+ _zip_to_dir_path = zip_to_dir_path
492
+
493
+ # EOF
scitex/io/_flush.py CHANGED
@@ -5,7 +5,10 @@
5
5
 
6
6
  import os
7
7
  import sys
8
- import warnings
8
+
9
+ from scitex import logging
10
+
11
+ logger = logging.getLogger(__name__)
9
12
 
10
13
 
11
14
  def flush(sys=sys):
@@ -14,7 +17,7 @@ def flush(sys=sys):
14
17
  This ensures all pending write operations are completed.
15
18
  """
16
19
  if sys is None:
17
- warnings.warn("flush needs sys. Skipping.")
20
+ logger.warning("flush needs sys. Skipping.")
18
21
  else:
19
22
  sys.stdout.flush()
20
23
  sys.stderr.flush()
scitex/io/_load.py CHANGED
@@ -48,6 +48,98 @@ from ._load_modules._zarr import _load_zarr
48
48
  from ._load_modules._canvas import _load_canvas
49
49
 
50
50
 
51
+ def _load_bundle(lpath, verbose=False, **kwargs):
52
+ """Load a .pltz, .figz, or .statsz bundle.
53
+
54
+ Parameters
55
+ ----------
56
+ lpath : str or Path
57
+ Path to the bundle (directory or ZIP).
58
+ verbose : bool
59
+ If True, print verbose output.
60
+ **kwargs
61
+ Additional arguments.
62
+
63
+ Returns
64
+ -------
65
+ For .pltz bundles:
66
+ tuple: (fig, ax, data) where fig is reconstructed figure,
67
+ ax is the axes, data is DataFrame or None.
68
+ For .figz bundles:
69
+ dict: Figure data with 'spec' and 'panels'.
70
+ For .statsz bundles:
71
+ dict: Stats data with 'spec' and 'comparisons'.
72
+ """
73
+ from ._bundle import load_bundle, BundleType
74
+
75
+ bundle = load_bundle(lpath)
76
+ bundle_type = bundle.get('type')
77
+
78
+ if bundle_type == BundleType.PLTZ:
79
+ # Return (fig, ax, data) tuple for .pltz bundles
80
+ # Note: We return the spec and data, not a reconstructed figure
81
+ # as matplotlib figures cannot be perfectly serialized/deserialized
82
+ import matplotlib.pyplot as plt
83
+ from pathlib import Path
84
+
85
+ p = Path(lpath)
86
+ bundle_dir = p
87
+
88
+ # Handle ZIP extraction
89
+ if not p.is_dir():
90
+ import tempfile
91
+ import zipfile
92
+ temp_dir = Path(tempfile.mkdtemp())
93
+ with zipfile.ZipFile(p, 'r') as zf:
94
+ zf.extractall(temp_dir)
95
+ bundle_dir = temp_dir
96
+
97
+ # Find PNG file - layered format stores in exports/
98
+ basename = bundle.get('basename', 'plot')
99
+ png_path = bundle_dir / "exports" / f"{basename}.png"
100
+ if not png_path.exists():
101
+ # Fallback to root level (legacy format)
102
+ png_path = bundle_dir / f"{basename}.png"
103
+
104
+ # Load the PNG as a figure
105
+ if png_path.exists():
106
+ img = plt.imread(str(png_path))
107
+ fig, ax = plt.subplots()
108
+ ax.imshow(img)
109
+ ax.axis('off')
110
+
111
+ # Attach metadata from spec
112
+ spec = bundle.get('spec', {})
113
+ if spec:
114
+ # Handle both layered and legacy spec formats
115
+ axes_list = spec.get('axes', [])
116
+ if axes_list and isinstance(axes_list, list):
117
+ for key, val in axes_list[0].items():
118
+ setattr(ax, f'_scitex_{key}', val)
119
+ # Theme from style (layered) or spec (legacy)
120
+ style = bundle.get('style', {})
121
+ theme = style.get('theme', {}) if style else spec.get('theme', {})
122
+ if theme:
123
+ fig._scitex_theme = theme.get('mode')
124
+
125
+ # Data from bundle (merged in load_layered_pltz_bundle)
126
+ data = bundle.get('data')
127
+ return fig, ax, data
128
+ else:
129
+ # No PNG, return spec and data
130
+ return bundle.get('spec'), None, bundle.get('data')
131
+
132
+ elif bundle_type == BundleType.FIGZ:
133
+ # Return figure dict for .figz bundles
134
+ return bundle
135
+
136
+ elif bundle_type == BundleType.STATSZ:
137
+ # Return stats dict for .statsz bundles
138
+ return bundle
139
+
140
+ return bundle
141
+
142
+
51
143
  def load(
52
144
  lpath: Union[str, Path],
53
145
  ext: str = None,
@@ -157,6 +249,12 @@ def load(
157
249
  if lpath.endswith(".canvas"):
158
250
  return _load_canvas(lpath, verbose=verbose, **kwargs)
159
251
 
252
+ # Handle bundle formats (.pltz, .figz, .statsz and their .d variants)
253
+ bundle_extensions = (".figz", ".pltz", ".statsz")
254
+ for bext in bundle_extensions:
255
+ if lpath.endswith(bext) or lpath.endswith(f"{bext}.d"):
256
+ return _load_bundle(lpath, verbose=verbose, **kwargs)
257
+
160
258
  # Check if it's a glob pattern
161
259
  if "*" in lpath or "?" in lpath or "[" in lpath:
162
260
  # Handle glob pattern
@@ -11,7 +11,6 @@ __DIR__ = os.path.dirname(__FILE__)
11
11
 
12
12
  import random
13
13
  import time
14
- import warnings
15
14
 
16
15
  # Time-stamp: "2025-06-13 21:00:00 (ywatanabe)"
17
16
 
@@ -22,6 +21,10 @@ from typing import Any, Dict, List, Optional
22
21
  import h5py
23
22
  import numpy as np
24
23
 
24
+ from scitex import logging
25
+
26
+ logger = logging.getLogger(__name__)
27
+
25
28
 
26
29
  class H5Explorer:
27
30
  """Interactive HDF5 file explorer.
@@ -262,7 +265,7 @@ def explore_h5(filepath: str) -> None:
262
265
  explorer.explore()
263
266
  explorer.close()
264
267
  else:
265
- warnings.warn(f"Warning: File does not exist: {filepath}")
268
+ logger.warning(f"File does not exist: {filepath}")
266
269
 
267
270
 
268
271
  def has_h5_key(h5_path, key, max_retries=3, action_on_corrupted="delete"):
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/_load_modules/_canvas.py
5
5
  """
6
- Load canvas directory (.canvas) for scitex.vis.
6
+ Load canvas directory (.canvas) for scitex.fig.
7
7
 
8
8
  Canvas directories are portable figure bundles containing:
9
9
  - canvas.json: Layout, panels, composition settings
@@ -100,7 +100,7 @@ def _load_canvas(
100
100
  # Return Canvas object by default
101
101
  if not as_dict:
102
102
  try:
103
- from scitex.vis.canvas import Canvas
103
+ from scitex.fig.canvas import Canvas
104
104
 
105
105
  canvas_obj = Canvas.from_dict(canvas_dict)
106
106
  # Store reference to original directory for copying
@@ -3,11 +3,12 @@
3
3
  # Time-stamp: "2024-11-14 07:55:38 (ywatanabe)"
4
4
  # File: ./scitex_repo/src/scitex/io/_load_modules/_image.py
5
5
 
6
- import logging
7
6
  from typing import Any, Dict, Optional, Tuple, Union
8
7
 
9
8
  from PIL import Image
10
9
 
10
+ from scitex import logging
11
+
11
12
  logger = logging.getLogger(__name__)
12
13
 
13
14
 
@@ -58,9 +59,7 @@ def _load_image(
58
59
 
59
60
  except Exception as e:
60
61
  # If metadata reading fails, return None
61
- import warnings
62
-
63
- warnings.warn(f"Failed to read metadata: {e}")
62
+ logger.warning(f"Failed to read metadata: {e}")
64
63
  return img, None
65
64
 
66
65