jarvisplot 2.1.12__tar.gz → 2.1.13__tar.gz

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 (334) hide show
  1. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/CHANGELOG.md +13 -0
  2. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/PKG-INFO +5 -2
  3. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/SOURCES.txt +1 -0
  4. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/requires.txt +4 -0
  5. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/MANIFEST.in +0 -1
  6. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/PKG-INFO +5 -2
  7. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/README.md +1 -1
  8. jarvisplot-2.1.13/VERSION +1 -0
  9. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/forest_legend.py +11 -0
  10. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/forest_runtime.py +6 -3
  11. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/1x1/ternary.json +1 -1
  12. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/ternary.json +1 -1
  13. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/ternary_cmap.json +1 -1
  14. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/4x1/ternary_cmap.json +1 -1
  15. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/gambit/2x1/rect_cmap.json +1 -1
  16. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/flowchart.py +39 -5
  17. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/pyproject.toml +4 -1
  18. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_card_debug_shape.py +21 -0
  19. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_flowchart_renderer.py +76 -1
  20. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_forest.py +7 -0
  21. jarvisplot-2.1.13/tests/test_forest_legend.py +39 -0
  22. jarvisplot-2.1.12/VERSION +0 -1
  23. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/README.md +0 -0
  24. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/a4paper_2x1.yaml +0 -0
  25. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/a4paper_4x1_rectcmap.yaml +0 -0
  26. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/compact_legend.yaml +0 -0
  27. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/correlation_demo.csv +0 -0
  28. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/correlation_demo_wide.csv +0 -0
  29. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/corrplot_diamond.yaml +0 -0
  30. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/corrplot_matrix.yaml +0 -0
  31. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/corrplot_scales.yaml +0 -0
  32. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/README.md +0 -0
  33. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/box.yaml +0 -0
  34. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/box.csv +0 -0
  35. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/forest-points.csv +0 -0
  36. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/forest-rows.csv +0 -0
  37. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/interval.csv +0 -0
  38. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/points.csv +0 -0
  39. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/summary-intervals.csv +0 -0
  40. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/summary-labels.csv +0 -0
  41. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/summary-points.csv +0 -0
  42. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/data/summary-rows.csv +0 -0
  43. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/interval.yaml +0 -0
  44. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/intervals-only.yaml +0 -0
  45. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/multi-interval.yaml +0 -0
  46. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/real-demo-debug.yaml +0 -0
  47. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/forest/real-demo.yaml +0 -0
  48. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/gambit_2x1.yaml +0 -0
  49. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/generated_data.yaml +0 -0
  50. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/legend_cards.yaml +0 -0
  51. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/pdf_cdf_1d.yaml +0 -0
  52. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/Example/ternary_1x1.yaml +0 -0
  53. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/dependency_links.txt +0 -0
  54. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/entry_points.txt +0 -0
  55. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/JarvisPLOT.egg-info/top_level.txt +0 -0
  56. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/__init__.py +0 -0
  57. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/adapters_rect.py +0 -0
  58. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/adapters_ternary.py +0 -0
  59. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/adaptive_cdf_runtime.py +0 -0
  60. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/bin_stat_runtime.py +0 -0
  61. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/cards/std_axes_adapter_config.json +0 -0
  62. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/colorbar_runtime.py +0 -0
  63. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/config_runtime.py +0 -0
  64. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/corr_layout.py +0 -0
  65. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/corr_layout_diamond.py +0 -0
  66. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/corr_order.py +0 -0
  67. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/correlation_runtime.py +0 -0
  68. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/corrplot_runtime.py +0 -0
  69. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/data_pipelines.py +0 -0
  70. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/debug_config.py +0 -0
  71. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/density_cell_runtime.py +0 -0
  72. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/design_runtime.py +0 -0
  73. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/distribution_1d_runtime.py +0 -0
  74. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/dynesty_runtime.py +0 -0
  75. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/figure.py +0 -0
  76. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/figure_types.py +0 -0
  77. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/forest_debug.py +0 -0
  78. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/helper.py +0 -0
  79. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/interp_2d_runtime.py +0 -0
  80. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/interp_natural_neighbor.py +0 -0
  81. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/interp_natural_neighbor_exact.py +0 -0
  82. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/layer_runtime.py +0 -0
  83. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/layout_runtime.py +0 -0
  84. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/legend_runtime.py +0 -0
  85. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/method_registry.py +0 -0
  86. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/posterior_density_runtime.py +0 -0
  87. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/posterior_hpd.py +0 -0
  88. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/posterior_mesh.py +0 -0
  89. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/preprocessor.py +0 -0
  90. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/preprocessor_runtime.py +0 -0
  91. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/profile_runtime.py +0 -0
  92. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/significance_runtime.py +0 -0
  93. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/Figure/style_runtime.py +0 -0
  94. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/__init__.py +0 -0
  95. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/agent_digest.py +0 -0
  96. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/agent_io.py +0 -0
  97. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cache_registry.py +0 -0
  98. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cache_store.py +0 -0
  99. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/capabilities.py +0 -0
  100. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/dynesty_runplot.json +0 -0
  101. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/rect.json +0 -0
  102. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/rect5x1.json +0 -0
  103. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/rect_cmap.json +0 -0
  104. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/rect_marginal.json +0 -0
  105. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/2x1/rectratio.json +0 -0
  106. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/4x1/rect.json +0 -0
  107. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/4x1/rect_cmap.json +0 -0
  108. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/a4paper/4x1/ternary.json +0 -0
  109. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/args.json +0 -0
  110. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/colors/colormaps.json +0 -0
  111. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/corrplot/diamond.json +0 -0
  112. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/corrplot/matrix.json +0 -0
  113. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/default/output.json +0 -0
  114. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/flowchart/default.json +0 -0
  115. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/fonts/default.json +0 -0
  116. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/forest/swiss_column.json +0 -0
  117. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/gambit/1x1/ternary.json +0 -0
  118. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/gambit/2x1/ternary.json +0 -0
  119. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/gambit/2x1/ternary_cmap.json +0 -0
  120. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/JarvisHEP.png +0 -0
  121. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/JarvisHEP.png +0 -0
  122. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/calculator.png +0 -0
  123. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/inputfile.png +0 -0
  124. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/opera.png +0 -0
  125. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/outputfile.png +0 -0
  126. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/flowchart/sampler.png +0 -0
  127. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/gambit.png +0 -0
  128. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/icons/gambit_small.png +0 -0
  129. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/legends/compact/legend-card.json +0 -0
  130. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/legends/default/legend-card.json +0 -0
  131. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/legends/paper/legend-card.json +0 -0
  132. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/legends/presentation/legend-card.json +0 -0
  133. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cards/style_preference.json +0 -0
  134. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cli.py +0 -0
  135. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/cli_help.py +0 -0
  136. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/client.py +0 -0
  137. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/column_demand.py +0 -0
  138. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/column_probe.py +0 -0
  139. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/config.py +0 -0
  140. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/config_address.py +0 -0
  141. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/core.py +0 -0
  142. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/core_assets.py +0 -0
  143. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/core_runtime.py +0 -0
  144. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_access.py +0 -0
  145. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_generation_contracts.py +0 -0
  146. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_loader.py +0 -0
  147. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_loader_hdf5.py +0 -0
  148. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_loader_runtime.py +0 -0
  149. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/data_loader_summary.py +0 -0
  150. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/dataset_types.py +0 -0
  151. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/diagnostic_guidance.py +0 -0
  152. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/diagnostics.py +0 -0
  153. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/distribution_1d_config.py +0 -0
  154. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/dryrun_runtime.py +0 -0
  155. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/expr_names.py +0 -0
  156. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/font_runtime.py +0 -0
  157. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/fonts.py +0 -0
  158. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/forest_contract.py +0 -0
  159. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/forest_text.py +0 -0
  160. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/generated_data.py +0 -0
  161. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/inner_func.py +0 -0
  162. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/legend_cards.py +0 -0
  163. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/man_catalog.py +0 -0
  164. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/man_methods.py +0 -0
  165. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/man_render_agent.py +0 -0
  166. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/man_render_human.py +0 -0
  167. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/man_transforms.py +0 -0
  168. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/agent-output.yaml +0 -0
  169. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/agent-readme.yaml +0 -0
  170. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/cache.yaml +0 -0
  171. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/cli-map.yaml +0 -0
  172. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/data-columns.yaml +0 -0
  173. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/debug-overlay.yaml +0 -0
  174. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/diagnostics.yaml +0 -0
  175. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/doctor.yaml +0 -0
  176. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/dryrun-viz.yaml +0 -0
  177. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/field-interp.yaml +0 -0
  178. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/fonts.yaml +0 -0
  179. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/generated-data.yaml +0 -0
  180. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/layer-method.yaml +0 -0
  181. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/legend.yaml +0 -0
  182. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/manifest.yaml +0 -0
  183. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/method_notes.yaml +0 -0
  184. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/style-axes.yaml +0 -0
  185. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/type-correlation-matrix.yaml +0 -0
  186. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/type-forest.yaml +0 -0
  187. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/type-posterior-2d.yaml +0 -0
  188. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/type-profile-2d.yaml +0 -0
  189. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/workflow.yaml +0 -0
  190. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/manual_cards/yaml-root.yaml +0 -0
  191. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/memtrace.py +0 -0
  192. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/method_contracts.py +0 -0
  193. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/render_health.py +0 -0
  194. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/common.json +0 -0
  195. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/dataset.json +0 -0
  196. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/distribution-1d.json +0 -0
  197. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/figure.json +0 -0
  198. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/generated-data.json +0 -0
  199. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/layer.json +0 -0
  200. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/legend-card.json +0 -0
  201. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/legend.json +0 -0
  202. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/core/transform.json +0 -0
  203. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/manifest.json +0 -0
  204. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/bar.json +0 -0
  205. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/barh.json +0 -0
  206. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/contour.json +0 -0
  207. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/contourf.json +0 -0
  208. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/corrplot.json +0 -0
  209. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/dynesty_runplot.json +0 -0
  210. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/errorbar.json +0 -0
  211. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/fill.json +0 -0
  212. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/fill_between.json +0 -0
  213. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/fill_betweenx.json +0 -0
  214. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/hist.json +0 -0
  215. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/hist2d.json +0 -0
  216. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/imshow.json +0 -0
  217. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/jpcontour.json +0 -0
  218. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/jpcontourf.json +0 -0
  219. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/jpfield.json +0 -0
  220. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/pcolor.json +0 -0
  221. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/pcolormesh.json +0 -0
  222. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/plot.json +0 -0
  223. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/quiver.json +0 -0
  224. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/scatter.json +0 -0
  225. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/stairs.json +0 -0
  226. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/step.json +0 -0
  227. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/tricontour.json +0 -0
  228. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/tricontourf.json +0 -0
  229. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/tripcolor.json +0 -0
  230. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/tripcolor_axes.json +0 -0
  231. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/triplot.json +0 -0
  232. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/voronoi.json +0 -0
  233. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/methods/voronoif.json +0 -0
  234. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/plot-config.json +0 -0
  235. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema/types/forest.json +0 -0
  236. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema_catalog.py +0 -0
  237. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/schema_diagnostics.py +0 -0
  238. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/templates_catalog.py +0 -0
  239. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/transform_contracts.py +0 -0
  240. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/__init__.py +0 -0
  241. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/cmaps.py +0 -0
  242. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/dataframes.py +0 -0
  243. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/expression.py +0 -0
  244. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/interpolator.py +0 -0
  245. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/utils/pathing.py +0 -0
  246. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/validation.py +0 -0
  247. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/__init__.py +0 -0
  248. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/cache.py +0 -0
  249. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/cap.py +0 -0
  250. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/config_cmd.py +0 -0
  251. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/data.py +0 -0
  252. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/doctor.py +0 -0
  253. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/dryrun.py +0 -0
  254. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/explain.py +0 -0
  255. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/fonts.py +0 -0
  256. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/man.py +0 -0
  257. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/suggest.py +0 -0
  258. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/verbs/template.py +0 -0
  259. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/version.py +0 -0
  260. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/jarvisplot/yaml_io.py +0 -0
  261. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/setup.cfg +0 -0
  262. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/conftest.py +0 -0
  263. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_adaptive_cdf.py +0 -0
  264. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_add_column.py +0 -0
  265. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_agent_digest.py +0 -0
  266. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_agent_envelope.py +0 -0
  267. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_axis_title.py +0 -0
  268. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cache_cleanup.py +0 -0
  269. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cache_policy.py +0 -0
  270. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cache_registry.py +0 -0
  271. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_capabilities.py +0 -0
  272. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cli_help.py +0 -0
  273. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cli_verbs.py +0 -0
  274. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_cmaps.py +0 -0
  275. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_column_existence.py +0 -0
  276. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_column_pruning.py +0 -0
  277. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_config_addressing.py +0 -0
  278. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_config_edit.py +0 -0
  279. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_config_expand.py +0 -0
  280. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_correlation_runtime.py +0 -0
  281. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_corrplot.py +0 -0
  282. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_data_access.py +0 -0
  283. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_data_describe.py +0 -0
  284. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_data_head_eval.py +0 -0
  285. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_data_loader_contracts.py +0 -0
  286. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_data_pipelines.py +0 -0
  287. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_debug_config.py +0 -0
  288. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_debug_switches.py +0 -0
  289. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_debug_yaml_override.py +0 -0
  290. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_density_cell_transform.py +0 -0
  291. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_design_runtime.py +0 -0
  292. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_diagnostic_guidance.py +0 -0
  293. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_distribution_1d_transform.py +0 -0
  294. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_doctor_partial.py +0 -0
  295. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_examples_validate.py +0 -0
  296. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_explain.py +0 -0
  297. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_expression_semantics.py +0 -0
  298. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_figure_contracts.py +0 -0
  299. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_figure_type_expander.py +0 -0
  300. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_font_runtime.py +0 -0
  301. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_fonts.py +0 -0
  302. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_fonts_cli.py +0 -0
  303. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_forest_examples.py +0 -0
  304. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_forest_text.py +0 -0
  305. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_generated_data.py +0 -0
  306. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_imshow_adapter.py +0 -0
  307. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_interp_2d_transform.py +0 -0
  308. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_interp_natural_neighbor.py +0 -0
  309. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_interpolator_contracts.py +0 -0
  310. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_jpcontour_methods.py +0 -0
  311. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_layer_legend.py +0 -0
  312. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_legend_cards.py +0 -0
  313. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_legend_runtime.py +0 -0
  314. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_man_cli.py +0 -0
  315. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_method_contracts.py +0 -0
  316. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_parse_data_metadata.py +0 -0
  317. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_pathing_contracts.py +0 -0
  318. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_posterior_hpd.py +0 -0
  319. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_profile_runtime.py +0 -0
  320. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_release_contract.py +0 -0
  321. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_render_defects.py +0 -0
  322. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_render_health.py +0 -0
  323. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_render_lifecycle.py +0 -0
  324. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_row_ledger.py +0 -0
  325. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_savefig_provenance.py +0 -0
  326. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_schema_catalog.py +0 -0
  327. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_suggest.py +0 -0
  328. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_suggest_axes.py +0 -0
  329. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_template_catalog.py +0 -0
  330. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_ternary_debug.py +0 -0
  331. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_transform_contracts.py +0 -0
  332. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_validation_imports.py +0 -0
  333. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tests/test_version.py +0 -0
  334. {jarvisplot-2.1.12 → jarvisplot-2.1.13}/tools/check_release.py +0 -0
