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
@@ -14,9 +14,14 @@ from functools import wraps
14
14
 
15
15
  import matplotlib
16
16
 
17
+ from scitex import logging
18
+
19
+ logger = logging.getLogger(__name__)
20
+
17
21
  from ._AxisWrapperMixins import (
18
22
  AdjustmentMixin,
19
23
  MatplotlibPlotMixin,
24
+ RawMatplotlibMixin,
20
25
  SeabornMixin,
21
26
  TrackingMixin,
22
27
  UnitAwareMixin,
@@ -25,7 +30,12 @@ from scitex.plt.styles import apply_plot_defaults, apply_plot_postprocess
25
30
 
26
31
 
27
32
  class AxisWrapper(
28
- MatplotlibPlotMixin, SeabornMixin, AdjustmentMixin, TrackingMixin, UnitAwareMixin
33
+ MatplotlibPlotMixin,
34
+ SeabornMixin,
35
+ RawMatplotlibMixin,
36
+ AdjustmentMixin,
37
+ TrackingMixin,
38
+ UnitAwareMixin,
29
39
  ):
30
40
  def __init__(self, fig_scitex, axis_mpl, track):
31
41
  """Initialize the AxisWrapper.
@@ -219,10 +229,8 @@ class AxisWrapper(
219
229
  kwargs,
220
230
  )
221
231
  except AttributeError:
222
- warnings.warn(
223
- f"Tracking setup incomplete for AxisWrapper ({__method_name__}).",
224
- UserWarning,
225
- stacklevel=2,
232
+ logger.warning(
233
+ f"Tracking setup incomplete for AxisWrapper ({__method_name__})."
226
234
  )
227
235
  except Exception as e:
228
236
  # Silently continue if tracking fails to not break plotting
@@ -240,11 +248,9 @@ class AxisWrapper(
240
248
  # 2. If not found on instance, try the counterpart type (fallback)
241
249
  if hasattr(self._counter_part, name):
242
250
  counterpart_attr = getattr(self._counter_part, name)
243
- warnings.warn(
251
+ logger.warning(
244
252
  f"SciTeX Axis_MplWrapper: '{name}' not directly handled. "
245
- f"Falling back to underlying '{self._counter_part.__name__}' attribute.",
246
- UserWarning,
247
- stacklevel=2,
253
+ f"Falling back to underlying '{self._counter_part.__name__}' attribute."
248
254
  )
249
255
  # If the counterpart attribute is callable (likely a method descriptor)
250
256
  if callable(counterpart_attr):
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: __init__.py - AdjustmentMixin package
5
+
6
+ """
7
+ AdjustmentMixin - Modular axis adjustment mixin for AxisWrapper.
8
+
9
+ This package provides axis adjustment functionality split into logical submodules:
10
+ - _labels: Label rotation and legend positioning
11
+ - _metadata: Axis labels, titles, and scientific metadata
12
+ - _visual: Visual adjustments (ticks, spines, extend, shift)
13
+ """
14
+
15
+ import os
16
+
17
+ __FILE__ = __file__
18
+ __DIR__ = os.path.dirname(__FILE__)
19
+
20
+ from ._labels import LabelsMixin
21
+ from ._metadata import MetadataMixin
22
+ from ._visual import VisualAdjustmentMixin
23
+
24
+
25
+ class AdjustmentMixin(LabelsMixin, MetadataMixin, VisualAdjustmentMixin):
26
+ """Mixin class for matplotlib axis adjustments.
27
+
28
+ Combines multiple specialized mixins:
29
+ - LabelsMixin: Label rotation and legend positioning
30
+ - MetadataMixin: Axis labels, titles, and scientific metadata
31
+ - VisualAdjustmentMixin: Ticks, spines, extend, shift
32
+ """
33
+ pass
34
+
35
+
36
+ # EOF
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: _labels.py - Label rotation and legend handling
5
+
6
+ """Mixin for label rotation and legend positioning."""
7
+
8
+ import os
9
+
10
+ from scitex import logging
11
+
12
+ __FILE__ = __file__
13
+ __DIR__ = os.path.dirname(__FILE__)
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class LabelsMixin:
19
+ """Mixin for label rotation and legend positioning."""
20
+
21
+ def _get_ax_module(self):
22
+ """Lazy import ax module to avoid circular imports."""
23
+ from .....plt import ax as ax_module
24
+ return ax_module
25
+
26
+ def rotate_labels(
27
+ self,
28
+ x: float = None,
29
+ y: float = None,
30
+ x_ha: str = None,
31
+ y_ha: str = None,
32
+ x_va: str = None,
33
+ y_va: str = None,
34
+ auto_adjust: bool = True,
35
+ scientific_convention: bool = True,
36
+ tight_layout: bool = False,
37
+ ) -> None:
38
+ """Rotate x and y axis labels with automatic positioning.
39
+
40
+ Parameters
41
+ ----------
42
+ x : float or None, optional
43
+ Rotation angle for x-axis labels in degrees.
44
+ y : float or None, optional
45
+ Rotation angle for y-axis labels in degrees.
46
+ x_ha, y_ha : str or None, optional
47
+ Horizontal alignment for x/y-axis labels.
48
+ x_va, y_va : str or None, optional
49
+ Vertical alignment for x/y-axis labels.
50
+ auto_adjust : bool, optional
51
+ Whether to automatically adjust alignment. Default is True.
52
+ scientific_convention : bool, optional
53
+ Whether to follow scientific conventions. Default is True.
54
+ tight_layout : bool, optional
55
+ Whether to apply tight_layout. Default is False.
56
+ """
57
+ self._axis_mpl = self._get_ax_module().rotate_labels(
58
+ self._axis_mpl,
59
+ x=x,
60
+ y=y,
61
+ x_ha=x_ha,
62
+ y_ha=y_ha,
63
+ x_va=x_va,
64
+ y_va=y_va,
65
+ auto_adjust=auto_adjust,
66
+ scientific_convention=scientific_convention,
67
+ tight_layout=tight_layout,
68
+ )
69
+
70
+ def legend(
71
+ self, *args, loc: str = "best", check_overlap: bool = False, **kwargs
72
+ ) -> None:
73
+ """Places legend at specified location, with support for outside positions.
74
+
75
+ Parameters
76
+ ----------
77
+ *args : tuple
78
+ Positional arguments (handles, labels) as in matplotlib
79
+ loc : str
80
+ Legend position. Default is "best" (matplotlib auto-placement).
81
+ Special positions:
82
+ - "best": Matplotlib automatic placement
83
+ - "outer": Place outside plot area (right side)
84
+ - "separate": Save legend as a separate figure file
85
+ - upper/lower/center variants: e.g. "upper right out"
86
+ check_overlap : bool
87
+ If True, checks for overlap between legend and data.
88
+ **kwargs : dict
89
+ Additional keyword arguments passed to legend()
90
+ """
91
+ import matplotlib.pyplot as plt
92
+
93
+ if loc == "outer":
94
+ legend = self._axis_mpl.legend(
95
+ *args, loc="center left", bbox_to_anchor=(1.02, 0.5), **kwargs
96
+ )
97
+ if hasattr(self, "_figure_wrapper") and self._figure_wrapper:
98
+ self._figure_wrapper._fig_mpl.tight_layout()
99
+ self._figure_wrapper._fig_mpl.subplots_adjust(right=0.85)
100
+ return legend
101
+
102
+ elif loc == "separate":
103
+ handles, labels = self._axis_mpl.get_legend_handles_labels()
104
+ if not handles:
105
+ logger.warning("No legend handles found.")
106
+ return None
107
+
108
+ fig = self._axis_mpl.get_figure()
109
+ if not hasattr(fig, "_separate_legend_params"):
110
+ fig._separate_legend_params = []
111
+
112
+ figsize = kwargs.pop("figsize", (4, 3))
113
+ dpi = kwargs.pop("dpi", 150)
114
+ frameon = kwargs.pop("frameon", True)
115
+ fancybox = kwargs.pop("fancybox", True)
116
+ shadow = kwargs.pop("shadow", True)
117
+
118
+ axis_id = self._get_axis_id(fig)
119
+
120
+ fig._separate_legend_params.append({
121
+ "axis": self._axis_mpl,
122
+ "axis_id": axis_id,
123
+ "handles": handles,
124
+ "labels": labels,
125
+ "figsize": figsize,
126
+ "dpi": dpi,
127
+ "frameon": frameon,
128
+ "fancybox": fancybox,
129
+ "shadow": shadow,
130
+ "kwargs": kwargs,
131
+ })
132
+
133
+ if self._axis_mpl.get_legend():
134
+ self._axis_mpl.get_legend().remove()
135
+
136
+ return None
137
+
138
+ outside_positions = {
139
+ "upper right out": ("center left", (1.15, 0.85)),
140
+ "right upper out": ("center left", (1.15, 0.85)),
141
+ "center right out": ("center left", (1.15, 0.5)),
142
+ "right out": ("center left", (1.15, 0.5)),
143
+ "right": ("center left", (1.05, 0.5)),
144
+ "lower right out": ("center left", (1.15, 0.15)),
145
+ "right lower out": ("center left", (1.15, 0.15)),
146
+ "upper left out": ("center right", (-0.25, 0.85)),
147
+ "left upper out": ("center right", (-0.25, 0.85)),
148
+ "center left out": ("center right", (-0.25, 0.5)),
149
+ "left out": ("center right", (-0.25, 0.5)),
150
+ "left": ("center right", (-0.15, 0.5)),
151
+ "lower left out": ("center right", (-0.25, 0.15)),
152
+ "left lower out": ("center right", (-0.25, 0.15)),
153
+ "upper center out": ("lower center", (0.5, 1.25)),
154
+ "upper out": ("lower center", (0.5, 1.25)),
155
+ "lower center out": ("upper center", (0.5, -0.25)),
156
+ "lower out": ("upper center", (0.5, -0.25)),
157
+ }
158
+
159
+ if loc in outside_positions:
160
+ location, bbox = outside_positions[loc]
161
+ legend_obj = self._axis_mpl.legend(
162
+ *args, loc=location, bbox_to_anchor=bbox, **kwargs
163
+ )
164
+ else:
165
+ legend_obj = self._axis_mpl.legend(*args, loc=loc, **kwargs)
166
+
167
+ if check_overlap and legend_obj is not None:
168
+ self._check_legend_overlap(legend_obj)
169
+
170
+ return legend_obj
171
+
172
+ def _get_axis_id(self, fig):
173
+ """Get unique axis identifier for separate legend handling."""
174
+ axis_id = None
175
+
176
+ try:
177
+ fig_axes = fig.get_axes()
178
+ for idx, ax in enumerate(fig_axes):
179
+ if ax is self._axis_mpl:
180
+ axis_id = f"ax_{idx:02d}"
181
+ break
182
+ except:
183
+ pass
184
+
185
+ if axis_id is None and hasattr(self._axis_mpl, "get_subplotspec"):
186
+ try:
187
+ spec = self._axis_mpl.get_subplotspec()
188
+ if spec is not None:
189
+ gridspec = spec.get_gridspec()
190
+ nrows, ncols = gridspec.get_geometry()
191
+ rowspan = spec.rowspan
192
+ colspan = spec.colspan
193
+ row_start = rowspan.start if hasattr(rowspan, "start") else rowspan
194
+ col_start = colspan.start if hasattr(colspan, "start") else colspan
195
+ flat_idx = row_start * ncols + col_start
196
+ axis_id = f"ax_{flat_idx:02d}"
197
+ except:
198
+ pass
199
+
200
+ if axis_id is None:
201
+ axis_id = f"ax_{len(fig._separate_legend_params):02d}"
202
+
203
+ return axis_id
204
+
205
+ def _check_legend_overlap(self, legend_obj):
206
+ """Check if legend overlaps with plotted data and issue warning if needed."""
207
+ import warnings
208
+ import matplotlib.transforms as transforms
209
+ import numpy as np
210
+
211
+ try:
212
+ fig = self._axis_mpl.get_figure()
213
+ fig.canvas.draw()
214
+
215
+ legend_bbox = legend_obj.get_window_extent(fig.canvas.get_renderer())
216
+ inv_transform = self._axis_mpl.transData.inverted()
217
+ legend_bbox_data = legend_bbox.transformed(inv_transform)
218
+
219
+ data_bboxes = []
220
+
221
+ for line in self._axis_mpl.get_lines():
222
+ if line.get_visible():
223
+ try:
224
+ data = line.get_xydata()
225
+ if len(data) > 0:
226
+ data_bboxes.append(data)
227
+ except:
228
+ pass
229
+
230
+ for collection in self._axis_mpl.collections:
231
+ if collection.get_visible():
232
+ try:
233
+ offsets = collection.get_offsets()
234
+ if len(offsets) > 0:
235
+ data_bboxes.append(offsets)
236
+ except:
237
+ pass
238
+
239
+ if data_bboxes:
240
+ all_data = np.vstack(data_bboxes)
241
+
242
+ x_overlap = (all_data[:, 0] >= legend_bbox_data.x0) & (
243
+ all_data[:, 0] <= legend_bbox_data.x1
244
+ )
245
+ y_overlap = (all_data[:, 1] >= legend_bbox_data.y0) & (
246
+ all_data[:, 1] <= legend_bbox_data.y1
247
+ )
248
+ overlap_points = np.sum(x_overlap & y_overlap)
249
+ overlap_pct = (overlap_points / len(all_data)) * 100
250
+
251
+ if overlap_pct > 5:
252
+ logger.warning(
253
+ f"Legend overlaps with {overlap_pct:.1f}% of data points. "
254
+ f"Consider using loc='outer' or loc='separate'."
255
+ )
256
+ return True
257
+
258
+ except Exception:
259
+ pass
260
+
261
+ return False
262
+
263
+
264
+ # EOF
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: _metadata.py - Axis metadata and labels
5
+
6
+ """Mixin for axis labels, titles, and metadata."""
7
+
8
+ import os
9
+ from typing import Optional
10
+
11
+ __FILE__ = __file__
12
+ __DIR__ = os.path.dirname(__FILE__)
13
+
14
+
15
+ class MetadataMixin:
16
+ """Mixin for setting axis labels, titles, and metadata."""
17
+
18
+ def _get_ax_module(self):
19
+ """Lazy import ax module to avoid circular imports."""
20
+ from .....plt import ax as ax_module
21
+ return ax_module
22
+
23
+ def set_xyt(
24
+ self,
25
+ x: Optional[str] = None,
26
+ y: Optional[str] = None,
27
+ t: Optional[str] = None,
28
+ format_labels: bool = True,
29
+ ) -> None:
30
+ """Set xlabel, ylabel, and title."""
31
+ self._axis_mpl = self._get_ax_module().set_xyt(
32
+ self._axis_mpl,
33
+ x=x,
34
+ y=y,
35
+ t=t,
36
+ format_labels=format_labels,
37
+ )
38
+
39
+ def set_xytc(
40
+ self,
41
+ x: Optional[str] = None,
42
+ y: Optional[str] = None,
43
+ t: Optional[str] = None,
44
+ c: Optional[str] = None,
45
+ format_labels: bool = True,
46
+ ) -> None:
47
+ """Set xlabel, ylabel, title, and caption for automatic saving.
48
+
49
+ Parameters
50
+ ----------
51
+ x : str, optional
52
+ X-axis label
53
+ y : str, optional
54
+ Y-axis label
55
+ t : str, optional
56
+ Title
57
+ c : str, optional
58
+ Caption to be saved automatically with scitex.io.save()
59
+ format_labels : bool, optional
60
+ Whether to apply automatic formatting, by default True
61
+ """
62
+ self._axis_mpl = self._get_ax_module().set_xytc(
63
+ self._axis_mpl,
64
+ x=x,
65
+ y=y,
66
+ t=t,
67
+ c=c,
68
+ format_labels=format_labels,
69
+ )
70
+
71
+ if c is not False and c is not None:
72
+ self._scitex_caption = c
73
+
74
+ def set_supxyt(
75
+ self,
76
+ xlabel: Optional[str] = None,
77
+ ylabel: Optional[str] = None,
78
+ title: Optional[str] = None,
79
+ format_labels: bool = True,
80
+ ) -> None:
81
+ """Set figure-level xlabel, ylabel, and title (suptitle)."""
82
+ self._axis_mpl = self._get_ax_module().set_supxyt(
83
+ self._axis_mpl,
84
+ xlabel=xlabel,
85
+ ylabel=ylabel,
86
+ title=title,
87
+ format_labels=format_labels,
88
+ )
89
+
90
+ def set_supxytc(
91
+ self,
92
+ xlabel: Optional[str] = None,
93
+ ylabel: Optional[str] = None,
94
+ title: Optional[str] = None,
95
+ caption: Optional[str] = None,
96
+ format_labels: bool = True,
97
+ ) -> None:
98
+ """Set figure-level xlabel, ylabel, title, and caption.
99
+
100
+ Parameters
101
+ ----------
102
+ xlabel : str, optional
103
+ Figure-level X-axis label
104
+ ylabel : str, optional
105
+ Figure-level Y-axis label
106
+ title : str, optional
107
+ Figure-level title (suptitle)
108
+ caption : str, optional
109
+ Figure-level caption for automatic saving
110
+ format_labels : bool, optional
111
+ Whether to apply automatic formatting
112
+ """
113
+ self._axis_mpl = self._get_ax_module().set_supxytc(
114
+ self._axis_mpl,
115
+ xlabel=xlabel,
116
+ ylabel=ylabel,
117
+ title=title,
118
+ caption=caption,
119
+ format_labels=format_labels,
120
+ )
121
+
122
+ if caption is not False and caption is not None:
123
+ fig = self._axis_mpl.get_figure()
124
+ fig._scitex_main_caption = caption
125
+
126
+ def set_meta(
127
+ self,
128
+ caption=None,
129
+ methods=None,
130
+ stats=None,
131
+ keywords=None,
132
+ experimental_details=None,
133
+ journal_style=None,
134
+ significance=None,
135
+ **kwargs,
136
+ ) -> None:
137
+ """Set comprehensive scientific metadata with YAML export capability.
138
+
139
+ Parameters
140
+ ----------
141
+ caption : str, optional
142
+ Figure caption text
143
+ methods : str, optional
144
+ Experimental methods description
145
+ stats : str, optional
146
+ Statistical analysis details
147
+ keywords : List[str], optional
148
+ Keywords for categorization
149
+ experimental_details : Dict[str, Any], optional
150
+ Structured experimental parameters
151
+ journal_style : str, optional
152
+ Target journal style
153
+ significance : str, optional
154
+ Significance statement
155
+ **kwargs : additional metadata
156
+ """
157
+ self._axis_mpl = self._get_ax_module().set_meta(
158
+ self._axis_mpl,
159
+ caption=caption,
160
+ methods=methods,
161
+ stats=stats,
162
+ keywords=keywords,
163
+ experimental_details=experimental_details,
164
+ journal_style=journal_style,
165
+ significance=significance,
166
+ **kwargs,
167
+ )
168
+
169
+ def set_figure_meta(
170
+ self,
171
+ caption=None,
172
+ methods=None,
173
+ stats=None,
174
+ significance=None,
175
+ funding=None,
176
+ conflicts=None,
177
+ data_availability=None,
178
+ **kwargs,
179
+ ) -> None:
180
+ """Set figure-level metadata for multi-panel figures.
181
+
182
+ Parameters
183
+ ----------
184
+ caption : str, optional
185
+ Figure-level caption
186
+ methods : str, optional
187
+ Overall experimental methods
188
+ stats : str, optional
189
+ Overall statistical approach
190
+ significance : str, optional
191
+ Significance and implications
192
+ funding : str, optional
193
+ Funding acknowledgments
194
+ conflicts : str, optional
195
+ Conflict of interest statement
196
+ data_availability : str, optional
197
+ Data availability statement
198
+ **kwargs : additional metadata
199
+ """
200
+ self._axis_mpl = self._get_ax_module().set_figure_meta(
201
+ self._axis_mpl,
202
+ caption=caption,
203
+ methods=methods,
204
+ stats=stats,
205
+ significance=significance,
206
+ funding=funding,
207
+ conflicts=conflicts,
208
+ data_availability=data_availability,
209
+ **kwargs,
210
+ )
211
+
212
+
213
+ # EOF
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: _visual.py - Visual adjustments (ticks, spines, position)
5
+
6
+ """Mixin for visual adjustments including ticks, spines, and positioning."""
7
+
8
+ import os
9
+ from typing import List, Optional, Union
10
+
11
+ __FILE__ = __file__
12
+ __DIR__ = os.path.dirname(__FILE__)
13
+
14
+
15
+ class VisualAdjustmentMixin:
16
+ """Mixin for visual adjustments to axis appearance."""
17
+
18
+ def _get_ax_module(self):
19
+ """Lazy import ax module to avoid circular imports."""
20
+ from .....plt import ax as ax_module
21
+ return ax_module
22
+
23
+ def set_ticks(
24
+ self,
25
+ xvals: Optional[List[Union[int, float]]] = None,
26
+ xticks: Optional[List[str]] = None,
27
+ yvals: Optional[List[Union[int, float]]] = None,
28
+ yticks: Optional[List[str]] = None,
29
+ ) -> None:
30
+ """Set custom tick positions and labels.
31
+
32
+ Parameters
33
+ ----------
34
+ xvals : list of numbers, optional
35
+ Positions for x-axis ticks
36
+ xticks : list of str, optional
37
+ Labels for x-axis ticks
38
+ yvals : list of numbers, optional
39
+ Positions for y-axis ticks
40
+ yticks : list of str, optional
41
+ Labels for y-axis ticks
42
+ """
43
+ self._axis_mpl = self._get_ax_module().set_ticks(
44
+ self._axis_mpl,
45
+ xvals=xvals,
46
+ xticks=xticks,
47
+ yvals=yvals,
48
+ yticks=yticks,
49
+ )
50
+
51
+ def set_n_ticks(self, n_xticks: int = 4, n_yticks: int = 4) -> None:
52
+ """Set the number of ticks on each axis.
53
+
54
+ Parameters
55
+ ----------
56
+ n_xticks : int, optional
57
+ Number of ticks on x-axis, by default 4
58
+ n_yticks : int, optional
59
+ Number of ticks on y-axis, by default 4
60
+ """
61
+ self._axis_mpl = self._get_ax_module().set_n_ticks(
62
+ self._axis_mpl, n_xticks=n_xticks, n_yticks=n_yticks
63
+ )
64
+
65
+ def hide_spines(
66
+ self,
67
+ top: bool = True,
68
+ bottom: bool = False,
69
+ left: bool = False,
70
+ right: bool = True,
71
+ ticks: bool = False,
72
+ labels: bool = False,
73
+ ) -> None:
74
+ """Hide specific spines and optionally ticks/labels.
75
+
76
+ Parameters
77
+ ----------
78
+ top : bool, optional
79
+ Hide top spine, by default True
80
+ bottom : bool, optional
81
+ Hide bottom spine, by default False
82
+ left : bool, optional
83
+ Hide left spine, by default False
84
+ right : bool, optional
85
+ Hide right spine, by default True
86
+ ticks : bool, optional
87
+ Hide all ticks, by default False
88
+ labels : bool, optional
89
+ Hide all tick labels, by default False
90
+ """
91
+ self._axis_mpl = self._get_ax_module().hide_spines(
92
+ self._axis_mpl,
93
+ top=top,
94
+ bottom=bottom,
95
+ left=left,
96
+ right=right,
97
+ ticks=ticks,
98
+ labels=labels,
99
+ )
100
+
101
+ def extend(self, x_ratio: float = 1.0, y_ratio: float = 1.0) -> None:
102
+ """Extend axis limits by a ratio.
103
+
104
+ Parameters
105
+ ----------
106
+ x_ratio : float, optional
107
+ Ratio to extend x-axis by, by default 1.0
108
+ y_ratio : float, optional
109
+ Ratio to extend y-axis by, by default 1.0
110
+ """
111
+ self._axis_mpl = self._get_ax_module().extend(
112
+ self._axis_mpl, x_ratio=x_ratio, y_ratio=y_ratio
113
+ )
114
+
115
+ def shift(self, dx: float = 0, dy: float = 0) -> None:
116
+ """Shift axis position.
117
+
118
+ Parameters
119
+ ----------
120
+ dx : float, optional
121
+ Horizontal shift, by default 0
122
+ dy : float, optional
123
+ Vertical shift, by default 0
124
+ """
125
+ self._axis_mpl = self._get_ax_module().shift(self._axis_mpl, dx=dx, dy=dy)
126
+
127
+
128
+ # EOF