jarvisplot 2.1.1__tar.gz → 2.1.2__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 (241) hide show
  1. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/PKG-INFO +1 -1
  2. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/PKG-INFO +1 -1
  3. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/corr_layout_diamond.py +9 -0
  4. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/corrplot_runtime.py +203 -26
  5. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/corrplot/diamond.json +2 -2
  6. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/core_runtime.py +11 -2
  7. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/pyproject.toml +1 -1
  8. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_corrplot.py +318 -0
  9. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/SOURCES.txt +0 -0
  10. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/dependency_links.txt +0 -0
  11. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/entry_points.txt +0 -0
  12. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/requires.txt +0 -0
  13. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/JarvisPLOT.egg-info/top_level.txt +0 -0
  14. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/README.md +0 -0
  15. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/__init__.py +0 -0
  16. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/adapters_rect.py +0 -0
  17. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/adapters_ternary.py +0 -0
  18. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/bin_stat_runtime.py +0 -0
  19. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/cards/std_axes_adapter_config.json +0 -0
  20. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/colorbar_runtime.py +0 -0
  21. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/config_runtime.py +0 -0
  22. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/corr_layout.py +0 -0
  23. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/corr_order.py +0 -0
  24. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/correlation_runtime.py +0 -0
  25. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/data_pipelines.py +0 -0
  26. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/debug_config.py +0 -0
  27. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/density_cell_runtime.py +0 -0
  28. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/design_runtime.py +0 -0
  29. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/dynesty_runtime.py +0 -0
  30. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/figure.py +0 -0
  31. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/figure_types.py +0 -0
  32. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/helper.py +0 -0
  33. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/interp_2d_runtime.py +0 -0
  34. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/interp_natural_neighbor.py +0 -0
  35. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/interp_natural_neighbor_exact.py +0 -0
  36. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/layer_runtime.py +0 -0
  37. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/layout_runtime.py +0 -0
  38. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/method_registry.py +0 -0
  39. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/posterior_density_runtime.py +0 -0
  40. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/posterior_hpd.py +0 -0
  41. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/posterior_mesh.py +0 -0
  42. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/preprocessor.py +0 -0
  43. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/preprocessor_runtime.py +0 -0
  44. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/profile_runtime.py +0 -0
  45. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/significance_runtime.py +0 -0
  46. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/Figure/style_runtime.py +0 -0
  47. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/__init__.py +0 -0
  48. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/agent_digest.py +0 -0
  49. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/agent_io.py +0 -0
  50. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cache_store.py +0 -0
  51. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/capabilities.py +0 -0
  52. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/1x1/ternary.json +0 -0
  53. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/dynesty_runplot.json +0 -0
  54. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/rect.json +0 -0
  55. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/rect5x1.json +0 -0
  56. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/rect_cmap.json +0 -0
  57. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/rect_marginal.json +0 -0
  58. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/rectratio.json +0 -0
  59. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/ternary.json +0 -0
  60. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/2x1/ternary_cmap.json +0 -0
  61. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/4x1/rect.json +0 -0
  62. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/4x1/rect_cmap.json +0 -0
  63. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/4x1/ternary.json +0 -0
  64. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/a4paper/4x1/ternary_cmap.json +0 -0
  65. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/args.json +0 -0
  66. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/colors/colormaps.json +0 -0
  67. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/corrplot/matrix.json +0 -0
  68. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/default/output.json +0 -0
  69. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/flowchart/default.json +0 -0
  70. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/gambit/1x1/ternary.json +0 -0
  71. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/gambit/2x1/rect_cmap.json +0 -0
  72. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/gambit/2x1/ternary.json +0 -0
  73. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/gambit/2x1/ternary_cmap.json +0 -0
  74. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/JarvisHEP.png +0 -0
  75. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/JarvisHEP.png +0 -0
  76. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/calculator.png +0 -0
  77. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/inputfile.png +0 -0
  78. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/opera.png +0 -0
  79. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/outputfile.png +0 -0
  80. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/flowchart/sampler.png +0 -0
  81. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/gambit.png +0 -0
  82. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/icons/gambit_small.png +0 -0
  83. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cards/style_preference.json +0 -0
  84. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cli.py +0 -0
  85. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/cli_help.py +0 -0
  86. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/client.py +0 -0
  87. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/column_demand.py +0 -0
  88. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/column_probe.py +0 -0
  89. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/config.py +0 -0
  90. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/config_address.py +0 -0
  91. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/core.py +0 -0
  92. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/core_assets.py +0 -0
  93. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/data_access.py +0 -0
  94. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/data_loader.py +0 -0
  95. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/data_loader_hdf5.py +0 -0
  96. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/data_loader_runtime.py +0 -0
  97. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/data_loader_summary.py +0 -0
  98. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/dataset_types.py +0 -0
  99. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/diagnostic_guidance.py +0 -0
  100. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/diagnostics.py +0 -0
  101. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/dryrun_runtime.py +0 -0
  102. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/expr_names.py +0 -0
  103. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/fix_apply.py +0 -0
  104. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/flowchart.py +0 -0
  105. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/inner_func.py +0 -0
  106. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/man_catalog.py +0 -0
  107. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/man_methods.py +0 -0
  108. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/man_render_agent.py +0 -0
  109. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/man_render_human.py +0 -0
  110. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/man_transforms.py +0 -0
  111. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/agent-output.yaml +0 -0
  112. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/cli-map.yaml +0 -0
  113. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/data-columns.yaml +0 -0
  114. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/debug-overlay.yaml +0 -0
  115. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/diagnostics.yaml +0 -0
  116. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/dryrun-viz.yaml +0 -0
  117. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/layer-method.yaml +0 -0
  118. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/manifest.yaml +0 -0
  119. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/method_notes.yaml +0 -0
  120. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/style-axes.yaml +0 -0
  121. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/type-correlation-matrix.yaml +0 -0
  122. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/type-posterior-2d.yaml +0 -0
  123. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/type-profile-2d.yaml +0 -0
  124. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/validate.yaml +0 -0
  125. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/workflow.yaml +0 -0
  126. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/manual_cards/yaml-root.yaml +0 -0
  127. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/memtrace.py +0 -0
  128. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/method_contracts.py +0 -0
  129. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/render_health.py +0 -0
  130. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/core/common.json +0 -0
  131. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/core/dataset.json +0 -0
  132. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/core/figure.json +0 -0
  133. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/core/layer.json +0 -0
  134. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/core/transform.json +0 -0
  135. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/manifest.json +0 -0
  136. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/bar.json +0 -0
  137. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/barh.json +0 -0
  138. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/contour.json +0 -0
  139. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/contourf.json +0 -0
  140. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/corrplot.json +0 -0
  141. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/dynesty_runplot.json +0 -0
  142. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/errorbar.json +0 -0
  143. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/fill.json +0 -0
  144. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/fill_between.json +0 -0
  145. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/fill_betweenx.json +0 -0
  146. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/hist.json +0 -0
  147. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/hist2d.json +0 -0
  148. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/imshow.json +0 -0
  149. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/jpcontour.json +0 -0
  150. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/jpcontourf.json +0 -0
  151. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/jpfield.json +0 -0
  152. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/pcolor.json +0 -0
  153. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/pcolormesh.json +0 -0
  154. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/plot.json +0 -0
  155. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/quiver.json +0 -0
  156. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/scatter.json +0 -0
  157. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/stairs.json +0 -0
  158. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/step.json +0 -0
  159. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/tricontour.json +0 -0
  160. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/tricontourf.json +0 -0
  161. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/tripcolor.json +0 -0
  162. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/tripcolor_axes.json +0 -0
  163. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/triplot.json +0 -0
  164. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/voronoi.json +0 -0
  165. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/methods/voronoif.json +0 -0
  166. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema/plot-config.json +0 -0
  167. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema_catalog.py +0 -0
  168. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/schema_diagnostics.py +0 -0
  169. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/templates_catalog.py +0 -0
  170. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/transform_contracts.py +0 -0
  171. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/__init__.py +0 -0
  172. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/cmaps.py +0 -0
  173. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/dataframes.py +0 -0
  174. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/expression.py +0 -0
  175. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/interpolator.py +0 -0
  176. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/utils/pathing.py +0 -0
  177. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/validation.py +0 -0
  178. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/__init__.py +0 -0
  179. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/cap.py +0 -0
  180. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/config_cmd.py +0 -0
  181. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/data.py +0 -0
  182. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/doctor.py +0 -0
  183. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/dryrun.py +0 -0
  184. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/explain.py +0 -0
  185. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/man.py +0 -0
  186. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/suggest.py +0 -0
  187. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/template.py +0 -0
  188. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/verbs/validate.py +0 -0
  189. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/jarvisplot/yaml_io.py +0 -0
  190. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/setup.cfg +0 -0
  191. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_agent_digest.py +0 -0
  192. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_agent_envelope.py +0 -0
  193. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_axis_title.py +0 -0
  194. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_capabilities.py +0 -0
  195. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_card_debug_shape.py +0 -0
  196. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_cli_help.py +0 -0
  197. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_cli_verbs.py +0 -0
  198. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_cmaps.py +0 -0
  199. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_column_existence.py +0 -0
  200. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_config_addressing.py +0 -0
  201. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_config_edit.py +0 -0
  202. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_config_expand.py +0 -0
  203. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_correlation_runtime.py +0 -0
  204. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_data_access.py +0 -0
  205. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_data_describe.py +0 -0
  206. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_data_head_eval.py +0 -0
  207. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_data_loader_contracts.py +0 -0
  208. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_data_pipelines.py +0 -0
  209. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_debug_config.py +0 -0
  210. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_debug_switches.py +0 -0
  211. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_debug_yaml_override.py +0 -0
  212. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_density_cell_transform.py +0 -0
  213. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_design_runtime.py +0 -0
  214. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_diagnostic_guidance.py +0 -0
  215. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_docs_status_labels.py +0 -0
  216. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_doctor_partial.py +0 -0
  217. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_explain.py +0 -0
  218. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_figure_contracts.py +0 -0
  219. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_figure_type_expander.py +0 -0
  220. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_fix_application.py +0 -0
  221. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_flowchart_renderer.py +0 -0
  222. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_imshow_adapter.py +0 -0
  223. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_interp_2d_transform.py +0 -0
  224. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_interp_natural_neighbor.py +0 -0
  225. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_interpolator_contracts.py +0 -0
  226. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_jpcontour_methods.py +0 -0
  227. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_man_cli.py +0 -0
  228. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_method_contracts.py +0 -0
  229. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_parse_data_metadata.py +0 -0
  230. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_pathing_contracts.py +0 -0
  231. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_posterior_hpd.py +0 -0
  232. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_render_health.py +0 -0
  233. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_row_ledger.py +0 -0
  234. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_schema_catalog.py +0 -0
  235. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_suggest.py +0 -0
  236. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_suggest_axes.py +0 -0
  237. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_template_catalog.py +0 -0
  238. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_template_json.py +0 -0
  239. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_ternary_debug.py +0 -0
  240. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_transform_contracts.py +0 -0
  241. {jarvisplot-2.1.1 → jarvisplot-2.1.2}/tests/test_validate_no_matplotlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: JarvisPLOT
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: Jarvis-PLOT: YAML-driven plotting engine
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -63,6 +63,15 @@ def diamond_extent(n: int, *, diag: bool = False) -> tuple[float, float, float,
63
63
 
64
64
  With ``diag`` the self-pairs come in at ``u = 0`` and push both ranges out
65
65
  by half a cell.
66
+
67
+ A half, not the quarter the pentagon of
68
+ :func:`corrplot_runtime._self_cell_vertices` actually reaches: that shape
69
+ is how a *fill* keeps a whole cell's area against the edge, and the round
70
+ glyphs do not take it. A circle on the diagonal is a circle, and at the
71
+ quarter it overhung the panel by 0.07 cells -- which is only 0.3 mm, but it
72
+ is 0.3 mm off the one gap the eye checks, the channel between the matrix
73
+ and the names, and it narrowed it on the diagonal rows alone. The panel
74
+ buys the half so that every glyph fits whatever shape it is.
66
75
  """
67
76
  n = max(int(n), 2)
68
77
  if diag:
@@ -161,6 +161,14 @@ _DIAMOND_ROUND = 1.0 / np.sqrt(2.0)
161
161
  #: because a divider that is *nearly* the cell divider reads as a mistake.
162
162
  _GRID_LWD = 0.3
163
163
 
164
+ #: Where the tint sits: under everything. It is the background the figure is
165
+ #: drawn *on*, so it takes the lowest layer on the axes rather than one derived
166
+ #: from the glyph's -- an axis draws its own tick labels at 2.5, and a tint
167
+ #: placed relative to the glyphs lands above that and prints over the names.
168
+ #: Its three pieces (the cells, the notch, the band under the label) are one
169
+ #: band and share one number, so they cannot drift apart.
170
+ _TINT_ZORDER = 0.4
171
+
164
172
  #: Square glyphs are a polygon per cell and nothing else, so they skip the
165
173
  #: patch objects entirely -- see :func:`_glyph_vertices`.
166
174
  _POLYGON_GLYPHS = ("square", "color", "shade")
@@ -171,21 +179,87 @@ _POLYGON_GLYPHS = ("square", "color", "shade")
171
179
  _FILLED_GLYPHS = ("color", "shade")
172
180
 
173
181
 
174
- def _notch_vertices(n: int, side: str = "left"):
182
+ #: How far a self cell reaches past the matrix's near edge, in cells. See
183
+ #: :func:`_self_cell_vertices` -- it is what makes the pentagon's area a cell.
184
+ _SELF_REACH = 0.25
185
+
186
+
187
+ def _self_cell_vertices(rows, side: str = "left", scale: float = 1.0):
188
+ """``(m, 5, 2)`` outlines for the cells on the diagonal.
189
+
190
+ A variable's pair with *itself* sits at ``u = 0``, so half of an ordinary
191
+ cell would hang off the matrix and print over the names. Clipping it
192
+ instead leaves a triangle -- half the area of every other cell, which reads
193
+ as a fainter diagonal rather than as the constant it is.
194
+
195
+ So it is neither: the cell keeps its point into the matrix and is squared
196
+ off on the outside, and the rectangle that squares it off is exactly deep
197
+ enough to pay back what the clip took. The triangle is ``1/4``, the
198
+ rectangle is ``a x 1``, so ``a = 1/4`` puts the pentagon at ``1/2`` -- the
199
+ area of a whole cell, for every variable, which is the only way a diagonal
200
+ of constant rho can look constant.
201
+
202
+ It fits without moving anything: the wedge beside each name is empty by
203
+ construction (see :func:`_notch_vertices`, which is what used to fill it)
204
+ and the quarter cell outside is page the panel takes from the gap.
205
+
206
+ ``scale`` shrinks it about ``(0, k)`` exactly as ``glyph.scale`` shrinks
207
+ every other cell. Without it these are the only shapes on the figure drawn
208
+ at full size, and since they also stack without a gap in ``v`` they fuse
209
+ into one bar down the edge instead of reading as a cell each.
210
+ """
211
+ k = np.asarray(rows, dtype=float)
212
+ flip = -1.0 if side == "right" else 1.0
213
+ zero = np.zeros_like(k)
214
+ half = 0.5 * float(scale)
215
+ back = flip * -2.0 * _SELF_REACH * half + zero
216
+ point, edge = flip * half + zero, half
217
+ return np.stack(
218
+ [
219
+ np.stack([back, k - edge], axis=1),
220
+ np.stack([zero, k - edge], axis=1),
221
+ np.stack([point, k], axis=1),
222
+ np.stack([zero, k + edge], axis=1),
223
+ np.stack([back, k + edge], axis=1),
224
+ ],
225
+ axis=1,
226
+ )
227
+
228
+
229
+ def _notch_vertices(n: int, side: str = "left", diag: bool = False):
175
230
  """The half cells that make the matrix's near edge straight.
176
231
 
177
- A variable's V has its vertex at ``(0, k)``, and the two cells meeting
178
- there touch the edge at a point, not along it -- so the boundary beside the
179
- names comes out as a row of notches. The notch at ``k`` is the triangle
180
- ``(0, k-1/2) (1/2, k) (0, k+1/2)``: filling it with that variable's own
181
- tint carries the band from the name into the matrix without a gap, and
182
- turns the sawtooth into the straight edge the rules can close against.
232
+ Whatever stands at ``u = 0`` meets the edge beside the names at a *point*,
233
+ so that boundary comes out as a row of notches and the tint carrying a
234
+ variable's band in from its name pinches to nothing there. Filling the
235
+ notch is what turns the sawtooth into the straight edge the rules close
236
+ against, and the band into one band.
237
+
238
+ The diagonal moves the notch, it does not remove it -- which is what an
239
+ earlier version of this card assumed, and the band broke on every shaded
240
+ row. Without the diagonal the near edge is ``u = 0`` and the first cells
241
+ are the pairs at ``u = 1/2``, so the gap is the triangle
242
+ ``(0, k-1/2) (1/2, k) (0, k+1/2)`` *inside* the matrix. With it the near
243
+ edge is ``u = -1/2`` and the self cell's own left corner is the point, so
244
+ the gap is the pair of triangles either side of it -- together with that
245
+ corner, the rectangle ``[-1/2, 0] x [k-1/2, k+1/2]``.
183
246
 
184
247
  Returned for every variable; the caller picks the tinted ones.
185
248
  """
186
249
  k = np.arange(int(n), dtype=float)
187
250
  flip = -1.0 if side == "right" else 1.0
188
251
  zero = np.zeros_like(k)
252
+ if diag:
253
+ back = flip * -0.5 + zero
254
+ return np.stack(
255
+ [
256
+ np.stack([back, k - 0.5], axis=1),
257
+ np.stack([zero, k - 0.5], axis=1),
258
+ np.stack([zero, k + 0.5], axis=1),
259
+ np.stack([back, k + 0.5], axis=1),
260
+ ],
261
+ axis=1,
262
+ )
189
263
  return np.stack(
190
264
  [
191
265
  np.stack([zero, k - 0.5], axis=1),
@@ -329,13 +403,25 @@ def _label_rules(ax, n: int, span, color, lw: float, clip: bool,
329
403
  colour and weight rather than a nearby pair, because a divider that only
330
404
  nearly matches reads as a second, different thing.
331
405
 
406
+ It starts where the *cells* meet, not where the axes end. Two cells of one
407
+ row touch at ``u = 0`` whichever layout is drawn -- without the diagonal
408
+ that is also the panel's near edge, so the two were the same number and the
409
+ difference never showed. With the diagonal the panel reaches half a cell
410
+ further out, and a rule begun at the edge leaves that half cell unruled:
411
+ the line between two names starts in mid air instead of at the matrix.
412
+
332
413
  Below the tick labels, like the band: an axis draws its labels at zorder
333
414
  2.5, and a rule over one of them is a strike-through.
334
415
  """
335
416
  from matplotlib.collections import LineCollection
336
417
 
337
418
  target = ax.ax if hasattr(ax, "ax") else ax
338
- x0, x1 = span
419
+ try:
420
+ lo, hi = target.get_xlim()
421
+ meet = (0.0 - float(lo)) / (float(hi) - float(lo))
422
+ except Exception:
423
+ meet = span[1] if span[0] < 0.0 else span[0]
424
+ x0, x1 = min(span[0], meet), max(span[1], meet)
339
425
  rules = LineCollection(
340
426
  [[(x0, k + 0.5), (x1, k + 0.5)] for k in range(int(n) - 1)],
341
427
  colors=color, linewidths=lw, zorder=0.6,
@@ -409,7 +495,7 @@ def _stripe_the_labels(ax, n: int, shaded, span, color, clip: bool) -> None:
409
495
  ax.axhspan(
410
496
  k - 0.5, k + 0.5, xmin=span[0], xmax=span[1],
411
497
  facecolor=color, edgecolor="none", linewidth=0.0,
412
- zorder=0.5, clip_on=clip,
498
+ zorder=_TINT_ZORDER, clip_on=clip,
413
499
  )
414
500
 
415
501
 
@@ -464,7 +550,7 @@ def _glyph_vertices(kind: str, cx, cy, rho, scale: float, corners=None):
464
550
 
465
551
 
466
552
  def _glyph_patches(kind: str, cx, cy, rho, scale: float, sign: float,
467
- ellipse_scale: float = 1.4):
553
+ ellipse_scale: float = 1.4, diamond: bool = False):
468
554
  """One matplotlib patch per drawn cell, in data coordinates.
469
555
 
470
556
  Only the round glyphs come through here; the square ones are built as bare
@@ -494,7 +580,22 @@ def _glyph_patches(kind: str, cx, cy, rho, scale: float, sign: float,
494
580
  # the box does not -- so at k = glyph.scale the widest one covers
495
581
  # 0.64 of the cell while a circle covers 0.9. sqrt(2) is the
496
582
  # factor that makes the two agree, which is where 1.4 comes from.
583
+ #
584
+ # And it is the *cell's* diagonal, not the page's. `ellipse` is
585
+ # the one glyph with a direction, and its direction means something
586
+ # about the two axes of the cell it sits in: turn the lattice 45
587
+ # degrees and leave the ellipse behind and every one of them is
588
+ # reporting the wrong pair. The index map sends the cell's own
589
+ # frame through a +45 degree rotation (`j+1` goes to `(+1/2, +1/2)`
590
+ # and `i+1` to `(-1/2, +1/2)`), so the glyph turns with it.
591
+ #
592
+ # `side: right` negates u, which reflects rather than rotates and
593
+ # sends an angle A to 135 - A. It needs no case of its own: the
594
+ # angle here is a constant +/-45, and 135 - A and A + 45 differ by
595
+ # 180 exactly when they differ at all -- and an ellipse's angle is
596
+ # read modulo 180.
497
597
  k = scale * ellipse_scale
598
+ lean = sign * 45.0 + (45.0 if diamond else 0.0)
498
599
  r = 0.0 if not np.isfinite(r) else float(np.clip(r, -1.0, 1.0))
499
600
  width = k * np.sqrt(max(1.0 + r, 0.0)) / np.sqrt(2.0)
500
601
  # |rho| = 1 collapses the minor axis to zero, which fills no
@@ -503,7 +604,7 @@ def _glyph_patches(kind: str, cx, cy, rho, scale: float, sign: float,
503
604
  # as a line, so the minor axis gets a hairline floor.
504
605
  height = max(k * np.sqrt(max(1.0 - r, 0.0)) / np.sqrt(2.0), 0.02 * k)
505
606
  patches.append(
506
- Ellipse((x, y), width=width, height=height, angle=sign * 45.0)
607
+ Ellipse((x, y), width=width, height=height, angle=lean)
507
608
  )
508
609
  elif kind == "pie":
509
610
  # Clockwise from twelve o'clock, as read off the page.
@@ -721,14 +822,53 @@ def draw_corrplot(ax, **kwargs):
721
822
  if sig_level is not None and insig == "blank":
722
823
  drawn &= ~insignificant
723
824
 
825
+ # The diagonal, when it is in. A self pair sits at `u = 0`, so anything
826
+ # built from an ordinary cell there hangs a quarter of a cell past the
827
+ # panel and prints over the names -- and everything on this figure except
828
+ # `_stripe_the_labels` is drawn well above the axis' own zorder of 2.5, so
829
+ # it prints *over* them, not under. Every shape cut from a cell therefore
830
+ # takes the pentagon on the diagonal: the fill, the grid outline, and the
831
+ # tint. See `_self_cell_vertices`.
832
+ self_cells = drawn & (index_x.astype(int) == index_y.astype(int))
833
+
834
+ def _with_self_cells(shapes, selection, closed_loop: bool, shape_scale=1.0):
835
+ """Swap the pentagon in wherever `shapes` covers a self pair.
836
+
837
+ `selection` is the mask over *all* cells that `shapes` was built from,
838
+ which is not the same mask each time -- the fill is drawn for `drawn`,
839
+ the tint for the shaded band, the grid for everything.
840
+ """
841
+ picked = self_cells[selection]
842
+ if not diamond or not np.any(picked):
843
+ return shapes
844
+ out = [np.asarray(shape) for shape in shapes]
845
+ pentagons = _self_cell_vertices(iy[selection & self_cells], side, shape_scale)
846
+ for slot, pentagon in zip(np.flatnonzero(picked), pentagons):
847
+ out[slot] = (
848
+ np.vstack([pentagon, pentagon[:1]]) if closed_loop else pentagon
849
+ )
850
+ return out
851
+
724
852
  label_span = _label_span(ax, side, label_column_mm) if diamond else None
725
853
 
726
854
  if diamond and edge_lwd > 0.0 and label_span is not None:
727
855
  # The column is a width in axes fractions; the outline is drawn in cell
728
- # units, and the panel is `u_span` cells wide.
729
- column_u = -label_span[0] * (n / 2.0) if side == "left" else (
730
- (label_span[1] - 1.0) * (n / 2.0)
731
- )
856
+ # units, so it is scaled by how many cells wide the panel is. Read off
857
+ # the axes rather than worked out as `n / 2`: with the diagonal in, the
858
+ # panel is a quarter cell wider than that (see `diamond_extent`), and a
859
+ # rule scaled by the wrong span stops short of the names it is meant to
860
+ # close over -- by 4% of the column, which at thirteen variables is the
861
+ # last two letters of the longest name left hanging outside it.
862
+ lo, hi = float(min(ax.get_xlim())), float(max(ax.get_xlim()))
863
+ u_span = hi - lo
864
+ # ... and measured from the panel's own near edge, which the diagonal
865
+ # moves out to `u = -1/4`. `_edge_rules` strikes the horizontal run
866
+ # from `-column_u` to `0`, so the near edge has to be added back in:
867
+ # left out, the rule stops a quarter cell short and the last letters of
868
+ # the longest name hang outside the box it is meant to close.
869
+ near_u = lo if side == "left" else -hi
870
+ column_u = (-label_span[0] if side == "left" else label_span[1] - 1.0)
871
+ column_u = column_u * u_span - near_u
732
872
  _edge_rules(ax, n, column_u, side, edge_color, edge_lwd, zorder + 40, clip)
733
873
  if diamond and grid_color and label_span is not None:
734
874
  _label_rules(ax, n, label_span, grid_color, _GRID_LWD, clip, zorder)
@@ -763,19 +903,25 @@ def draw_corrplot(ax, **kwargs):
763
903
  band = shaded[index_x.astype(int)] | shaded[index_y.astype(int)]
764
904
  band &= drawn
765
905
  if np.any(band):
906
+ # The tint is a background and keeps the plain cell, diagonal
907
+ # included: it has to reach the panel's edge or the band it carries
908
+ # from the name into the matrix comes apart there. It can, because
909
+ # the panel buys the whole half cell -- which is also what stops it
910
+ # printing over the names, and that is a clearance, not a shape.
766
911
  cells = PolyCollection(
767
912
  np.stack([ix[band], iy[band]], axis=1)[:, None, :]
768
913
  + 0.5 * _DIAMOND_CORNERS[None, :, :],
769
914
  closed=True, facecolors=stripe_color, edgecolors="none",
770
- zorder=zorder - 20,
915
+ zorder=_TINT_ZORDER,
771
916
  )
772
917
  cells.set_clip_on(clip)
773
918
  ax.add_collection(cells)
774
919
  # The half cells beside the names, so the band reaches the matrix and
775
920
  # the edge it makes is straight enough for the rules to close against.
921
+ # The diagonal moves this, it does not remove it: see `_notch_vertices`.
776
922
  notches = PolyCollection(
777
- _notch_vertices(n, side)[shaded], closed=True,
778
- facecolors=stripe_color, edgecolors="none", zorder=zorder - 20,
923
+ _notch_vertices(n, side, diag)[shaded], closed=True,
924
+ facecolors=stripe_color, edgecolors="none", zorder=_TINT_ZORDER,
779
925
  )
780
926
  notches.set_clip_on(clip)
781
927
  ax.add_collection(notches)
@@ -790,9 +936,13 @@ def draw_corrplot(ax, **kwargs):
790
936
  else:
791
937
  if kind in _POLYGON_GLYPHS:
792
938
  artists = PolyCollection(
793
- _glyph_vertices(
794
- kind, ix[drawn], iy[drawn], rho[drawn], scale,
795
- corners=_DIAMOND_CORNERS if diamond else _CORNERS,
939
+ _with_self_cells(
940
+ _glyph_vertices(
941
+ kind, ix[drawn], iy[drawn], rho[drawn], scale,
942
+ corners=_DIAMOND_CORNERS if diamond else _CORNERS,
943
+ ),
944
+ drawn if kind in _FILLED_GLYPHS else np.zeros(ix.shape, dtype=bool),
945
+ closed_loop=False, shape_scale=scale,
796
946
  ),
797
947
  closed=True,
798
948
  )
@@ -800,7 +950,7 @@ def draw_corrplot(ax, **kwargs):
800
950
  artists = PatchCollection(
801
951
  _glyph_patches(
802
952
  kind, ix[drawn], iy[drawn], rho[drawn], round_scale, sign,
803
- ellipse_scale=ellipse_scale,
953
+ ellipse_scale=ellipse_scale, diamond=diamond,
804
954
  ),
805
955
  match_original=False,
806
956
  )
@@ -847,14 +997,27 @@ def draw_corrplot(ax, **kwargs):
847
997
  if kind == "shade":
848
998
  # The sign is already in the colour; the hatch is what survives a
849
999
  # greyscale print, which is the whole point of shade.
1000
+ #
1001
+ # It runs corner to corner of the cell, and *which* corners is the
1002
+ # layout's business. On the square card those are the diagonal ones,
1003
+ # `(+/-1, +/-1) * half`. On the diamond the same cell is turned 45
1004
+ # degrees, so its corners are the ones straight up and straight across
1005
+ # -- and a stroke still drawn to `(+/-1, +/-1)` reaches `half * sqrt2`
1006
+ # where the cell only reaches `half / sqrt2`: twice too long, over the
1007
+ # boundary and into the neighbour, on every cell of the figure.
1008
+ step = 0.5 * scale
1009
+ arm = (
1010
+ [(0.0, step), (step, 0.0)] if diamond else [(step, step), (step, -step)]
1011
+ )
850
1012
  hatch = LineCollection(
851
1013
  [
852
1014
  [
853
- (x - 0.5 * scale, y - sign * 0.5 * scale * np.sign(r)),
854
- (x + 0.5 * scale, y + sign * 0.5 * scale * np.sign(r)),
1015
+ (x - dx, y - sign * dy * np.sign(r)),
1016
+ (x + dx, y + sign * dy * np.sign(r)),
855
1017
  ]
856
1018
  for x, y, r in zip(ix[drawn], iy[drawn], rho[drawn])
857
1019
  if r != 0.0
1020
+ for dx, dy in [arm[0] if r > 0 else arm[1]]
858
1021
  ],
859
1022
  colors="#FFFFFF",
860
1023
  linewidths=0.4,
@@ -868,9 +1031,23 @@ def draw_corrplot(ax, **kwargs):
868
1031
  # picture, a quarter of the paths, and at 100 variables that is 40,000
869
1032
  # of them. The outline has to be per cell rather than n+1 ruled lines
870
1033
  # because a `triangle` selection leaves holes for the ruling to cross.
1034
+ # The pentagon is a shape for glyphs that *fill* their cell. Outlining
1035
+ # it under a round one would be drawing a boundary the glyph does not
1036
+ # keep: at `rho = 1` the circle on the diagonal overhangs it, and the
1037
+ # flat backs line up into a grey rail down the edge of the matrix with
1038
+ # the circles straddling it. So there the diagonal simply carries no
1039
+ # outline -- the matrix's own edge is already closed by `edge.lwd`.
1040
+ ruled = (
1041
+ np.ones(ix.shape, dtype=bool)
1042
+ if not diamond or kind in _FILLED_GLYPHS
1043
+ else ~self_cells
1044
+ )
871
1045
  grid = LineCollection(
872
- np.stack([ix, iy], axis=1)[:, None, :]
873
- + (_DIAMOND_LOOP if diamond else _CELL_LOOP)[None, :, :],
1046
+ _with_self_cells(
1047
+ np.stack([ix[ruled], iy[ruled]], axis=1)[:, None, :]
1048
+ + (_DIAMOND_LOOP if diamond else _CELL_LOOP)[None, :, :],
1049
+ ruled, closed_loop=True,
1050
+ ),
874
1051
  colors=grid_color, linewidths=_GRID_LWD, zorder=zorder - 10,
875
1052
  )
876
1053
  grid.set_clip_on(clip)
@@ -496,7 +496,7 @@
496
496
  "Options": {
497
497
  "method": {"type": "enum", "values": ["circle", "square", "ellipse", "color", "shade", "pie", "number"], "default": "circle"},
498
498
  "type": {"type": "enum", "values": ["upper", "lower"], "default": "upper", "forbidden": ["full"]},
499
- "diag": {"type": "boolean", "default": false},
499
+ "diag": {"type": "boolean", "default": true},
500
500
  "side": {"type": "enum", "values": ["left", "right"], "default": "right"},
501
501
  "stripe": {"type": "enum", "values": ["alternate", "none"], "default": "alternate", "false_alias": "none"},
502
502
  "order": {"type": "enum", "values": ["original", "AOE", "FPC", "hclust", "alphabet"], "default": "original"},
@@ -511,7 +511,7 @@
511
511
  "corrplot": {
512
512
  "method": "circle",
513
513
  "type": "upper",
514
- "diag": false,
514
+ "diag": true,
515
515
  "glyph.scale": 0.9,
516
516
  "ellipse.scale": 1.4,
517
517
  "outline": "sign",
@@ -895,8 +895,17 @@ def _prebuild_one(core, info: dict, card: Mapping) -> None:
895
895
  _enforce_corr_contract(info, contract, name)
896
896
 
897
897
  source = entry.get("source")
898
- dts = (getattr(core, "dataset_registry", {}) or {}).get(
899
- source if isinstance(source, str) else None
898
+ # A correlation layer may intentionally concatenate several root
899
+ # datasets. The runtime already supports source lists; the prebuild only
900
+ # needs one member's cheap column metadata to solve the shared geometry.
901
+ # Use the first registered member (the input tables are required to carry
902
+ # the same schema), while leaving the complete source list for the actual
903
+ # correlation transform below.
904
+ registry = getattr(core, "dataset_registry", {}) or {}
905
+ source_names = [source] if isinstance(source, str) else list(source or [])
906
+ dts = next(
907
+ (registry.get(item) for item in source_names if isinstance(item, str) and registry.get(item) is not None),
908
+ None,
900
909
  )
901
910
  names = list(getattr(dts, "keys", None) or [])
902
911
  if not names:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "JarvisPLOT"
7
- version = "2.1.1"
7
+ version = "2.1.2"
8
8
  description = "Jarvis-PLOT: YAML-driven plotting engine"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"