@@ -4,6 +4,19 @@ Release history of the `JarvisPLOT` distribution (import package `jarvisplot`,
4
4
  CLI `jplot`). User guides and reference documentation are available in
5
5
  [Jarvis-Books `Docs/Jarvis-PLOT/`](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-PLOT/README.md).
6
6
 
7
+ ## 2.1.13 — 2026-10-29
8
+ ### Fixed
9
+
10
+ - Branch flowchart connections from a module to its output files, and give each
11
+ file's output variables a separate, spaced group centered on its file icon.
12
+ - Correct A4 ternary badge image paths on case-sensitive filesystems, including
13
+ Linux, for the full-width, standard and colorbar cards.
14
+ - Keep the GAMBIT `rectcmap` colorbar label inside the page with Matplotlib 3.10
15
+ while preserving its separation from tick labels.
16
+ - Allow forest footer legends to meet the badge at their shared grid boundary
17
+ with macOS Helvetica and Matplotlib 3.10.9. Actual overlap with the badge or
18
+ description remains an error.
19
+
7
20
  ## 2.1.12 — 2026-10-19
8
21
 
9
22
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.12
3
+ Version: 2.1.13
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -19,6 +19,9 @@ Requires-Dist: scipy
19
19
  Requires-Dist: shapely
20
20
  Requires-Dist: deepmerge
