ultraplot 2.1.9__tar.gz → 2.2.0__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 (465) hide show
  1. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/workflows/publish-pypi.yml +1 -2
  2. {ultraplot-2.1.9/ultraplot.egg-info → ultraplot-2.2.0}/PKG-INFO +2 -2
  3. ultraplot-2.2.0/docs/_scripts/fetch_releases.py +154 -0
  4. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/custom.css +38 -0
  5. {ultraplot-2.1.9 → ultraplot-2.2.0}/environment.yml +2 -0
  6. {ultraplot-2.1.9 → ultraplot-2.2.0}/pyproject.toml +1 -1
  7. {ultraplot-2.1.9 → ultraplot-2.2.0}/tools/release/publish_zenodo.py +53 -2
  8. ultraplot-2.2.0/ultraplot/_version.py +1 -0
  9. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/base.py +54 -15
  10. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/geo.py +133 -73
  11. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot.py +24 -3
  12. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/figure.py +121 -77
  13. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/labels.py +1 -3
  14. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_axes.py +31 -0
  15. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colorbar.py +308 -0
  16. ultraplot-2.2.0/ultraplot/tests/test_docs_fetch_releases.py +172 -0
  17. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_release_metadata.py +6 -2
  18. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_subplots.py +38 -0
  19. {ultraplot-2.1.9 → ultraplot-2.2.0/ultraplot.egg-info}/PKG-INFO +2 -2
  20. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot.egg-info/SOURCES.txt +1 -0
  21. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot.egg-info/requires.txt +1 -1
  22. ultraplot-2.1.9/docs/_scripts/fetch_releases.py +0 -139
  23. ultraplot-2.1.9/ultraplot/_version.py +0 -1
  24. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/ISSUE_TEMPLATE.md +0 -0
  25. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/dependabot.yml +0 -0
  26. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/micromamba-condarc.yml +0 -0
  27. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/workflows/build-ultraplot.yml +0 -0
  28. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/workflows/main.yml +0 -0
  29. {ultraplot-2.1.9 → ultraplot-2.2.0}/.github/workflows/test-map.yml +0 -0
  30. {ultraplot-2.1.9 → ultraplot-2.2.0}/.gitignore +0 -0
  31. {ultraplot-2.1.9 → ultraplot-2.2.0}/.pre-commit-config.yaml +0 -0
  32. {ultraplot-2.1.9 → ultraplot-2.2.0}/.readthedocs.yml +0 -0
  33. {ultraplot-2.1.9 → ultraplot-2.2.0}/CITATION.cff +0 -0
  34. {ultraplot-2.1.9 → ultraplot-2.2.0}/CODEOFCONDUCT.md +0 -0
  35. {ultraplot-2.1.9 → ultraplot-2.2.0}/CONTRIBUTING.rst +0 -0
  36. {ultraplot-2.1.9 → ultraplot-2.2.0}/INSTALL.rst +0 -0
  37. {ultraplot-2.1.9 → ultraplot-2.2.0}/LICENSE.txt +0 -0
  38. {ultraplot-2.1.9 → ultraplot-2.2.0}/README.rst +0 -0
  39. {ultraplot-2.1.9 → ultraplot-2.2.0}/UltraPlotLogo.svg +0 -0
  40. {ultraplot-2.1.9 → ultraplot-2.2.0}/codecov.yml +0 -0
  41. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/1dplots.py +0 -0
  42. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/2dplots.py +0 -0
  43. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/Makefile +0 -0
  44. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_ext/notoc.py +0 -0
  45. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/custom.js +0 -0
  46. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/cartesian_example.svg +0 -0
  47. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/colorbars_legends_example.svg +0 -0
  48. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/colormaps_example.svg +0 -0
  49. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/panels_example.svg +0 -0
  50. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/projection_example.svg +0 -0
  51. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/example_plots/subplot_example.svg +0 -0
  52. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_blank.svg +0 -0
  53. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_long.png +0 -0
  54. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_long.svg +0 -0
  55. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_social.png +0 -0
  56. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_social.svg +0 -0
  57. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_static/logo_square.png +0 -0
  58. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/_templates/whatsnew_sidebar.html +0 -0
  59. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/about.rst +0 -0
  60. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/api.rst +0 -0
  61. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/basics.py +0 -0
  62. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/cartesian.py +0 -0
  63. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/colorbars_legends.py +0 -0
  64. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/colormaps.py +0 -0
  65. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/colors.py +0 -0
  66. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/conf.py +0 -0
  67. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/configuration.rst +0 -0
  68. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/contributing.rst +0 -0
  69. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/cycles.py +0 -0
  70. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/README.txt +0 -0
  71. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/colors/01_cycle_colormap.py +0 -0
  72. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/colors/02_diverging_colormap.py +0 -0
  73. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/colors/README.txt +0 -0
  74. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/geo/01_robin_tracks.py +0 -0
  75. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/geo/02_orthographic_views.py +0 -0
  76. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/geo/03_projections_features.py +0 -0
  77. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/geo/04_choropleth.py +0 -0
  78. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/geo/README.txt +0 -0
  79. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/layouts/01_shared_axes_abc.py +0 -0
  80. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/layouts/02_complex_layout_insets.py +0 -0
  81. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/layouts/03_spanning_labels.py +0 -0
  82. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/layouts/README.txt +0 -0
  83. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/legends_colorbars/01_multi_colorbars.py +0 -0
  84. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/legends_colorbars/02_legend_inset_colorbar.py +0 -0
  85. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/legends_colorbars/03_semantic_legends.py +0 -0
  86. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/legends_colorbars/README.txt +0 -0
  87. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/01_curved_quiver.py +0 -0
  88. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/02_network_graph.py +0 -0
  89. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/03_lollipop.py +0 -0
  90. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/04_datetime_series.py +0 -0
  91. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/05_box_violin.py +0 -0
  92. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/06_ridge_plot.py +0 -0
  93. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/07_radar.py +0 -0
  94. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/07_sankey.py +0 -0
  95. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/08_chord_diagram.py +0 -0
  96. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/08_ternary.py +0 -0
  97. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/09_phylogeny.py +0 -0
  98. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/10_circos_bed.py +0 -0
  99. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/11_topic_ribbon.py +0 -0
  100. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/examples/plot_types/README.txt +0 -0
  101. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/external-links.rst +0 -0
  102. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/faq.rst +0 -0
  103. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/fonts.py +0 -0
  104. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/index.rst +0 -0
  105. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/insets_panels.py +0 -0
  106. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/install.rst +0 -0
  107. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/lazy_loading.rst +0 -0
  108. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/make.bat +0 -0
  109. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/networks.py +0 -0
  110. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/projections.py +0 -0
  111. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/requirements-rtd.txt +0 -0
  112. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/sphinxext/custom_roles.py +0 -0
  113. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/sphinxext/jupytext_cache.py +0 -0
  114. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/stats.py +0 -0
  115. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/subplots.py +0 -0
  116. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/ultraplotrc +0 -0
  117. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/usage.rst +0 -0
  118. {ultraplot-2.1.9 → ultraplot-2.2.0}/docs/why.rst +0 -0
  119. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/PermanentMarker-Regular.ttf +0 -0
  120. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/environment-logo.yml +0 -0
  121. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/logo.py +0 -0
  122. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/run-linter.sh +0 -0
  123. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/webicon.py +0 -0
  124. {ultraplot-2.1.9 → ultraplot-2.2.0}/logo/whyUltraPlot.svg +0 -0
  125. {ultraplot-2.1.9 → ultraplot-2.2.0}/noxfile.py +0 -0
  126. {ultraplot-2.1.9 → ultraplot-2.2.0}/requirements-minimal.txt +0 -0
  127. {ultraplot-2.1.9 → ultraplot-2.2.0}/setup.cfg +0 -0
  128. {ultraplot-2.1.9 → ultraplot-2.2.0}/tools/ci/build_test_map.py +0 -0
  129. {ultraplot-2.1.9 → ultraplot-2.2.0}/tools/ci/select_tests.py +0 -0
  130. {ultraplot-2.1.9 → ultraplot-2.2.0}/tools/ci/version_support.py +0 -0
  131. {ultraplot-2.1.9 → ultraplot-2.2.0}/tools/release/sync_citation.py +0 -0
  132. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/__init__.py +0 -0
  133. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/_lazy.py +0 -0
  134. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/__init__.py +0 -0
  135. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/cartesian.py +0 -0
  136. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/container.py +0 -0
  137. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot_types/__init__.py +0 -0
  138. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot_types/circlize.py +0 -0
  139. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot_types/curved_quiver.py +0 -0
  140. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot_types/ribbon.py +0 -0
  141. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/plot_types/sankey.py +0 -0
  142. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/polar.py +0 -0
  143. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/shared.py +0 -0
  144. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/axes/three.py +0 -0
  145. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Algae.rgb +0 -0
  146. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Amp.rgb +0 -0
  147. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/BR.rgb +0 -0
  148. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Balance.rgb +0 -0
  149. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues1_r.xml +0 -0
  150. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues2.xml +0 -0
  151. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues3.xml +0 -0
  152. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues4_r.xml +0 -0
  153. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues5.xml +0 -0
  154. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues6.xml +0 -0
  155. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues7.xml +0 -0
  156. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues8.xml +0 -0
  157. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Blues9.xml +0 -0
  158. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Boreal.json +0 -0
  159. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns1.xml +0 -0
  160. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns2.xml +0 -0
  161. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns3.xml +0 -0
  162. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns4.xml +0 -0
  163. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns5.xml +0 -0
  164. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns6.xml +0 -0
  165. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns7.xml +0 -0
  166. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns8.xml +0 -0
  167. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Browns9.xml +0 -0
  168. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/ColdHot.rgb +0 -0
  169. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Crest.rgb +0 -0
  170. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Curl.rgb +0 -0
  171. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Deep.rgb +0 -0
  172. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Delta.rgb +0 -0
  173. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Dense.rgb +0 -0
  174. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Div.json +0 -0
  175. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/DryWet.json +0 -0
  176. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Dusk.json +0 -0
  177. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Fire.json +0 -0
  178. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Flare.rgb +0 -0
  179. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Glacial.json +0 -0
  180. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens1_r.xml +0 -0
  181. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens2.xml +0 -0
  182. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens3_r.xml +0 -0
  183. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens4.xml +0 -0
  184. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens5.xml +0 -0
  185. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens6_r.xml +0 -0
  186. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens7.xml +0 -0
  187. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Greens8.xml +0 -0
  188. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Haline.rgb +0 -0
  189. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Ice.rgb +0 -0
  190. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/IceFire.rgb +0 -0
  191. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Mako.rgb +0 -0
  192. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Marine.json +0 -0
  193. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Matter.rgb +0 -0
  194. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Mono.txt +0 -0
  195. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/MonoCycle.txt +0 -0
  196. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/NegPos.json +0 -0
  197. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Oranges1.xml +0 -0
  198. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Oranges2.xml +0 -0
  199. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Oranges3.xml +0 -0
  200. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Oranges4.xml +0 -0
  201. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Oxy.rgb +0 -0
  202. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Phase.rgb +0 -0
  203. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Purples1_r.xml +0 -0
  204. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Purples2.xml +0 -0
  205. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Purples3.xml +0 -0
  206. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Reds1.xml +0 -0
  207. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Reds2.xml +0 -0
  208. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Reds3.xml +0 -0
  209. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Reds4.xml +0 -0
  210. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Reds5.xml +0 -0
  211. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Rocket.rgb +0 -0
  212. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Solar.rgb +0 -0
  213. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Speed.rgb +0 -0
  214. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Stellar.json +0 -0
  215. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Sunrise.json +0 -0
  216. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Sunset.json +0 -0
  217. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Tempo.rgb +0 -0
  218. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Thermal.rgb +0 -0
  219. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Turbid.rgb +0 -0
  220. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Vivid.xml +0 -0
  221. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Vlag.rgb +0 -0
  222. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Yellows1.xml +0 -0
  223. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Yellows2.xml +0 -0
  224. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Yellows3.xml +0 -0
  225. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/Yellows4.xml +0 -0
  226. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/acton.txt +0 -0
  227. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/bam.txt +0 -0
  228. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/bamO.txt +0 -0
  229. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/bamako.txt +0 -0
  230. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/batlow.txt +0 -0
  231. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/batlowK.txt +0 -0
  232. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/batlowW.txt +0 -0
  233. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/berlin.txt +0 -0
  234. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/bilbao.txt +0 -0
  235. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/broc.txt +0 -0
  236. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/brocO.txt +0 -0
  237. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/buda.txt +0 -0
  238. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/bukavu.txt +0 -0
  239. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/cork.txt +0 -0
  240. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/corkO.txt +0 -0
  241. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/davos.txt +0 -0
  242. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/devon.txt +0 -0
  243. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/fes.txt +0 -0
  244. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/hawaii.txt +0 -0
  245. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/imola.txt +0 -0
  246. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/lajolla.txt +0 -0
  247. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/lapaz.txt +0 -0
  248. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/lisbon.txt +0 -0
  249. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/nuuk.txt +0 -0
  250. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/oleron.txt +0 -0
  251. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/oslo.txt +0 -0
  252. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/roma.txt +0 -0
  253. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/romaO.txt +0 -0
  254. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/tofino.txt +0 -0
  255. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/tokyo.txt +0 -0
  256. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/turku.txt +0 -0
  257. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/vanimo.txt +0 -0
  258. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/vik.txt +0 -0
  259. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cmaps/vikO.txt +0 -0
  260. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/colorbar.py +0 -0
  261. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/colors/opencolor.txt +0 -0
  262. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/colors/xkcd.txt +0 -0
  263. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/colors.py +0 -0
  264. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/config.py +0 -0
  265. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/constructor.py +0 -0
  266. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/538.hex +0 -0
  267. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/FlatUI.hex +0 -0
  268. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/Qual1.rgb +0 -0
  269. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/Qual2.rgb +0 -0
  270. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/bmh.hex +0 -0
  271. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/classic.hex +0 -0
  272. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/colorblind.hex +0 -0
  273. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/colorblind10.hex +0 -0
  274. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/default.hex +0 -0
  275. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/ggplot.hex +0 -0
  276. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/seaborn.hex +0 -0
  277. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/cycles/tableau.hex +0 -0
  278. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/demos.py +0 -0
  279. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/externals/__init__.py +0 -0
  280. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/externals/hsluv.py +0 -0
  281. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-Bold.ttf +0 -0
  282. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-ExtraLight.ttf +0 -0
  283. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-Heavy.ttf +0 -0
  284. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-Light.ttf +0 -0
  285. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-Medium.ttf +0 -0
  286. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-Regular.ttf +0 -0
  287. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-SemiBold.ttf +0 -0
  288. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraMath-UltraLight.ttf +0 -0
  289. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Black.ttf +0 -0
  290. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-BlackItalic.ttf +0 -0
  291. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Bold.ttf +0 -0
  292. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-BoldItalic.ttf +0 -0
  293. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-ExtraBold.ttf +0 -0
  294. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-ExtraBoldItalic.ttf +0 -0
  295. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-ExtraLight.ttf +0 -0
  296. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-ExtraLightItalic.ttf +0 -0
  297. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Italic.ttf +0 -0
  298. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Light.ttf +0 -0
  299. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-LightItalic.ttf +0 -0
  300. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Medium.ttf +0 -0
  301. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-MediumItalic.ttf +0 -0
  302. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-Regular.ttf +0 -0
  303. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-SemiBold.ttf +0 -0
  304. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/FiraSans-SemiBoldItalic.ttf +0 -0
  305. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_FIRAMATH.txt +0 -0
  306. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_FIRASANS.txt +0 -0
  307. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_NOTOSANS.txt +0 -0
  308. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_NOTOSERIF.txt +0 -0
  309. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_OPENSANS.txt +0 -0
  310. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_ROBOTO.txt +0 -0
  311. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_SOURCESANS.txt +0 -0
  312. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_SOURCESERIF.txt +0 -0
  313. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_TEXGYRE.txt +0 -0
  314. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/LICENSE_UBUNTU.txt +0 -0
  315. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSans-Bold.ttf +0 -0
  316. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSans-BoldItalic.ttf +0 -0
  317. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSans-Italic.ttf +0 -0
  318. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSans-Regular.ttf +0 -0
  319. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSerif-Bold.ttf +0 -0
  320. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSerif-BoldItalic.ttf +0 -0
  321. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSerif-Italic.ttf +0 -0
  322. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/NotoSerif-Regular.ttf +0 -0
  323. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-Bold.ttf +0 -0
  324. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-BoldItalic.ttf +0 -0
  325. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-Italic.ttf +0 -0
  326. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-Regular.ttf +0 -0
  327. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-Semibold.ttf +0 -0
  328. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  329. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Black.ttf +0 -0
  330. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-BlackItalic.ttf +0 -0
  331. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Bold.ttf +0 -0
  332. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-BoldItalic.ttf +0 -0
  333. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Italic.ttf +0 -0
  334. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Light.ttf +0 -0
  335. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-LightItalic.ttf +0 -0
  336. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Medium.ttf +0 -0
  337. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-MediumItalic.ttf +0 -0
  338. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Roboto-Regular.ttf +0 -0
  339. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-Black.ttf +0 -0
  340. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-BlackItalic.ttf +0 -0
  341. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-Bold.ttf +0 -0
  342. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-BoldItalic.ttf +0 -0
  343. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-ExtraLight.ttf +0 -0
  344. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
  345. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-Italic.ttf +0 -0
  346. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-Light.ttf +0 -0
  347. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-LightItalic.ttf +0 -0
  348. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-Regular.ttf +0 -0
  349. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-SemiBold.ttf +0 -0
  350. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
  351. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-Black.ttf +0 -0
  352. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-BlackItalic.ttf +0 -0
  353. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-Bold.ttf +0 -0
  354. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-BoldItalic.ttf +0 -0
  355. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-ExtraLight.ttf +0 -0
  356. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-ExtraLightItalic.ttf +0 -0
  357. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-Italic.ttf +0 -0
  358. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-Light.ttf +0 -0
  359. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-LightItalic.ttf +0 -0
  360. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-Regular.ttf +0 -0
  361. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-SemiBold.ttf +0 -0
  362. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/SourceSerifPro-SemiBoldItalic.ttf +0 -0
  363. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-Bold.ttf +0 -0
  364. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-BoldItalic.ttf +0 -0
  365. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-Italic.ttf +0 -0
  366. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-Light.ttf +0 -0
  367. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-LightItalic.ttf +0 -0
  368. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-Medium.ttf +0 -0
  369. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-MediumItalic.ttf +0 -0
  370. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/Ubuntu-Regular.ttf +0 -0
  371. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreadventor-bold.ttf +0 -0
  372. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreadventor-bolditalic.ttf +0 -0
  373. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreadventor-italic.ttf +0 -0
  374. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreadventor-regular.ttf +0 -0
  375. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrebonum-bold.ttf +0 -0
  376. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrebonum-bolditalic.ttf +0 -0
  377. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrebonum-italic.ttf +0 -0
  378. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrebonum-regular.ttf +0 -0
  379. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrechorus-mediumitalic.ttf +0 -0
  380. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrecursor-bold.ttf +0 -0
  381. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrecursor-bolditalic.ttf +0 -0
  382. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrecursor-italic.ttf +0 -0
  383. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrecursor-regular.ttf +0 -0
  384. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreheros-bold.ttf +0 -0
  385. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreheros-bolditalic.ttf +0 -0
  386. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreheros-italic.ttf +0 -0
  387. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreheros-regular.ttf +0 -0
  388. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrepagella-bold.ttf +0 -0
  389. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrepagella-bolditalic.ttf +0 -0
  390. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrepagella-italic.ttf +0 -0
  391. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyrepagella-regular.ttf +0 -0
  392. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreschola-bold.ttf +0 -0
  393. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreschola-bolditalic.ttf +0 -0
  394. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreschola-italic.ttf +0 -0
  395. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyreschola-regular.ttf +0 -0
  396. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyretermes-bold.ttf +0 -0
  397. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyretermes-bolditalic.ttf +0 -0
  398. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyretermes-italic.ttf +0 -0
  399. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/fonts/texgyretermes-regular.ttf +0 -0
  400. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/gridspec.py +0 -0
  401. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/__init__.py +0 -0
  402. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/benchmarks.py +0 -0
  403. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/context.py +0 -0
  404. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/docstring.py +0 -0
  405. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/fonts.py +0 -0
  406. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/guides.py +0 -0
  407. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/inputs.py +0 -0
  408. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/rcsetup.py +0 -0
  409. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/versions.py +0 -0
  410. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/internals/warnings.py +0 -0
  411. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/legend.py +0 -0
  412. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/proj.py +0 -0
  413. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/scale.py +0 -0
  414. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/__init__.py +0 -0
  415. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/conftest.py +0 -0
  416. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_1dplots.py +0 -0
  417. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_2dplots.py +0 -0
  418. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_animation.py +0 -0
  419. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_axes_base_colorbar_helpers.py +0 -0
  420. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_base.py +0 -0
  421. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_circlize_integration.py +0 -0
  422. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colorbar_helpers_extra.py +0 -0
  423. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colormap.py +0 -0
  424. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colormap_helpers_extra.py +0 -0
  425. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colors.py +0 -0
  426. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_colors_helpers.py +0 -0
  427. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_config.py +0 -0
  428. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_config_helpers_extra.py +0 -0
  429. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_constructor.py +0 -0
  430. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_constructor_helpers_extra.py +0 -0
  431. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_core_versions.py +0 -0
  432. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_demos.py +0 -0
  433. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_docs.py +0 -0
  434. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_external_axes_container_integration.py +0 -0
  435. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_external_container_edge_cases.py +0 -0
  436. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_external_container_mocked.py +0 -0
  437. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_figure.py +0 -0
  438. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_fonts.py +0 -0
  439. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_format.py +0 -0
  440. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_geographic.py +0 -0
  441. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_gridspec.py +0 -0
  442. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_handlers.py +0 -0
  443. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_imports.py +0 -0
  444. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_imshow.py +0 -0
  445. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_inputs.py +0 -0
  446. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_inputs_helpers.py +0 -0
  447. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_inset.py +0 -0
  448. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_integration.py +0 -0
  449. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_legend.py +0 -0
  450. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_plot.py +0 -0
  451. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_proj_helpers.py +0 -0
  452. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_projections.py +0 -0
  453. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_rcsetup_helpers.py +0 -0
  454. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_scale_helpers.py +0 -0
  455. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_statistical_plotting.py +0 -0
  456. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_text_helpers.py +0 -0
  457. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_tickers.py +0 -0
  458. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/tests/test_ultralayout.py +0 -0
  459. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/text.py +0 -0
  460. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/ticker.py +0 -0
  461. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/ui.py +0 -0
  462. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/ultralayout.py +0 -0
  463. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot/utils.py +0 -0
  464. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot.egg-info/dependency_links.txt +0 -0
  465. {ultraplot-2.1.9 → ultraplot-2.2.0}/ultraplot.egg-info/top_level.txt +0 -0