21
21
  Requires-Dist: rich
22
+ Provides-Extra: test
23
+ Requires-Dist: pytest; extra == "test"
24
+ Requires-Dist: pyarrow; extra == "test"
22
25
 
23
26
  # Jarvis-PLOT
24
27
 
@@ -27,7 +30,7 @@ but it can also be used as a **standalone scientific plotting tool**.
27
30
 
28
31
  It provides a simple command-line interface (CLI) to generate publication-quality figures from YAML configuration files, with most layout and style decisions handled by predefined profiles and style cards.
29
32
 
30
- Current source candidate: **2.1.12** (`jplot -v` reports the installed version).
33
+ Current source candidate: **2.1.13** (`jplot -v` reports the installed version).
31
34
  Release history: [CHANGELOG.md](https://github.com/Pengxuan-Zhu-Phys/Jarvis-PLOT/blob/main/CHANGELOG.md). Design documents and specifications: [Jarvis-Books `Docs/Jarvis-PLOT/`](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-PLOT/README.md).
32
35
 
33
36
  ---
@@ -297,6 +297,7 @@ tests/test_fonts.py
297
297
  tests/test_fonts_cli.py
298
298
  tests/test_forest.py
299
299
  tests/test_forest_examples.py
300
+ tests/test_forest_legend.py
300
301
  tests/test_forest_text.py
301
302
  tests/test_generated_data.py
302
303
  tests/test_imshow_adapter.py
@@ -13,3 +13,7 @@ scipy
13
13
  shapely
14
14
  deepmerge
15
15
  rich
16
+
17
+ [test]
18
+ pytest
19
+ pyarrow
@@ -8,7 +8,6 @@ include tests/conftest.py
8
8
  exclude jprel
9
9
  prune docs
10
10
  prune .github
11
- prune .claude
12
11
  prune .codex
13
12
  prune .agents
14
13
  prune .cursor
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.12
3
+ Version: 2.1.13
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -19,6 +19,9 @@ Requires-Dist: scipy
19
19
  Requires-Dist: shapely
20
20
  Requires-Dist: deepmerge
21
21
  Requires-Dist: rich
22
+ Provides-Extra: test
23
+ Requires-Dist: pytest; extra == "test"
24
+ Requires-Dist: pyarrow; extra == "test"
22
25
 
23
26
  # Jarvis-PLOT
24
27
 
@@ -27,7 +30,7 @@ but it can also be used as a **standalone scientific plotting tool**.
27
30
 
28
31
  It provides a simple command-line interface (CLI) to generate publication-quality figures from YAML configuration files, with most layout and style decisions handled by predefined profiles and style cards.
29
32
 
30
- Current source candidate: **2.1.12** (`jplot -v` reports the installed version).
33
+ Current source candidate: **2.1.13** (`jplot -v` reports the installed version).
31
34
  Release history: [CHANGELOG.md](https://github.com/Pengxuan-Zhu-Phys/Jarvis-PLOT/blob/main/CHANGELOG.md). Design documents and specifications: [Jarvis-Books `Docs/Jarvis-PLOT/`](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-PLOT/README.md).
32
35
 
33
36
  ---
@@ -5,7 +5,7 @@ but it can also be used as a **standalone scientific plotting tool**.
5
5
 
6
6
  It provides a simple command-line interface (CLI) to generate publication-quality figures from YAML configuration files, with most layout and style decisions handled by predefined profiles and style cards.
7
7
 
8
- Current source candidate: **2.1.12** (`jplot -v` reports the installed version).
8
+ Current source candidate: **2.1.13** (`jplot -v` reports the installed version).
9
9
  Release history: [CHANGELOG.md](https://github.com/Pengxuan-Zhu-Phys/Jarvis-PLOT/blob/main/CHANGELOG.md). Design documents and specifications: [Jarvis-Books `Docs/Jarvis-PLOT/`](https://github.com/Pengxuan-Zhu-Phys/Jarvis-Books/blob/main/Docs/Jarvis-PLOT/README.md).
10
10
 
11
11
  ---
@@ -0,0 +1 @@
1
+ 2.1.13
@@ -6,6 +6,17 @@ from matplotlib.patches import Rectangle
6
6
  from matplotlib.offsetbox import VPacker
7
7
 
8
8
 
9
+ def boxes_overlap(first, second):
10
+ """Require positive overlap on both physical axes, measured in mm.
11
+
12
+ Footer columns and the badge share grid boundaries. Touching those edges
13
+ is valid; Bbox.overlaps also counts contact and floating-point roundoff.
14
+ """
15
+ width = min(first.xmax, second.xmax) - max(first.xmin, second.xmin)
16
+ height = min(first.ymax, second.ymax) - max(first.ymin, second.ymin)
17
+ return min(width, height) > 1e-9
18
+
19
+
9
20
  class PhysicalLegendColumn(VPacker):
10
21
  """Recompute physical column width for each raster/vector renderer."""
11
22
  def __init__(self, width_mm, **kwargs):
@@ -91,7 +91,10 @@ class ForestFigure(Figure):
91
91
  def _render(self):
92
92
  from matplotlib.patches import Rectangle
93
93
  from .legend_runtime import apply_legend
94
- from .forest_legend import ForestGlyph, HandlerForestGlyph, HandlerForestPoint, PhysicalLegendColumn, group_glyph_and_points
94
+ from .forest_legend import (
95
+ ForestGlyph, HandlerForestGlyph, HandlerForestPoint,
96
+ PhysicalLegendColumn, boxes_overlap, group_glyph_and_points,
97
+ )
95
98
  from matplotlib.collections import PathCollection
96
99
  info, layout, ax = self.info, self.forest_layout, self.axes['ax']
97
100
  g, fonts, style = layout['geometry'], layout['typography'], layout['style']
@@ -468,9 +471,9 @@ class ForestFigure(Figure):
468
471
  if legend:
469
472
  for column in legend._legend_handle_box.get_children():
470
473
  for item in column.get_children():
471
- if any(physical_box(item).overlaps(b) for b in badge_boxes):
474
+ if any(boxes_overlap(physical_box(item), b) for b in badge_boxes):
472
475
  raise ValueError('forest footer legend overlaps axlogo; adjust forest.geometry footer/legend/logo positions or frame.ax.legend layout')
473
- if any(physical_box(item).overlaps(b) for b in description_boxes):
476
+ if any(boxes_overlap(physical_box(item), b) for b in description_boxes):
474
477
  raise ValueError('forest footer legend overlaps description; adjust forest.geometry column starts or frame.ax.legend layout')
475
478
  for row, artists in annotations:
476
479
  boxes = [physical_box(artist) for artist in artists]
@@ -137,7 +137,7 @@
137
137
  },
138
138
  "axlogo": {
139
139
  "clip": false,
140
- "file": "&JP/jarvisplot/cards/icons/jarvisHEP.png"
140
+ "file": "&JP/jarvisplot/cards/icons/JarvisHEP.png"
141
141
  }
142
142
  },
143
143
  "Debug": {
@@ -134,7 +134,7 @@
134
134
  },
135
135
  "axlogo": {
136
136
  "clip": false,
137
- "file": "&JP/jarvisplot/cards/icons/jarvisHEP.png"
137
+ "file": "&JP/jarvisplot/cards/icons/JarvisHEP.png"
138
138
  }
139
139
  },
140
140
  "Debug": {
@@ -178,7 +178,7 @@
178
178
  },
179
179
  "axlogo": {
180
180
  "clip": false,
181
- "file": "&JP/jarvisplot/cards/icons/jarvisHEP.png"
181
+ "file": "&JP/jarvisplot/cards/icons/JarvisHEP.png"
182
182
  }
183
183
  },
184
184
  "Debug": {
@@ -177,7 +177,7 @@
177
177
  },
178
178
  "axlogo": {
179
179
  "clip": false,
180
- "file": "&JP/jarvisplot/cards/icons/jarvisHEP.png"
180
+ "file": "&JP/jarvisplot/cards/icons/JarvisHEP.png"
181
181
  }
182
182
  },
183
183
  "Style": {
@@ -162,7 +162,7 @@
162
162
  "fontfamily": "STIXGeneral"
163
163
  },
164
164
  "ylabel_coords": {
165
- "x": 3.7,
165
+ "x": 3.4,
166
166
  "y": 0.5
167
167
  },
168
168
  "ticks": {
@@ -12,6 +12,8 @@ from .utils.pathing import resolve_project_path
12
12
 
13
13
 
14
14
  DEFAULT_FLOWCHART_CARD = "&JP/jarvisplot/cards/flowchart/default.json"
15
+ _OUTPUT_FILE_Y_OFFSET = -0.18
16
+ _OUTPUT_FILE_GROUP_GAP = 0.22
15
17
 
16
18
 
17
19
  def _deep_merge(base: dict, override: Mapping | None) -> dict:
@@ -314,6 +316,14 @@ class FlowchartRenderer:
314
316
  ax.text(x+0.12, y-0.01, "SEL", ha="center", va="center", fontsize=5, fontweight="extra bold", color="#008A34", zorder=121, path_effects=[pe.withStroke(linewidth=0.2, foreground="white")])
315
317
 
316
318
  def _draw_classic_edges(self, ax, graph) -> None:
319
+ output_files: dict[str, set[str]] = {}
320
+ for edge in graph.edges:
321
+ source_id = str(edge.get("source", {}).get("node", ""))
322
+ target_id = str(edge.get("target", {}).get("node", ""))
323
+ if (str(edge.get("role", "dataflow")).lower() == "fileflow"
324
+ and source_id in graph.mains and target_id in graph.files):
325
+ output_files.setdefault(source_id, set()).add(target_id)
326
+
317
327
  for edge in graph.edges:
318
328
  role = str(edge.get("role", "dataflow")).lower()
319
329
  source_id = str(edge.get("source", {}).get("node", ""))
@@ -336,7 +346,10 @@ class FlowchartRenderer:
336
346
  ax.plot(start[0] + 0.03, start[1], "s", color="gray", markersize=2.0, zorder=79)
337
347
  self._classic_curve(ax, start, end, color="#D45040", lw=2.2, alpha=0.95)
338
348
  elif role == "fileflow" and graph.is_main(source_id) and graph.is_file(target_id):
339
- start = (start[0], end[1])
349
+ if len(output_files.get(source_id, ())) <= 1:
350
+ start = (start[0], end[1])
351
+ else:
352
+ start = (start[0], start[1] + _OUTPUT_FILE_Y_OFFSET)
340
353
  self._classic_curve(ax, start, end, color="#3B4DC0", lw=2.2, alpha=0.95)
341
354
  elif role == "fileflow" and graph.is_file(source_id) and graph.is_var(target_id):
342
355
  self._classic_curve(ax, start, end, color="#3B4DC0", lw=0.75, alpha=0.7)
@@ -660,14 +673,35 @@ class _ClassicGraph:
660
673
  counts = []
661
674
  for file_id in self._files_for_main(main_id, "input"):
662
675
  counts.append(len(self._incoming_variables(file_id)))
663
- for file_id in self._files_for_main(main_id, "output"):
676
+ output_files = self._files_for_main(main_id, "output")
677
+ for file_id in output_files:
664
678
  counts.append(len(self._outgoing_variables(file_id)))
665
679
  counts.append(len(self._direct_input_variables(main_id)))
666
680
  counts.append(len(self._direct_output_variables(main_id)))
667
681
  if self.nodes[main_id].get("kind") == "source":
668
682
  counts.append(len(self._outgoing_variables(main_id)))
669
683
  max_count = max(counts or [1])
670
- return max(1.25, max_count * self.var_gap + 0.45)
684
+ height = max(1.25, max_count * self.var_gap + 0.45)
685
+ if len(output_files) > 1:
686
+ output_height = sum(self._output_file_band_height(file_id) for file_id in output_files)
687
+ output_height += (len(output_files) - 1) * _OUTPUT_FILE_GROUP_GAP
688
+ height = max(height, output_height + 2 * abs(_OUTPUT_FILE_Y_OFFSET) + 0.45)
689
+ return height
690
+
691
+ def _output_file_band_height(self, file_id: str) -> float:
692
+ return max(0.65, len(self._outgoing_variables(file_id)) * self.var_gap)
693
+
694
+ def _output_file_centers(self, file_ids: list[str], center_y: float) -> list[float]:
695
+ if len(file_ids) <= 1:
696
+ return self._spread_y(center_y, len(file_ids), 0.65)
697
+ heights = [self._output_file_band_height(file_id) for file_id in file_ids]
698
+ total_height = sum(heights) + (len(file_ids) - 1) * _OUTPUT_FILE_GROUP_GAP
699
+ top = center_y + total_height / 2.0
700
+ centers = []
701
+ for height in heights:
702
+ centers.append(top - height / 2.0)
703
+ top -= height + _OUTPUT_FILE_GROUP_GAP
704
+ return centers
671
705
 
672
706
  def _place_main_group(self, main_id: str, x: float, y: float, height: float) -> None:
673
707
  node = self.nodes[main_id]
@@ -688,14 +722,14 @@ class _ClassicGraph:
688
722
  input_files = self._files_for_main(main_id, "input")
689
723
  output_files = self._files_for_main(main_id, "output")
690
724
  input_anchor_y = y + 0.18
691
- output_anchor_y = y - 0.18
725
+ output_anchor_y = y + _OUTPUT_FILE_Y_OFFSET
692
726
  for file_id, fy in zip(input_files, self._spread_y(input_anchor_y, len(input_files), 0.65)):
693
727
  self._place_file(file_id, x - self.input_file_dx, fy, "input")
694
728
  incoming = self._incoming_variables(file_id)
695
729
  for var_id in incoming:
696
730
  if var_id not in self.variables and var_id not in self.bridges:
697
731
  self._place_variable(var_id, x - self.input_variable_dx, fy, align="right")
698
- for file_id, fy in zip(output_files, self._spread_y(output_anchor_y, len(output_files), 0.65)):
732
+ for file_id, fy in zip(output_files, self._output_file_centers(output_files, output_anchor_y)):
699
733
  self._place_file(file_id, x + self.output_file_dx, fy, "output")
700
734
  self._place_variables(self._outgoing_variables(file_id), x + self.output_variable_dx, fy, align="right")
701
735
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "JarvisPLOT"
7
- version = "2.1.12"
7
+ version = "2.1.13"
8
8
  description = "Jarvis-PLOT: YAML-driven plotting engine"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -27,6 +27,9 @@ dependencies = [
27
27
  "rich"
28
28
  ]
29
29
 
30
+ [project.optional-dependencies]
31
+ test = ["pytest", "pyarrow"]
32
+
30
33
  [project.scripts]
31
34
  jplot = "jarvisplot.client:main"
32
35
 
@@ -73,3 +73,24 @@ def test_ternary_knobs_only_ship_on_cards_that_have_a_ternary_axes(relpath, _use
73
73
 
74
74
  def test_all_registered_cards_are_covered():
75
75
  assert len(CARD_FILES) >= 13
76
+
77
+
78
+ def test_card_resource_paths_match_exact_case():
79
+ """Catch Linux-only missing assets even on a case-insensitive filesystem."""
80
+ resources = {p.relative_to(ROOT).as_posix() for p in CARDS.rglob("*") if p.is_file()}
81
+ missing = []
82
+
83
+ def walk(node, card):
84
+ if isinstance(node, dict):
85
+ for value in node.values():
86
+ walk(value, card)
87
+ elif isinstance(node, list):
88
+ for value in node:
89
+ walk(value, card)
90
+ elif isinstance(node, str) and node.startswith("&JP/"):
91
+ if node.removeprefix("&JP/") not in resources:
92
+ missing.append(f"{card}: {node}")
93
+
94
+ for path in sorted(CARDS.rglob("*.json")):
95
+ walk(json.loads(path.read_text(encoding="utf-8")), path.relative_to(CARDS))
96
+ assert missing == [], "Missing or incorrectly cased card resources:\n" + "\n".join(missing)
@@ -2,8 +2,83 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
 
5
+ import pytest
6
+
5
7
  from jarvisplot import render_flowchart
6
- from jarvisplot.flowchart import _ClassicGraph, render_flowchart_file
8
+ from jarvisplot.flowchart import FlowchartRenderer, _ClassicGraph, render_flowchart_file
9
+
10
+
11
+ def test_multiple_output_files_branch_from_the_module():
12
+ import matplotlib.pyplot as plt
13
+
14
+ file_ids = ["file::Calc::output::first", "file::Calc::output::second"]
15
+ single_id = "file::Other::output::only"
16
+ scene = {
17
+ "layers": [{"id": "layer", "nodes": ["Calc", *file_ids, "Other", single_id]}],
18
+ "nodes": [
19
+ {"id": "Calc", "kind": "module", "layer": "layer"},
20
+ {"id": "Other", "kind": "module", "layer": "layer"},
21
+ *({"id": file_id, "kind": "file", "role": "output_file", "layer": "layer"}
22
+ for file_id in [*file_ids, single_id]),
23
+ ],
24
+ "edges": [
25
+ *({"source": {"node": "Calc"}, "target": {"node": file_id}, "role": "fileflow"}
26
+ for file_id in file_ids),
27
+ {"source": {"node": "Other"}, "target": {"node": single_id}, "role": "fileflow"},
28
+ ],
29
+ }
30
+ graph = _ClassicGraph(scene, {"classic": {}})
31
+ graph.layout()
32
+ fig, ax = plt.subplots()
33
+ try:
34
+ FlowchartRenderer(scene, {})._draw_classic_edges(ax, graph)
35
+ for line, file_id in zip(ax.lines[:2], file_ids):
36
+ module_x, module_y = graph.mains["Calc"]["pos"]
37
+ assert (line.get_xdata()[0], line.get_ydata()[0]) == (module_x, module_y - 0.18)
38
+ assert (line.get_xdata()[-1], line.get_ydata()[-1]) == graph.files[file_id]["pos"]
39
+ assert line.get_ydata()[0] != line.get_ydata()[-1]
40
+ assert len(set(ax.lines[2].get_ydata())) == 1
41
+ assert ax.lines[2].get_ydata()[0] == graph.files[single_id]["pos"][1]
42
+ finally:
43
+ plt.close(fig)
44
+
45
+
46
+ @pytest.mark.parametrize("counts", [(18, 4), (1, 1), (9, 0, 3)])
47
+ def test_output_file_variable_groups_have_separate_space(counts):
48
+ file_ids = [f"file::Calc::output::file{i}" for i in range(len(counts))]
49
+ variables = [[f"var::file{i}_{j}" for j in range(count)] for i, count in enumerate(counts)]
50
+ scene = {
51
+ "layers": [{"id": "layer", "nodes": ["Calc", *file_ids, "Next"]}],
52
+ "nodes": [
53
+ {"id": "Calc", "kind": "module", "layer": "layer"},
54
+ {"id": "Next", "kind": "module", "layer": "layer"},
55
+ *({"id": file_id, "kind": "file", "layer": "layer"} for file_id in file_ids),
56
+ *({"id": var_id, "kind": "variable", "layer": "layer"}
57
+ for group in variables for var_id in group),
58
+ ],
59
+ "edges": [
60
+ *({"source": {"node": "Calc"}, "target": {"node": file_id}, "role": "fileflow"}
61
+ for file_id in file_ids),
62
+ *({"source": {"node": file_id}, "target": {"node": var_id}, "role": "fileflow"}
63
+ for file_id, group in zip(file_ids, variables) for var_id in group),
64
+ ],
65
+ }
66
+ graph = _ClassicGraph(scene, {"classic": {"group_gap": 0.1}})
67
+ graph.layout()
68
+
69
+ previous_y = None
70
+ for file_id, group in zip(file_ids, variables):
71
+ file_y = graph.files[file_id]["pos"][1]
72
+ ys = [graph.variables[var_id]["pos"][1] for var_id in group]
73
+ if ys:
74
+ assert file_y == pytest.approx((ys[0] + ys[-1]) / 2)
75
+ if previous_y is not None:
76
+ assert previous_y - ys[0] >= graph.var_gap + 0.22 - 1e-9
77
+ previous_y = ys[-1]
78
+ file_ys = [graph.files[file_id]["pos"][1] for file_id in file_ids]
79
+ assert all(a - b >= 0.65 - 1e-9 for a, b in zip(file_ys, file_ys[1:]))
80
+ next_group_top = graph.mains["Next"]["pos"][1] + graph.mains["Next"]["height"] / 2
81
+ assert min(file_ys + [graph.variables[v]["pos"][1] for group in variables for v in group]) > next_group_top
7
82
 
8
83
 
9
84
  def test_render_flowchart_scene_with_selectionflow(tmp_path):
@@ -702,6 +702,13 @@ def test_grouped_legend_retains_empty_semantic_column(group, tmp_path):
702
702
  assert occupied.get_children()[0].get_children()[-1]._text.get_text().replace('\n', ' ') == ('Estimate + bounds' if group == 'glyph' else 'Ordinary')
703
703
 
704
704
 
705
+ def test_footer_legend_still_rejects_actual_badge_overlap(tmp_path):
706
+ info, frames = fixture()
707
+ info['forest'] = {'geometry': {'logo_bottom_mm': 5}}
708
+ with pytest.raises(ValueError, match='footer legend overlaps axlogo'):
709
+ draw(info, frames, tmp_path)
710
+
711
+
705
712
  def test_yaml_description_moves_to_third_footer_column_without_losing_text(tmp_path):
706
713
  config, bag = validate_file(str(EXAMPLE/'real-demo.yaml'))
707
714
  assert bag.ok
@@ -0,0 +1,39 @@
1
+ """Footer collisions distinguish shared grid edges from occupied area."""
2
+ import numpy as np
3
+ import pytest
4
+ from matplotlib.transforms import Bbox
5
+
6
+ from jarvisplot.Figure.forest_legend import boxes_overlap
7
+
8
+
9
+ @pytest.mark.parametrize(
10
+ 'badge_right', [8.541666666666668, np.nextafter(8.541666666666668, np.inf)],
11
+ )
12
+ def test_legend_may_touch_the_badge_at_its_grid_boundary(badge_right):
13
+ # Native 3.10.9 Helvetica layout: vertical ranges overlap by 0.064 mm,
14
+ # but the legend starts exactly at the badge's right edge.
15
+ item = Bbox.from_extents(8.541666666666668, 33.5, 23.4682, 37.0221)
16
+ badge = Bbox.from_extents(2, 36.9583, badge_right, 43.5)
17
+ assert not boxes_overlap(item, badge)
18
+ assert not boxes_overlap(badge, item)
19
+
20
+
21
+ def test_positive_legend_badge_overlap_is_still_a_collision():
22
+ item = Bbox.from_extents(8.541666666666668, 33.5, 23.4682, 37.0221)
23
+ badge = Bbox.from_extents(2, 36.9583, 8.551666666666668, 43.5)
24
+ assert boxes_overlap(item, badge)
25
+ assert boxes_overlap(badge, item)
26
+
27
+
28
+ def test_empty_semantic_legend_column_does_not_occupy_area():
29
+ empty = Bbox.from_extents(5, 5, 5, 5)
30
+ badge = Bbox.from_extents(2, 2, 8, 8)
31
+ assert not boxes_overlap(empty, badge)
32
+
33
+
34
+ def test_legend_may_touch_description_at_a_horizontal_edge():
35
+ item = Bbox.from_extents(8, 30, 23, 37)
36
+ description = Bbox.from_extents(15, 37, 45, 42)
37
+ assert not boxes_overlap(item, description)
38
+ description = Bbox.from_extents(15, 36.99, 45, 42)
39
+ assert boxes_overlap(item, description)
jarvisplot-2.1.12/VERSION DELETED
@@ -1 +0,0 @@
1
- 2.1.12