@@ -3,8 +3,7 @@ name: Publish to PyPI
3
3
  on:
4
4
  pull_request:
5
5
  push:
6
- tags:
7
- - "v*"
6
+ tags: ["v*"]
8
7
 
9
8
  concurrency:
10
9
  group: publish-pypi-${{ github.sha }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultraplot
3
- Version: 2.1.9
3
+ Version: 2.2.0
4
4
  Summary: A succinct matplotlib wrapper for making beautiful, publication-quality graphics.
5
5
  Author-email: Casper van Elteren <caspervanelteren@gmail.com>, Luke Davis <lukelbd@gmail.com>
6
6
  Maintainer-email: Casper van Elteren <caspervanelteren@gmail.com>, "Matthew R. Becker" <becker.mr@gmail.com>
@@ -29,7 +29,7 @@ Provides-Extra: docs
29
29
  Requires-Dist: jupyter; extra == "docs"
30
30
  Requires-Dist: jupytext; extra == "docs"
31
31
  Requires-Dist: lxml-html-clean; extra == "docs"
32
- Requires-Dist: m2r2; extra == "docs"
32
+ Requires-Dist: markdown; extra == "docs"
33
33
  Requires-Dist: mpltern; extra == "docs"
34
34
  Requires-Dist: nbsphinx; extra == "docs"
35
35
  Requires-Dist: sphinx; extra == "docs"
@@ -0,0 +1,154 @@
1
+ """
2
+ Dynamically build the "What's new?" page from the GitHub releases feed.
3
+
4
+ The release notes on GitHub are written in Markdown and frequently mix raw
5
+ HTML (``<details><summary>`` blocks wrapping fenced code samples). The
6
+ previous implementation converted the body to RST via ``m2r2``, which left
7
+ the inner Markdown code fences inside ``.. raw:: html`` directives — Sphinx
8
+ then rendered them as literal text. This module instead converts each
9
+ release body to HTML (so fences become ``<pre><code>`` elements) and emits
10
+ a single ``.. raw:: html`` block per release wrapped in a styling hook
11
+ ``div.uplt-whats-new-release-body``.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import re
17
+ from pathlib import Path
18
+ from typing import Iterable
19
+
20
+ import markdown
21
+ import requests
22
+
23
+ GITHUB_REPO = "ultraplot/ultraplot"
24
+ OUTPUT_RST = Path("whats_new.rst")
25
+ GITHUB_API_URL = f"https://api.github.com/repos/{GITHUB_REPO}/releases"
26
+
27
+ # Markdown extensions: fenced code (for ```python blocks), tables, attribute
28
+ # lists for class hooks, and md_in_html so block-level HTML such as
29
+ # ``<details>`` correctly contains parsed Markdown children.
30
+ _MD_EXTENSIONS = ("fenced_code", "tables", "attr_list", "md_in_html")
31
+
32
+ # Strip the trailing "by @user in PR_URL" attribution that GitHub auto-adds
33
+ # to release notes. Keep the PR link in parentheses so credit/traceability
34
+ # remains while removing the contributor handles from rendered output.
35
+ # GitHub author handles can include ``[bot]`` suffixes (``@dependabot[bot]``,
36
+ # ``@pre-commit-ci[bot]``); ``\w`` alone misses the brackets.
37
+ _PR_ATTRIBUTION = re.compile(
38
+ r" by @[\w.\-]+(?:\[bot\])? in (https://github\.com/[^\s]+)"
39
+ )
40
+
41
+ # Match an ATX heading line, tolerating up-to-3 leading spaces. Authors
42
+ # occasionally indent whole sections by two spaces in the GitHub release
43
+ # editor (e.g. v2.0.1's "### Layout, Rendering, and Geo Improvements"),
44
+ # which python-markdown then parses as a paragraph rather than a heading.
45
+ # We capture the ``#`` run so we can both strip the indent and downgrade
46
+ # one level — the page already provides the H1 ("What's new?") and each
47
+ # release contributes a per-release RST H2, so body headings start at H2.
48
+ _ATX_HEADING = re.compile(r"^[ ]{0,3}(#{1,5})(?=\s)", flags=re.MULTILINE)
49
+
50
+
51
+ def _strip_pr_attribution(text: str) -> str:
52
+ return _PR_ATTRIBUTION.sub(r" (\1)", text)
53
+
54
+
55
+ def _downgrade_headings(text: str) -> str:
56
+ """Demote every Markdown ATX heading by one level (``#`` → ``##``, etc.)."""
57
+ return _ATX_HEADING.sub(lambda m: "#" + m.group(1), text)
58
+
59
+
60
+ def _normalize_unicode(text: str) -> str:
61
+ return text.replace("→", "->")
62
+
63
+
64
+ def _indent_html(html: str, indent: str = " ") -> str:
65
+ """Indent every line of ``html`` by ``indent`` for inclusion under ``.. raw:: html``."""
66
+ return "\n".join(indent + line if line else line for line in html.splitlines())
67
+
68
+
69
+ def format_release_body(text: str) -> str:
70
+ """
71
+ Convert a GitHub release body (Markdown + embedded HTML) into an RST
72
+ ``.. raw:: html`` block wrapped in ``div.uplt-whats-new-release-body``.
73
+
74
+ Parameters
75
+ ----------
76
+ text : str
77
+ Raw Markdown release body as returned by the GitHub releases API.
78
+
79
+ Returns
80
+ -------
81
+ str
82
+ Indented RST snippet ready to be appended to ``whats_new.rst``.
83
+ """
84
+ cleaned = _downgrade_headings(
85
+ _normalize_unicode(_strip_pr_attribution(text or ""))
86
+ ).strip()
87
+ html_body = markdown.markdown(cleaned, extensions=list(_MD_EXTENSIONS))
88
+ wrapped = f'<div class="uplt-whats-new-release-body">\n{html_body}\n</div>'
89
+ return ".. raw:: html\n\n" + _indent_html(wrapped) + "\n"
90
+
91
+
92
+ def _format_release_title(release: dict) -> str:
93
+ """
94
+ Build the per-release section title in ``"<tag>: <name>"`` form,
95
+ de-duplicating the tag if it is already a prefix of the release name.
96
+ """
97
+ tag = release["tag_name"].lower()
98
+ title = (release.get("name") or "").strip()
99
+ if title.lower().startswith(tag):
100
+ title = title[len(tag) :].lstrip(" :-—–")
101
+ return f"{tag}: {title}" if title else tag
102
+
103
+
104
+ def fetch_all_releases() -> list[dict]:
105
+ """Fetch every GitHub release across paginated responses."""
106
+ releases: list[dict] = []
107
+ page = 1
108
+ while True:
109
+ response = requests.get(GITHUB_API_URL, params={"per_page": 30, "page": page})
110
+ if response.status_code != 200:
111
+ print(f"Error fetching releases: {response.status_code}")
112
+ break
113
+ page_data = response.json()
114
+ if not page_data:
115
+ break
116
+ releases.extend(page_data)
117
+ page += 1
118
+ return releases
119
+
120
+
121
+ def _render_releases(releases: Iterable[dict]) -> str:
122
+ """Render an iterable of release dicts to the full ``whats_new.rst`` body."""
123
+ header = "What's new?"
124
+ out = f".. _whats_new:\n\n{header}\n{'=' * len(header)}\n\n"
125
+ for release in releases:
126
+ title = _format_release_title(release)
127
+ date = release["published_at"][:10]
128
+ heading = f"{title} ({date})"
129
+ out += f"{heading}\n{'-' * len(heading)}\n\n"
130
+ out += format_release_body(release.get("body") or "") + "\n"
131
+ return out
132
+
133
+
134
+ def fetch_releases() -> str:
135
+ """Fetch the latest releases from GitHub and format them as RST."""
136
+ releases = fetch_all_releases()
137
+ if not releases:
138
+ print("Error fetching releases!")
139
+ return ""
140
+ return _render_releases(releases)
141
+
142
+
143
+ def write_rst() -> None:
144
+ """Write fetched releases to ``whats_new.rst``."""
145
+ content = fetch_releases()
146
+ if content:
147
+ OUTPUT_RST.write_text(content, encoding="utf-8")
148
+ print(f"Updated {OUTPUT_RST}")
149
+ else:
150
+ print("No updates to write.")
151
+
152
+
153
+ if __name__ == "__main__":
154
+ write_rst()
@@ -1212,3 +1212,41 @@ body.wy-body-for-nav
1212
1212
  border-radius: 0.2rem;
1213
1213
  background: var(--uplt-color-sidebar-bg);
1214
1214
  }
1215
+
1216
+ /* What's-new release bodies generated by docs/_scripts/fetch_releases.py.
1217
+ Each release is emitted inside a <div class="uplt-whats-new-release-body">
1218
+ so we have a single styling hook for spacing, code-block padding, and the
1219
+ <details> snippet affordance. */
1220
+ .uplt-whats-new-release-body {
1221
+ margin-top: 0.5rem;
1222
+ margin-bottom: 1.5rem;
1223
+ }
1224
+
1225
+ .uplt-whats-new-release-body h2,
1226
+ .uplt-whats-new-release-body h3,
1227
+ .uplt-whats-new-release-body h4 {
1228
+ margin-top: 1.25rem;
1229
+ margin-bottom: 0.5rem;
1230
+ }
1231
+
1232
+ .uplt-whats-new-release-body details {
1233
+ margin: 0.5rem 0 1rem;
1234
+ padding: 0.25rem 0.75rem;
1235
+ border: 1px solid var(--uplt-color-sidebar-bg, #e5e7eb);
1236
+ border-radius: 0.35rem;
1237
+ background: var(--uplt-color-sidebar-bg, #f9fafb);
1238
+ }
1239
+
1240
+ .uplt-whats-new-release-body details > summary {
1241
+ cursor: pointer;
1242
+ font-weight: 600;
1243
+ }
1244
+
1245
+ .uplt-whats-new-release-body pre {
1246
+ overflow-x: auto;
1247
+ }
1248
+
1249
+ .uplt-whats-new-release-body img {
1250
+ max-width: 100%;
1251
+ height: auto;
1252
+ }
@@ -20,5 +20,7 @@ dependencies:
20
20
  - networkx
21
21
  - pyarrow
22
22
  - cftime
23
+ - markdown
24
+ - requests
23
25
  - pip:
24
26
  - pycirclize
@@ -74,7 +74,7 @@ docs = [
74
74
  "jupyter",
75
75
  "jupytext",
76
76
  "lxml-html-clean",
77
- "m2r2",
77
+ "markdown",
78
78
  "mpltern",
79
79
  "nbsphinx",
80
80
  "sphinx",
@@ -288,19 +288,70 @@ def validate_inputs(dist_dir: Path, access_token: str | None) -> None:
288
288
  raise SystemExit(f"Distribution directory {dist_dir} does not contain files.")
289
289
 
290
290
 
291
+ def find_existing_draft(api_url: str, token: str, record_id: int) -> dict | None:
292
+ record = api_request("GET", f"{api_url}/records/{record_id}", token=token)
293
+ conceptrecid = str(record.get("conceptrecid") or record.get("id"))
294
+
295
+ page = 1
296
+ while True:
297
+ payload = api_request(
298
+ "GET",
299
+ f"{api_url}/deposit/depositions?page={page}&size=100",
300
+ token=token,
301
+ )
302
+
303
+ if not payload:
304
+ break
305
+
306
+ for dep in payload:
307
+ if str(dep.get("conceptrecid")) != conceptrecid:
308
+ continue
309
+ if dep.get("submitted"):
310
+ continue
311
+
312
+ print(f"Found existing draft deposition {dep['id']}")
313
+ return dep
314
+
315
+ if len(payload) < 100:
316
+ break
317
+
318
+ page += 1
319
+
320
+ return None
321
+
322
+
323
+ def get_or_create_draft(api_url: str, token: str, record_id: int) -> dict:
324
+ try:
325
+ return create_new_version(api_url, token, record_id)
326
+ except RuntimeError as exc:
327
+ message = str(exc)
328
+ if "files.enabled" not in message:
329
+ raise
330
+
331
+ draft = find_existing_draft(api_url, token, record_id)
332
+ if draft is None:
333
+ raise
334
+ print(f"Reusing existing Zenodo draft {draft['id']}.")
335
+ return draft
336
+
337
+
291
338
  def main() -> int:
292
339
  args = parse_args()
293
340
  validate_inputs(args.dist_dir, args.access_token)
294
- citation = load_citation(args.citation)
341
+
342
+ citation = load_citation(args.citation_file)
295
343
  pyproject = load_pyproject(args.pyproject)
296
344
  metadata = build_metadata(citation, pyproject)
345
+
297
346
  conceptrecid = resolve_concept_recid(args.api_url, citation["doi"])
298
347
  record_id = latest_record_id(args.api_url, conceptrecid)
299
- draft = create_new_version(args.api_url, args.access_token, record_id)
348
+
349
+ draft = get_or_create_draft(args.api_url, args.access_token, record_id)
300
350
  clear_draft_files(draft, args.access_token)
301
351
  upload_dist_files(draft, args.access_token, args.dist_dir)
302
352
  draft = update_metadata(draft, args.access_token, metadata)
303
353
  published = publish_draft(draft, args.access_token)
354
+
304
355
  doi = published.get("doi") or published.get("metadata", {}).get("doi")
305
356
  print(
306
357
  f"Published Zenodo release record {published['id']} for "
@@ -0,0 +1 @@
1
+ __version__ = '2.2.0'
@@ -2417,6 +2417,8 @@ class Axes(_ExternalModeMixin, maxes.Axes):
2417
2417
  """
2418
2418
  Reposition the subplot axes.
2419
2419
  """
2420
+ # NOTE: The panel span override logic here will move to a layout
2421
+ # composer in a future refactor.
2420
2422
  # WARNING: In later versions self.numRows, self.numCols, and self.figbox
2421
2423
  # are @property definitions that never go stale but in mpl < 3.4 they are
2422
2424
  # attributes that must be updated explicitly with update_params().
@@ -2460,9 +2462,9 @@ class Axes(_ExternalModeMixin, maxes.Axes):
2460
2462
  )
2461
2463
 
2462
2464
  # Check if the panel has a span override (spans more columns/rows
2463
- # than its parent). When it does, use the SubplotSpec position for
2464
- # the "along" dimension so the span is respected. Otherwise use
2465
- # parent_bbox which correctly tracks aspect-ratio adjustments.
2465
+ # than its parent). When it does, compute the visual extent from
2466
+ # actual axes positions so the panel aligns with aspect-adjusted
2467
+ # axes rather than raw grid slots. Otherwise use parent_bbox.
2466
2468
  parent_ss = self._panel_parent.get_subplotspec().get_topmost_subplotspec()
2467
2469
  p_row1, p_row2, p_col1, p_col2 = parent_ss._get_rows_columns(
2468
2470
  ncols=gs.ncols_total
@@ -2470,9 +2472,30 @@ class Axes(_ExternalModeMixin, maxes.Axes):
2470
2472
 
2471
2473
  if side in ("right", "left"):
2472
2474
  has_span_override = (row1 < p_row1) or (row2 > p_row2)
2473
- along_bbox = (
2474
- ss.get_position(self.figure) if has_span_override else parent_bbox
2475
- )
2475
+ if has_span_override:
2476
+ # Compute visual extent from all axes in the span range
2477
+ vmin, vmax = float("inf"), float("-inf")
2478
+ for other in self.figure.axes:
2479
+ if getattr(other, "_panel_side", None):
2480
+ continue
2481
+ oss = getattr(other, "get_subplotspec", lambda: None)()
2482
+ if oss is None:
2483
+ continue
2484
+ oss = oss.get_topmost_subplotspec()
2485
+ if oss.get_gridspec() is not gs:
2486
+ continue
2487
+ o_r1, o_r2, _, _ = oss._get_rows_columns(ncols=gs.ncols_total)
2488
+ if o_r1 >= row1 and o_r2 <= row2:
2489
+ opos = other.get_position()
2490
+ vmin = min(vmin, opos.y0)
2491
+ vmax = max(vmax, opos.y1)
2492
+ if vmin < vmax:
2493
+ along_y0, along_h = vmin, vmax - vmin
2494
+ else:
2495
+ slot = ss.get_position(self.figure)
2496
+ along_y0, along_h = slot.y0, slot.height
2497
+ else:
2498
+ along_y0, along_h = parent_bbox.y0, parent_bbox.height
2476
2499
  boundary = None
2477
2500
  width = sum(gs._wratios_total[col1 : col2 + 1]) / figwidth
2478
2501
  if a_col2 < col1:
@@ -2492,14 +2515,32 @@ class Axes(_ExternalModeMixin, maxes.Axes):
2492
2515
  x0 = anchor_bbox.x1 + pad
2493
2516
  else:
2494
2517
  x0 = anchor_bbox.x0 - pad - width
2495
- bbox = mtransforms.Bbox.from_bounds(
2496
- x0, along_bbox.y0, width, along_bbox.height
2497
- )
2518
+ bbox = mtransforms.Bbox.from_bounds(x0, along_y0, width, along_h)
2498
2519
  else:
2499
2520
  has_span_override = (col1 < p_col1) or (col2 > p_col2)
2500
- along_bbox = (
2501
- ss.get_position(self.figure) if has_span_override else parent_bbox
2502
- )
2521
+ if has_span_override:
2522
+ vmin, vmax = float("inf"), float("-inf")
2523
+ for other in self.figure.axes:
2524
+ if getattr(other, "_panel_side", None):
2525
+ continue
2526
+ oss = getattr(other, "get_subplotspec", lambda: None)()
2527
+ if oss is None:
2528
+ continue
2529
+ oss = oss.get_topmost_subplotspec()
2530
+ if oss.get_gridspec() is not gs:
2531
+ continue
2532
+ _, _, o_c1, o_c2 = oss._get_rows_columns(ncols=gs.ncols_total)
2533
+ if o_c1 >= col1 and o_c2 <= col2:
2534
+ opos = other.get_position()
2535
+ vmin = min(vmin, opos.x0)
2536
+ vmax = max(vmax, opos.x1)
2537
+ if vmin < vmax:
2538
+ along_x0, along_w = vmin, vmax - vmin
2539
+ else:
2540
+ slot = ss.get_position(self.figure)
2541
+ along_x0, along_w = slot.x0, slot.width
2542
+ else:
2543
+ along_x0, along_w = parent_bbox.x0, parent_bbox.width
2503
2544
  boundary = None
2504
2545
  height = sum(gs._hratios_total[row1 : row2 + 1]) / figheight
2505
2546
  if a_row2 < row1:
@@ -2518,9 +2559,7 @@ class Axes(_ExternalModeMixin, maxes.Axes):
2518
2559
  y0 = anchor_bbox.y1 + pad
2519
2560
  else:
2520
2561
  y0 = anchor_bbox.y0 - pad - height
2521
- bbox = mtransforms.Bbox.from_bounds(
2522
- along_bbox.x0, y0, along_bbox.width, height
2523
- )
2562
+ bbox = mtransforms.Bbox.from_bounds(along_x0, y0, along_w, height)
2524
2563
  setter(bbox)
2525
2564
 
2526
2565
  def _update_abc(self, **kwargs):
@@ -1352,12 +1352,116 @@ class GeoAxes(shared._SharedAxes, plot.PlotAxes):
1352
1352
  self.apply_aspect()
1353
1353
  self._adjust_panel_positions(tol=tol)
1354
1354
 
1355
+ def _compute_span_extent(self, side, panel, gs, p_r1, p_r2, p_c1, p_c2):
1356
+ """
1357
+ If the panel spans beyond the parent's SubplotSpec, compute the visual
1358
+ extent (min, max) along the span axis from all non-panel axes in range.
1359
+ Returns None if not a span override or no valid extent found.
1360
+ """
1361
+ # NOTE: This will move to a layout composer in a future refactor.
1362
+ ss = getattr(panel, "get_subplotspec", lambda: None)()
1363
+ if ss is None or p_c1 is None:
1364
+ return None
1365
+
1366
+ panel_ss = ss.get_topmost_subplotspec()
1367
+ s_r1, s_r2, s_c1, s_c2 = panel_ss._get_rows_columns(ncols=gs.ncols_total)
1368
+
1369
+ if side in ("bottom", "top"):
1370
+ has_span_override = s_c1 < p_c1 or s_c2 > p_c2
1371
+ elif side in ("left", "right"):
1372
+ has_span_override = s_r1 < p_r1 or s_r2 > p_r2
1373
+ else:
1374
+ return None
1375
+
1376
+ if not has_span_override:
1377
+ return None
1378
+
1379
+ vmin, vmax = float("inf"), float("-inf")
1380
+ for other_ax in self.figure.axes:
1381
+ if getattr(other_ax, "_panel_side", None):
1382
+ continue
1383
+ oss = getattr(other_ax, "get_subplotspec", lambda: None)()
1384
+ if oss is None:
1385
+ continue
1386
+ oss = oss.get_topmost_subplotspec()
1387
+ if oss.get_gridspec() is not gs:
1388
+ continue
1389
+ o_r1, o_r2, o_c1, o_c2 = oss._get_rows_columns(ncols=gs.ncols_total)
1390
+ opos = other_ax.get_position()
1391
+ if side in ("left", "right"):
1392
+ if o_r1 >= s_r1 and o_r2 <= s_r2:
1393
+ vmin = min(vmin, opos.y0)
1394
+ vmax = max(vmax, opos.y1)
1395
+ else:
1396
+ if o_c1 >= s_c1 and o_c2 <= s_c2:
1397
+ vmin = min(vmin, opos.x0)
1398
+ vmax = max(vmax, opos.x1)
1399
+
1400
+ return (vmin, vmax) if vmin < vmax else None
1401
+
1402
+ @staticmethod
1403
+ def _compute_adjusted_panel_pos(
1404
+ side, panel_pos, span_extent, original_pos, main_pos, sx, sy, tol
1405
+ ):
1406
+ """
1407
+ Compute the new [x0, y0, width, height] for a panel on the given side,
1408
+ accounting for aspect-adjusted main axes and optional span extent.
1409
+ Returns the new position list, or None for unknown sides.
1410
+ """
1411
+ # NOTE: This will move to a layout composer in a future refactor.
1412
+ ox0, oy0 = original_pos.x0, original_pos.y0
1413
+ ox1, oy1 = original_pos.x1, original_pos.y1
1414
+ mx0, my0 = main_pos.x0, main_pos.y0
1415
+ px0, py0 = panel_pos.x0, panel_pos.y0
1416
+ px1, py1 = panel_pos.x1, panel_pos.y1
1417
+
1418
+ if side in ("left", "right"):
1419
+ # Compute vertical extent
1420
+ if span_extent is not None:
1421
+ along_y0 = span_extent[0]
1422
+ along_h = span_extent[1] - span_extent[0]
1423
+ elif py0 <= oy0 + tol and py1 >= oy1 - tol:
1424
+ along_y0, along_h = my0, main_pos.height
1425
+ else:
1426
+ along_y0 = my0 + (panel_pos.y0 - oy0) * sy
1427
+ along_h = panel_pos.height * sy
1428
+
1429
+ if side == "left":
1430
+ gap = original_pos.x0 - (panel_pos.x0 + panel_pos.width)
1431
+ new_x0 = main_pos.x0 - panel_pos.width - gap
1432
+ else:
1433
+ gap = panel_pos.x0 - (original_pos.x0 + original_pos.width)
1434
+ new_x0 = main_pos.x0 + main_pos.width + gap
1435
+ return [new_x0, along_y0, panel_pos.width, along_h]
1436
+
1437
+ elif side in ("top", "bottom"):
1438
+ # Compute horizontal extent
1439
+ if span_extent is not None:
1440
+ along_x0 = span_extent[0]
1441
+ along_w = span_extent[1] - span_extent[0]
1442
+ elif px0 <= ox0 + tol and px1 >= ox1 - tol:
1443
+ along_x0, along_w = mx0, main_pos.width
1444
+ else:
1445
+ along_x0 = mx0 + (panel_pos.x0 - ox0) * sx
1446
+ along_w = panel_pos.width * sx
1447
+
1448
+ if side == "top":
1449
+ gap = panel_pos.y0 - (original_pos.y0 + original_pos.height)
1450
+ new_y0 = main_pos.y0 + main_pos.height + gap
1451
+ else:
1452
+ gap = original_pos.y0 - (panel_pos.y0 + panel_pos.height)
1453
+ new_y0 = main_pos.y0 - panel_pos.height - gap
1454
+ return [along_x0, new_y0, along_w, panel_pos.height]
1455
+
1456
+ return None
1457
+
1355
1458
  def _adjust_panel_positions(self, *, tol: float = 1e-9) -> None:
1356
1459
  """
1357
1460
  Adjust panel positions to align with the aspect-constrained main axes.
1358
1461
  After apply_aspect() shrinks the main axes, panels should flank the actual
1359
1462
  map boundaries rather than the full gridspec allocation.
1360
1463
  """
1464
+ # NOTE: This will move to a layout composer in a future refactor.
1361
1465
  if not getattr(self, "_panel_dict", None):
1362
1466
  return # no panels to adjust
1363
1467
 
@@ -1366,11 +1470,8 @@ class GeoAxes(shared._SharedAxes, plot.PlotAxes):
1366
1470
 
1367
1471
  # Subplot-spec position before apply_aspect(). This is the true "gridspec slot"
1368
1472
  # and remains well-defined even if we temporarily modify axes positions.
1369
- try:
1370
- ss = self.get_subplotspec()
1371
- original_pos = ss.get_position(self.figure) if ss is not None else None
1372
- except Exception:
1373
- original_pos = None
1473
+ ss = getattr(self, "get_subplotspec", lambda: None)()
1474
+ original_pos = ss.get_position(self.figure) if ss is not None else None
1374
1475
  if original_pos is None:
1375
1476
  original_pos = getattr(
1376
1477
  self, "_originalPosition", None
@@ -1390,87 +1491,46 @@ class GeoAxes(shared._SharedAxes, plot.PlotAxes):
1390
1491
  # panel, so span overrides across subplot rows/cols are preserved).
1391
1492
  sx = main_pos.width / original_pos.width if original_pos.width else 1.0
1392
1493
  sy = main_pos.height / original_pos.height if original_pos.height else 1.0
1393
- ox0, oy0 = original_pos.x0, original_pos.y0
1394
- ox1, oy1 = (
1395
- original_pos.x0 + original_pos.width,
1396
- original_pos.y0 + original_pos.height,
1397
- )
1398
- mx0, my0 = main_pos.x0, main_pos.y0
1494
+
1495
+ # Detect span overrides by comparing SubplotSpec extents of parent vs panels
1496
+ parent_ss = getattr(self, "get_subplotspec", lambda: None)()
1497
+ if parent_ss is not None:
1498
+ parent_ss = parent_ss.get_topmost_subplotspec()
1499
+ gs = parent_ss.get_gridspec()
1500
+ p_r1, p_r2, p_c1, p_c2 = parent_ss._get_rows_columns(ncols=gs.ncols_total)
1501
+ else:
1502
+ gs = None
1503
+ p_r1 = p_r2 = p_c1 = p_c2 = None
1399
1504
 
1400
1505
  for side, panels in self._panel_dict.items():
1401
1506
  for panel in panels:
1402
1507
  # Use the panel subplot-spec box as the baseline (not its current
1403
1508
  # original position) to avoid accumulated adjustments.
1404
- try:
1405
- ss = panel.get_subplotspec()
1406
- panel_pos = (
1407
- ss.get_position(panel.figure) if ss is not None else None
1408
- )
1409
- except Exception:
1410
- panel_pos = None
1509
+ ss = getattr(panel, "get_subplotspec", lambda: None)()
1510
+ panel_pos = ss.get_position(panel.figure) if ss is not None else None
1411
1511
  if panel_pos is None:
1412
1512
  panel_pos = panel.get_position(original=True)
1413
- px0, py0 = panel_pos.x0, panel_pos.y0
1414
- px1, py1 = (
1415
- panel_pos.x0 + panel_pos.width,
1416
- panel_pos.y0 + panel_pos.height,
1417
- )
1418
-
1419
- # Use _set_position when available to avoid layoutbox side effects
1420
- # from public set_position() on newer matplotlib versions.
1421
- setter = getattr(panel, "_set_position", panel.set_position)
1422
1513
 
1423
- if side == "left":
1424
- # Calculate original gap between panel and main axes
1425
- gap = original_pos.x0 - (panel_pos.x0 + panel_pos.width)
1426
- # Position panel to the left of the adjusted main axes
1427
- new_x0 = main_pos.x0 - panel_pos.width - gap
1428
- if py0 <= oy0 + tol and py1 >= oy1 - tol:
1429
- new_y0, new_h = my0, main_pos.height
1430
- else:
1431
- new_y0 = my0 + (panel_pos.y0 - oy0) * sy
1432
- new_h = panel_pos.height * sy
1433
- new_pos = [new_x0, new_y0, panel_pos.width, new_h]
1434
- elif side == "right":
1435
- # Calculate original gap
1436
- gap = panel_pos.x0 - (original_pos.x0 + original_pos.width)
1437
- # Position panel to the right of the adjusted main axes
1438
- new_x0 = main_pos.x0 + main_pos.width + gap
1439
- if py0 <= oy0 + tol and py1 >= oy1 - tol:
1440
- new_y0, new_h = my0, main_pos.height
1441
- else:
1442
- new_y0 = my0 + (panel_pos.y0 - oy0) * sy
1443
- new_h = panel_pos.height * sy
1444
- new_pos = [new_x0, new_y0, panel_pos.width, new_h]
1445
- elif side == "top":
1446
- # Calculate original gap
1447
- gap = panel_pos.y0 - (original_pos.y0 + original_pos.height)
1448
- # Position panel above the adjusted main axes
1449
- new_y0 = main_pos.y0 + main_pos.height + gap
1450
- if px0 <= ox0 + tol and px1 >= ox1 - tol:
1451
- new_x0, new_w = mx0, main_pos.width
1452
- else:
1453
- new_x0 = mx0 + (panel_pos.x0 - ox0) * sx
1454
- new_w = panel_pos.width * sx
1455
- new_pos = [new_x0, new_y0, new_w, panel_pos.height]
1456
- elif side == "bottom":
1457
- # Calculate original gap
1458
- gap = original_pos.y0 - (panel_pos.y0 + panel_pos.height)
1459
- # Position panel below the adjusted main axes
1460
- new_y0 = main_pos.y0 - panel_pos.height - gap
1461
- if px0 <= ox0 + tol and px1 >= ox1 - tol:
1462
- new_x0, new_w = mx0, main_pos.width
1463
- else:
1464
- new_x0 = mx0 + (panel_pos.x0 - ox0) * sx
1465
- new_w = panel_pos.width * sx
1466
- new_pos = [new_x0, new_y0, new_w, panel_pos.height]
1467
- else:
1468
- # Unknown side, skip adjustment
1514
+ span_extent = self._compute_span_extent(
1515
+ side, panel, gs, p_r1, p_r2, p_c1, p_c2
1516
+ )
1517
+ new_pos = self._compute_adjusted_panel_pos(
1518
+ side,
1519
+ panel_pos,
1520
+ span_extent,
1521
+ original_pos,
1522
+ main_pos,
1523
+ sx,
1524
+ sy,
1525
+ tol,
1526
+ )
1527
+ if new_pos is None:
1469
1528
  continue
1470
1529
 
1471
1530
  # Panels typically have aspect='auto', which causes matplotlib to
1472
1531
  # reset their *active* position to their *original* position inside
1473
1532
  # apply_aspect()/get_position(). Update both so the change persists.
1533
+ setter = getattr(panel, "_set_position", panel.set_position)
1474
1534
  try:
1475
1535
  setter(new_pos, which="both")
1476
1536
  except TypeError: # older matplotlib