ultraplot 2.4.0__tar.gz → 2.4.1__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 (478) hide show
  1. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/workflows/publish-pypi.yml +5 -49
  2. ultraplot-2.4.1/.zenodo.json +30 -0
  3. {ultraplot-2.4.0 → ultraplot-2.4.1}/CITATION.cff +6 -2
  4. {ultraplot-2.4.0/ultraplot.egg-info → ultraplot-2.4.1}/PKG-INFO +1 -1
  5. ultraplot-2.4.1/ultraplot/_subplots.py +398 -0
  6. ultraplot-2.4.1/ultraplot/_version.py +1 -0
  7. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/base.py +1 -2
  8. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/constructor.py +20 -3
  9. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/figure.py +66 -373
  10. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/gridspec.py +3 -3
  11. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_figure.py +77 -0
  12. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_geographic.py +16 -3
  13. ultraplot-2.4.1/ultraplot/tests/test_release_metadata.py +106 -0
  14. ultraplot-2.4.1/ultraplot/tests/test_subplot_manager.py +406 -0
  15. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/ui.py +6 -2
  16. {ultraplot-2.4.0 → ultraplot-2.4.1/ultraplot.egg-info}/PKG-INFO +1 -1
  17. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot.egg-info/SOURCES.txt +3 -2
  18. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot.egg-info/scm_file_list.json +3 -2
  19. ultraplot-2.4.1/ultraplot.egg-info/scm_version.json +8 -0
  20. ultraplot-2.4.0/tools/release/publish_zenodo.py +0 -364
  21. ultraplot-2.4.0/tools/release/sync_citation.py +0 -168
  22. ultraplot-2.4.0/ultraplot/_version.py +0 -1
  23. ultraplot-2.4.0/ultraplot/tests/test_release_metadata.py +0 -143
  24. ultraplot-2.4.0/ultraplot.egg-info/scm_version.json +0 -8
  25. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/ISSUE_TEMPLATE.md +0 -0
  26. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/dependabot.yml +0 -0
  27. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/micromamba-condarc.yml +0 -0
  28. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/workflows/build-ultraplot.yml +0 -0
  29. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/workflows/main.yml +0 -0
  30. {ultraplot-2.4.0 → ultraplot-2.4.1}/.github/workflows/test-map.yml +0 -0
  31. {ultraplot-2.4.0 → ultraplot-2.4.1}/.gitignore +0 -0
  32. {ultraplot-2.4.0 → ultraplot-2.4.1}/.pre-commit-config.yaml +0 -0
  33. {ultraplot-2.4.0 → ultraplot-2.4.1}/.readthedocs.yml +0 -0
  34. {ultraplot-2.4.0 → ultraplot-2.4.1}/CODEOFCONDUCT.md +0 -0
  35. {ultraplot-2.4.0 → ultraplot-2.4.1}/CONTRIBUTING.rst +0 -0
  36. {ultraplot-2.4.0 → ultraplot-2.4.1}/INSTALL.rst +0 -0
  37. {ultraplot-2.4.0 → ultraplot-2.4.1}/LICENSE.txt +0 -0
  38. {ultraplot-2.4.0 → ultraplot-2.4.1}/README.rst +0 -0
  39. {ultraplot-2.4.0 → ultraplot-2.4.1}/UltraPlotLogo.svg +0 -0
  40. {ultraplot-2.4.0 → ultraplot-2.4.1}/codecov.yml +0 -0
  41. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/1dplots.py +0 -0
  42. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/2dplots.py +0 -0
  43. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/Makefile +0 -0
  44. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_ext/notoc.py +0 -0
  45. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_scripts/fetch_releases.py +0 -0
  46. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/custom.css +0 -0
  47. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/custom.js +0 -0
  48. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/cartesian_example.svg +0 -0
  49. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/colorbars_legends_example.svg +0 -0
  50. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/colormaps_example.svg +0 -0
  51. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/panels_example.svg +0 -0
  52. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/projection_example.svg +0 -0
  53. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/example_plots/subplot_example.svg +0 -0
  54. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_blank.svg +0 -0
  55. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_long.png +0 -0
  56. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_long.svg +0 -0
  57. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_social.png +0 -0
  58. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_social.svg +0 -0
  59. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_static/logo_square.png +0 -0
  60. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/_templates/whatsnew_sidebar.html +0 -0
  61. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/about.rst +0 -0
  62. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/api.rst +0 -0
  63. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/basics.py +0 -0
  64. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/cartesian.py +0 -0
  65. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/colorbars_legends.py +0 -0
  66. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/colormaps.py +0 -0
  67. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/colors.py +0 -0
  68. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/conf.py +0 -0
  69. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/configuration.rst +0 -0
  70. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/contributing.rst +0 -0
  71. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/cycles.py +0 -0
  72. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/README.txt +0 -0
  73. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/colors/01_cycle_colormap.py +0 -0
  74. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/colors/02_diverging_colormap.py +0 -0
  75. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/colors/README.txt +0 -0
  76. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/geo/01_robin_tracks.py +0 -0
  77. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/geo/02_orthographic_views.py +0 -0
  78. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/geo/03_projections_features.py +0 -0
  79. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/geo/04_choropleth.py +0 -0
  80. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/geo/README.txt +0 -0
  81. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/layouts/01_shared_axes_abc.py +0 -0
  82. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/layouts/02_complex_layout_insets.py +0 -0
  83. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/layouts/03_spanning_labels.py +0 -0
  84. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/layouts/README.txt +0 -0
  85. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/legend_types/01_semantic_legends.py +0 -0
  86. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/legends_colorbars/01_multi_colorbars.py +0 -0
  87. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/legends_colorbars/02_legend_inset_colorbar.py +0 -0
  88. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/legends_colorbars/03_semantic_legends.py +0 -0
  89. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/legends_colorbars/README.txt +0 -0
  90. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/01_curved_quiver.py +0 -0
  91. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/02_network_graph.py +0 -0
  92. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/03_lollipop.py +0 -0
  93. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/04_datetime_series.py +0 -0
  94. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/05_box_violin.py +0 -0
  95. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/06_ridge_plot.py +0 -0
  96. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/07_radar.py +0 -0
  97. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/07_sankey.py +0 -0
  98. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/08_chord_diagram.py +0 -0
  99. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/08_ternary.py +0 -0
  100. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/09_phylogeny.py +0 -0
  101. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/10_circos_bed.py +0 -0
  102. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/11_topic_ribbon.py +0 -0
  103. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/12_taylor_diagram.py +0 -0
  104. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/examples/plot_types/README.txt +0 -0
  105. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/external-links.rst +0 -0
  106. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/faq.rst +0 -0
  107. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/fonts.py +0 -0
  108. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/index.rst +0 -0
  109. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/insets_panels.py +0 -0
  110. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/install.rst +0 -0
  111. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/lazy_loading.rst +0 -0
  112. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/make.bat +0 -0
  113. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/networks.py +0 -0
  114. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/projections.py +0 -0
  115. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/requirements-rtd.txt +0 -0
  116. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/sphinxext/custom_roles.py +0 -0
  117. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/sphinxext/jupytext_cache.py +0 -0
  118. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/stats.py +0 -0
  119. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/subplots.py +0 -0
  120. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/ultraplotrc +0 -0
  121. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/usage.rst +0 -0
  122. {ultraplot-2.4.0 → ultraplot-2.4.1}/docs/why.rst +0 -0
  123. {ultraplot-2.4.0 → ultraplot-2.4.1}/environment.yml +0 -0
  124. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/PermanentMarker-Regular.ttf +0 -0
  125. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/environment-logo.yml +0 -0
  126. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/logo.py +0 -0
  127. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/run-linter.sh +0 -0
  128. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/webicon.py +0 -0
  129. {ultraplot-2.4.0 → ultraplot-2.4.1}/logo/whyUltraPlot.svg +0 -0
  130. {ultraplot-2.4.0 → ultraplot-2.4.1}/noxfile.py +0 -0
  131. {ultraplot-2.4.0 → ultraplot-2.4.1}/pyproject.toml +0 -0
  132. {ultraplot-2.4.0 → ultraplot-2.4.1}/requirements-minimal.txt +0 -0
  133. {ultraplot-2.4.0 → ultraplot-2.4.1}/setup.cfg +0 -0
  134. {ultraplot-2.4.0 → ultraplot-2.4.1}/tools/ci/build_test_map.py +0 -0
  135. {ultraplot-2.4.0 → ultraplot-2.4.1}/tools/ci/select_tests.py +0 -0
  136. {ultraplot-2.4.0 → ultraplot-2.4.1}/tools/ci/version_support.py +0 -0
  137. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/__init__.py +0 -0
  138. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/_lazy.py +0 -0
  139. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/__init__.py +0 -0
  140. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/_formatting.py +0 -0
  141. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/cartesian.py +0 -0
  142. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/container.py +0 -0
  143. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/geo.py +0 -0
  144. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot.py +0 -0
  145. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot_types/__init__.py +0 -0
  146. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot_types/circlize.py +0 -0
  147. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot_types/curved_quiver.py +0 -0
  148. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot_types/ribbon.py +0 -0
  149. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/plot_types/sankey.py +0 -0
  150. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/polar.py +0 -0
  151. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/shared.py +0 -0
  152. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/taylor.py +0 -0
  153. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/axes/three.py +0 -0
  154. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Algae.rgb +0 -0
  155. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Amp.rgb +0 -0
  156. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/BR.rgb +0 -0
  157. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Balance.rgb +0 -0
  158. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues1_r.xml +0 -0
  159. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues2.xml +0 -0
  160. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues3.xml +0 -0
  161. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues4_r.xml +0 -0
  162. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues5.xml +0 -0
  163. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues6.xml +0 -0
  164. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues7.xml +0 -0
  165. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues8.xml +0 -0
  166. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Blues9.xml +0 -0
  167. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Boreal.json +0 -0
  168. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns1.xml +0 -0
  169. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns2.xml +0 -0
  170. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns3.xml +0 -0
  171. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns4.xml +0 -0
  172. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns5.xml +0 -0
  173. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns6.xml +0 -0
  174. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns7.xml +0 -0
  175. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns8.xml +0 -0
  176. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Browns9.xml +0 -0
  177. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/ColdHot.rgb +0 -0
  178. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Crest.rgb +0 -0
  179. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Curl.rgb +0 -0
  180. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Deep.rgb +0 -0
  181. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Delta.rgb +0 -0
  182. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Dense.rgb +0 -0
  183. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Div.json +0 -0
  184. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/DryWet.json +0 -0
  185. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Dusk.json +0 -0
  186. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Fire.json +0 -0
  187. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Flare.rgb +0 -0
  188. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Glacial.json +0 -0
  189. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens1_r.xml +0 -0
  190. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens2.xml +0 -0
  191. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens3_r.xml +0 -0
  192. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens4.xml +0 -0
  193. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens5.xml +0 -0
  194. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens6_r.xml +0 -0
  195. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens7.xml +0 -0
  196. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Greens8.xml +0 -0
  197. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Haline.rgb +0 -0
  198. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Ice.rgb +0 -0
  199. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/IceFire.rgb +0 -0
  200. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Mako.rgb +0 -0
  201. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Marine.json +0 -0
  202. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Matter.rgb +0 -0
  203. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Mono.txt +0 -0
  204. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/MonoCycle.txt +0 -0
  205. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/NegPos.json +0 -0
  206. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Oranges1.xml +0 -0
  207. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Oranges2.xml +0 -0
  208. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Oranges3.xml +0 -0
  209. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Oranges4.xml +0 -0
  210. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Oxy.rgb +0 -0
  211. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Phase.rgb +0 -0
  212. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Purples1_r.xml +0 -0
  213. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Purples2.xml +0 -0
  214. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Purples3.xml +0 -0
  215. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Reds1.xml +0 -0
  216. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Reds2.xml +0 -0
  217. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Reds3.xml +0 -0
  218. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Reds4.xml +0 -0
  219. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Reds5.xml +0 -0
  220. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Rocket.rgb +0 -0
  221. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Solar.rgb +0 -0
  222. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Speed.rgb +0 -0
  223. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Stellar.json +0 -0
  224. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Sunrise.json +0 -0
  225. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Sunset.json +0 -0
  226. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Tempo.rgb +0 -0
  227. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Thermal.rgb +0 -0
  228. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Turbid.rgb +0 -0
  229. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Vivid.xml +0 -0
  230. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Vlag.rgb +0 -0
  231. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Yellows1.xml +0 -0
  232. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Yellows2.xml +0 -0
  233. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Yellows3.xml +0 -0
  234. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/Yellows4.xml +0 -0
  235. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/acton.txt +0 -0
  236. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/bam.txt +0 -0
  237. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/bamO.txt +0 -0
  238. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/bamako.txt +0 -0
  239. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/batlow.txt +0 -0
  240. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/batlowK.txt +0 -0
  241. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/batlowW.txt +0 -0
  242. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/berlin.txt +0 -0
  243. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/bilbao.txt +0 -0
  244. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/broc.txt +0 -0
  245. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/brocO.txt +0 -0
  246. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/buda.txt +0 -0
  247. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/bukavu.txt +0 -0
  248. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/cork.txt +0 -0
  249. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/corkO.txt +0 -0
  250. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/davos.txt +0 -0
  251. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/devon.txt +0 -0
  252. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/fes.txt +0 -0
  253. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/hawaii.txt +0 -0
  254. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/imola.txt +0 -0
  255. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/lajolla.txt +0 -0
  256. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/lapaz.txt +0 -0
  257. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/lisbon.txt +0 -0
  258. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/nuuk.txt +0 -0
  259. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/oleron.txt +0 -0
  260. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/oslo.txt +0 -0
  261. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/roma.txt +0 -0
  262. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/romaO.txt +0 -0
  263. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/tofino.txt +0 -0
  264. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/tokyo.txt +0 -0
  265. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/turku.txt +0 -0
  266. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/vanimo.txt +0 -0
  267. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/vik.txt +0 -0
  268. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cmaps/vikO.txt +0 -0
  269. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/colorbar.py +0 -0
  270. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/colors/opencolor.txt +0 -0
  271. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/colors/xkcd.txt +0 -0
  272. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/colors.py +0 -0
  273. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/config.py +0 -0
  274. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/538.hex +0 -0
  275. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/FlatUI.hex +0 -0
  276. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/Qual1.rgb +0 -0
  277. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/Qual2.rgb +0 -0
  278. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/bmh.hex +0 -0
  279. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/classic.hex +0 -0
  280. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/colorblind.hex +0 -0
  281. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/colorblind10.hex +0 -0
  282. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/default.hex +0 -0
  283. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/ggplot.hex +0 -0
  284. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/seaborn.hex +0 -0
  285. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/cycles/tableau.hex +0 -0
  286. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/demos.py +0 -0
  287. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/externals/__init__.py +0 -0
  288. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/externals/hsluv.py +0 -0
  289. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-Bold.ttf +0 -0
  290. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-ExtraLight.ttf +0 -0
  291. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-Heavy.ttf +0 -0
  292. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-Light.ttf +0 -0
  293. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-Medium.ttf +0 -0
  294. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-Regular.ttf +0 -0
  295. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-SemiBold.ttf +0 -0
  296. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraMath-UltraLight.ttf +0 -0
  297. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Black.ttf +0 -0
  298. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-BlackItalic.ttf +0 -0
  299. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Bold.ttf +0 -0
  300. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-BoldItalic.ttf +0 -0
  301. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-ExtraBold.ttf +0 -0
  302. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-ExtraBoldItalic.ttf +0 -0
  303. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-ExtraLight.ttf +0 -0
  304. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-ExtraLightItalic.ttf +0 -0
  305. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Italic.ttf +0 -0
  306. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Light.ttf +0 -0
  307. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-LightItalic.ttf +0 -0
  308. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Medium.ttf +0 -0
  309. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-MediumItalic.ttf +0 -0
  310. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-Regular.ttf +0 -0
  311. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-SemiBold.ttf +0 -0
  312. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/FiraSans-SemiBoldItalic.ttf +0 -0
  313. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_FIRAMATH.txt +0 -0
  314. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_FIRASANS.txt +0 -0
  315. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_NOTOSANS.txt +0 -0
  316. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_NOTOSERIF.txt +0 -0
  317. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_OPENSANS.txt +0 -0
  318. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_ROBOTO.txt +0 -0
  319. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_SOURCESANS.txt +0 -0
  320. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_SOURCESERIF.txt +0 -0
  321. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_TEXGYRE.txt +0 -0
  322. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/LICENSE_UBUNTU.txt +0 -0
  323. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSans-Bold.ttf +0 -0
  324. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSans-BoldItalic.ttf +0 -0
  325. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSans-Italic.ttf +0 -0
  326. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSans-Regular.ttf +0 -0
  327. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSerif-Bold.ttf +0 -0
  328. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSerif-BoldItalic.ttf +0 -0
  329. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSerif-Italic.ttf +0 -0
  330. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/NotoSerif-Regular.ttf +0 -0
  331. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-Bold.ttf +0 -0
  332. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-BoldItalic.ttf +0 -0
  333. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-Italic.ttf +0 -0
  334. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-Regular.ttf +0 -0
  335. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-Semibold.ttf +0 -0
  336. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  337. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Black.ttf +0 -0
  338. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-BlackItalic.ttf +0 -0
  339. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Bold.ttf +0 -0
  340. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-BoldItalic.ttf +0 -0
  341. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Italic.ttf +0 -0
  342. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Light.ttf +0 -0
  343. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-LightItalic.ttf +0 -0
  344. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Medium.ttf +0 -0
  345. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-MediumItalic.ttf +0 -0
  346. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Roboto-Regular.ttf +0 -0
  347. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-Black.ttf +0 -0
  348. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-BlackItalic.ttf +0 -0
  349. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-Bold.ttf +0 -0
  350. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-BoldItalic.ttf +0 -0
  351. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-ExtraLight.ttf +0 -0
  352. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
  353. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-Italic.ttf +0 -0
  354. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-Light.ttf +0 -0
  355. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-LightItalic.ttf +0 -0
  356. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-Regular.ttf +0 -0
  357. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-SemiBold.ttf +0 -0
  358. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
  359. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-Black.ttf +0 -0
  360. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-BlackItalic.ttf +0 -0
  361. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-Bold.ttf +0 -0
  362. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-BoldItalic.ttf +0 -0
  363. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-ExtraLight.ttf +0 -0
  364. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-ExtraLightItalic.ttf +0 -0
  365. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-Italic.ttf +0 -0
  366. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-Light.ttf +0 -0
  367. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-LightItalic.ttf +0 -0
  368. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-Regular.ttf +0 -0
  369. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-SemiBold.ttf +0 -0
  370. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/SourceSerifPro-SemiBoldItalic.ttf +0 -0
  371. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-Bold.ttf +0 -0
  372. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-BoldItalic.ttf +0 -0
  373. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-Italic.ttf +0 -0
  374. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-Light.ttf +0 -0
  375. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-LightItalic.ttf +0 -0
  376. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-Medium.ttf +0 -0
  377. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-MediumItalic.ttf +0 -0
  378. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/Ubuntu-Regular.ttf +0 -0
  379. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreadventor-bold.ttf +0 -0
  380. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreadventor-bolditalic.ttf +0 -0
  381. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreadventor-italic.ttf +0 -0
  382. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreadventor-regular.ttf +0 -0
  383. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrebonum-bold.ttf +0 -0
  384. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrebonum-bolditalic.ttf +0 -0
  385. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrebonum-italic.ttf +0 -0
  386. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrebonum-regular.ttf +0 -0
  387. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrechorus-mediumitalic.ttf +0 -0
  388. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrecursor-bold.ttf +0 -0
  389. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrecursor-bolditalic.ttf +0 -0
  390. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrecursor-italic.ttf +0 -0
  391. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrecursor-regular.ttf +0 -0
  392. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreheros-bold.ttf +0 -0
  393. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreheros-bolditalic.ttf +0 -0
  394. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreheros-italic.ttf +0 -0
  395. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreheros-regular.ttf +0 -0
  396. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrepagella-bold.ttf +0 -0
  397. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrepagella-bolditalic.ttf +0 -0
  398. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrepagella-italic.ttf +0 -0
  399. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyrepagella-regular.ttf +0 -0
  400. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreschola-bold.ttf +0 -0
  401. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreschola-bolditalic.ttf +0 -0
  402. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreschola-italic.ttf +0 -0
  403. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyreschola-regular.ttf +0 -0
  404. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyretermes-bold.ttf +0 -0
  405. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyretermes-bolditalic.ttf +0 -0
  406. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyretermes-italic.ttf +0 -0
  407. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/fonts/texgyretermes-regular.ttf +0 -0
  408. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/__init__.py +0 -0
  409. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/benchmarks.py +0 -0
  410. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/context.py +0 -0
  411. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/docstring.py +0 -0
  412. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/fonts.py +0 -0
  413. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/guides.py +0 -0
  414. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/inputs.py +0 -0
  415. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/labels.py +0 -0
  416. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/rcsetup.py +0 -0
  417. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/versions.py +0 -0
  418. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/internals/warnings.py +0 -0
  419. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/legend.py +0 -0
  420. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/proj.py +0 -0
  421. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/scale.py +0 -0
  422. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/__init__.py +0 -0
  423. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/conftest.py +0 -0
  424. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_1dplots.py +0 -0
  425. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_2dplots.py +0 -0
  426. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_animation.py +0 -0
  427. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_axes.py +0 -0
  428. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_axes_alt_styles.py +0 -0
  429. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_axes_base_colorbar_helpers.py +0 -0
  430. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_base.py +0 -0
  431. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_circlize_integration.py +0 -0
  432. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colorbar.py +0 -0
  433. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colorbar_helpers_extra.py +0 -0
  434. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colormap.py +0 -0
  435. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colormap_helpers_extra.py +0 -0
  436. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colors.py +0 -0
  437. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_colors_helpers.py +0 -0
  438. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_config.py +0 -0
  439. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_config_helpers_extra.py +0 -0
  440. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_constructor.py +0 -0
  441. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_constructor_helpers_extra.py +0 -0
  442. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_core_versions.py +0 -0
  443. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_demos.py +0 -0
  444. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_docs.py +0 -0
  445. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_docs_fetch_releases.py +0 -0
  446. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_docs_search.py +0 -0
  447. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_external_axes_container_integration.py +0 -0
  448. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_external_container_edge_cases.py +0 -0
  449. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_external_container_mocked.py +0 -0
  450. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_fonts.py +0 -0
  451. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_format.py +0 -0
  452. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_gridspec.py +0 -0
  453. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_handlers.py +0 -0
  454. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_imports.py +0 -0
  455. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_imshow.py +0 -0
  456. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_inputs.py +0 -0
  457. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_inputs_helpers.py +0 -0
  458. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_inset.py +0 -0
  459. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_integration.py +0 -0
  460. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_legend.py +0 -0
  461. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_plot.py +0 -0
  462. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_proj_helpers.py +0 -0
  463. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_projections.py +0 -0
  464. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_rcsetup_helpers.py +0 -0
  465. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_scale_helpers.py +0 -0
  466. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_semantic_legend.py +0 -0
  467. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_statistical_plotting.py +0 -0
  468. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_subplots.py +0 -0
  469. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_text_helpers.py +0 -0
  470. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_tickers.py +0 -0
  471. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/tests/test_ultralayout.py +0 -0
  472. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/text.py +0 -0
  473. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/ticker.py +0 -0
  474. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/ultralayout.py +0 -0
  475. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot/utils.py +0 -0
  476. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot.egg-info/dependency_links.txt +0 -0
  477. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot.egg-info/requires.txt +0 -0
  478. {ultraplot-2.4.0 → ultraplot-2.4.1}/ultraplot.egg-info/top_level.txt +0 -0
@@ -121,6 +121,11 @@ jobs:
121
121
  verbose: true
122
122
  skip-existing: true
123
123
 
124
+ # NOTE: Publishing this release is what triggers the Zenodo archive. Zenodo's
125
+ # GitHub integration webhooks the 'release: published' event and mints a new
126
+ # version under the concept DOI in CITATION.cff -- no job, token, or API call
127
+ # of ours is involved. The integration only sees releases published *after* it
128
+ # was enabled, so it never backfills.
124
129
  publish-github-release:
125
130
  name: Publish GitHub release
126
131
  needs: publish-pypi
@@ -133,52 +138,3 @@ jobs:
133
138
  uses: softprops/action-gh-release@v3
134
139
  with:
135
140
  generate_release_notes: true
136
-
137
- # publish-zenodo:
138
- # name: Publish Zenodo release
139
- # needs: publish-github-release
140
- # runs-on: ubuntu-latest
141
- # if: github.event_name == 'push'
142
- # permissions:
143
- # contents: read
144
- # env:
145
- # ZENODO_ACCESS_TOKEN: ${{ secrets.ZENODO_ACCESS_TOKEN }}
146
- # steps:
147
- # - uses: actions/checkout@v7
148
- # with:
149
- # fetch-depth: 0
150
- #
151
- # - uses: actions/setup-python@v6
152
- # with:
153
- # python-version: "3.12"
154
- #
155
- # - name: Install release tooling
156
- # run: |
157
- # python -m pip install --upgrade pip
158
- # python -m pip install PyYAML
159
- # shell: bash
160
- #
161
- # - name: Download artifacts
162
- # uses: actions/download-artifact@v8
163
- # with:
164
- # name: dist-${{ github.sha }}-${{ github.run_id }}-${{ github.run_number }}
165
- # path: dist
166
- #
167
- # - name: Generate release citation metadata
168
- # run: |
169
- # python tools/release/sync_citation.py \
170
- # --tag "${GITHUB_REF_NAME}" \
171
- # --output "${RUNNER_TEMP}/CITATION.cff"
172
- # shell: bash
173
- #
174
- # - name: Check tree stayed clean
175
- # run: |
176
- # git diff --quiet || (git status --short && git diff && exit 1)
177
- # shell: bash
178
- #
179
- # - name: Publish to Zenodo
180
- # run: |
181
- # python tools/release/publish_zenodo.py \
182
- # --dist-dir dist \
183
- # --citation-file "${RUNNER_TEMP}/CITATION.cff"
184
- # shell: bash
@@ -0,0 +1,30 @@
1
+ {
2
+ "upload_type": "software",
3
+ "title": "UltraPlot",
4
+ "description": "A succinct matplotlib wrapper for making beautiful, publication-quality graphics.",
5
+ "creators": [
6
+ {
7
+ "name": "van Elteren, Casper",
8
+ "orcid": "0000-0001-9862-8936"
9
+ },
10
+ {
11
+ "name": "Becker, Matthew R.",
12
+ "orcid": "0000-0001-7774-2246"
13
+ }
14
+ ],
15
+ "license": "mit",
16
+ "access_right": "open",
17
+ "keywords": [
18
+ "plotting",
19
+ "matplotlib",
20
+ "scientific visualization",
21
+ "wrapper"
22
+ ],
23
+ "related_identifiers": [
24
+ {
25
+ "identifier": "https://github.com/Ultraplot/UltraPlot",
26
+ "relation": "isSupplementTo",
27
+ "scheme": "url"
28
+ }
29
+ ]
30
+ }
@@ -8,8 +8,12 @@ authors:
8
8
  - family-names: "Becker"
9
9
  given-names: "Matthew R."
10
10
  orcid: "https://orcid.org/0000-0001-7774-2246"
11
- date-released: "2026-03-30"
12
- version: "2.1.5"
11
+ # NOTE: Deliberately no 'version' or 'date-released'. The package version comes
12
+ # from the git tag via setuptools_scm, and Zenodo's GitHub integration takes the
13
+ # version and publication date from the release itself. Pinning them here means
14
+ # hand-editing this file on every release, which is how it drifted to 2.1.5 while
15
+ # the project shipped 2.4.0. The DOI below is the *concept* DOI: it is stable
16
+ # across releases and always resolves to the latest version.
13
17
  doi: "10.5281/zenodo.15733564"
14
18
  repository-code: "https://github.com/Ultraplot/UltraPlot"
15
19
  license: "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultraplot
3
- Version: 2.4.0
3
+ Version: 2.4.1
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>
@@ -0,0 +1,398 @@
1
+ """
2
+ Subplot creation and management for ultraplot figures.
3
+ """
4
+
5
+ from numbers import Integral
6
+ from typing import TYPE_CHECKING
7
+
8
+ import matplotlib.axes as maxes
9
+ import matplotlib.gridspec as mgridspec
10
+ import matplotlib.projections as mproj
11
+ import numpy as np
12
+
13
+ from . import axes as paxes
14
+ from . import constructor
15
+ from . import gridspec as pgridspec
16
+ from .internals import _not_none, _pop_params, warnings
17
+
18
+ if TYPE_CHECKING:
19
+ from .figure import Figure
20
+
21
+
22
+ class SubplotManager:
23
+ """
24
+ Manages subplot creation, gridspec ownership, and projection parsing
25
+ for a Figure instance.
26
+
27
+ Parameters
28
+ ----------
29
+ figure : `~ultraplot.figure.Figure`
30
+ The parent figure.
31
+ """
32
+
33
+ def __init__(self, figure: "Figure"):
34
+ self.figure = figure
35
+ self.subplot_dict: dict = {}
36
+ self.counter: int = 0
37
+ self._gridspec = None
38
+
39
+ def reset(self):
40
+ """
41
+ Forget every subplot and release the gridspec.
42
+
43
+ Called by `~ultraplot.figure.Figure.clear`, which destroys the axes this
44
+ manager tracks. Without this the figure keeps handing out axes that are no
45
+ longer attached to it.
46
+ """
47
+ self.subplot_dict.clear()
48
+ self.counter = 0
49
+ self._gridspec = None
50
+
51
+ @property
52
+ def gridspec(self):
53
+ """The single GridSpec used for all subplots in the figure."""
54
+ return self._gridspec
55
+
56
+ @gridspec.setter
57
+ def gridspec(self, gs):
58
+ if not isinstance(gs, pgridspec.GridSpec):
59
+ raise ValueError("Gridspec must be a ultraplot.GridSpec instance.")
60
+ self._gridspec = gs
61
+ gs.figure = self.figure # gridspec.figure should reference the real Figure
62
+
63
+ @staticmethod
64
+ def parse_backend(backend=None, basemap=None):
65
+ """
66
+ Handle deprecation of basemap and cartopy package.
67
+ """
68
+ if backend == "basemap":
69
+ warnings._warn_ultraplot(
70
+ f"{backend=} will be deprecated in next major release (v2.0). "
71
+ "See https://github.com/Ultraplot/ultraplot/pull/243"
72
+ )
73
+ return backend
74
+
75
+ def parse_proj(
76
+ self,
77
+ proj=None,
78
+ projection=None,
79
+ proj_kw=None,
80
+ projection_kw=None,
81
+ backend=None,
82
+ basemap=None,
83
+ **kwargs,
84
+ ):
85
+ """
86
+ Translate user-input projection into a registered matplotlib axes class.
87
+ """
88
+ # Parse arguments
89
+ proj = _not_none(proj=proj, projection=projection, default="cartesian")
90
+ proj_kw = _not_none(proj_kw=proj_kw, projection_kw=projection_kw, default={})
91
+ backend = self.parse_backend(backend, basemap)
92
+ if isinstance(proj, str):
93
+ proj = proj.lower()
94
+
95
+ # Search axes projections
96
+ name = None
97
+
98
+ # Handle cartopy/basemap Projection objects directly
99
+ # These should be converted to Ultraplot GeoAxes
100
+ if not isinstance(proj, str):
101
+ if constructor.Projection is not object and isinstance(
102
+ proj, constructor.Projection
103
+ ):
104
+ name = "ultraplot_cartopy"
105
+ kwargs["map_projection"] = proj
106
+ elif constructor.Basemap is not object and isinstance(
107
+ proj, constructor.Basemap
108
+ ):
109
+ name = "ultraplot_basemap"
110
+ kwargs["map_projection"] = proj
111
+
112
+ if name is None and isinstance(proj, str):
113
+ try:
114
+ mproj.get_projection_class("ultraplot_" + proj)
115
+ except (KeyError, ValueError):
116
+ pass
117
+ else:
118
+ name = "ultraplot_" + proj
119
+ if name is None and isinstance(proj, str):
120
+ # Try geographic projections first if cartopy/basemap available
121
+ if (
122
+ constructor.Projection is not object
123
+ or constructor.Basemap is not object
124
+ ):
125
+ try:
126
+ proj_obj = constructor.Proj(
127
+ proj, backend=backend, include_axes=True, **proj_kw
128
+ )
129
+ name = "ultraplot_" + proj_obj._proj_backend
130
+ kwargs["map_projection"] = proj_obj
131
+ except ValueError:
132
+ pass # not a geographic projection, try matplotlib registry below
133
+
134
+ # If not geographic, check if registered globally in matplotlib
135
+ # (e.g., 'ternary', 'polar', '3d')
136
+ if name is None and proj in mproj.get_projection_names():
137
+ name = proj
138
+
139
+ if name is None and isinstance(proj, str):
140
+ raise ValueError(
141
+ f"Invalid projection name {proj!r}. If you are trying to generate a "
142
+ "GeoAxes with a cartopy.crs.Projection or mpl_toolkits.basemap.Basemap "
143
+ "then cartopy or basemap must be installed. Otherwise the known axes "
144
+ f"subclasses are:\n{paxes._cls_table}"
145
+ )
146
+
147
+ if name is not None:
148
+ kwargs["projection"] = name
149
+ return kwargs
150
+
151
+ def add_subplot(self, *args, **kwargs):
152
+ """
153
+ The driver function for adding single subplots.
154
+ """
155
+ fig = self.figure
156
+ fig._layout_dirty = True
157
+ kwargs = self.parse_proj(**kwargs)
158
+
159
+ args = args or (1, 1, 1)
160
+ gs = self.gridspec
161
+
162
+ # Integer arg
163
+ if len(args) == 1 and isinstance(args[0], Integral):
164
+ if not 111 <= args[0] <= 999:
165
+ raise ValueError(f"Input {args[0]} must fall between 111 and 999.")
166
+ args = tuple(map(int, str(args[0])))
167
+
168
+ # Subplot spec
169
+ if len(args) == 1 and isinstance(
170
+ args[0], (maxes.SubplotBase, mgridspec.SubplotSpec)
171
+ ):
172
+ ss = args[0]
173
+ if isinstance(ss, maxes.SubplotBase):
174
+ ss = ss.get_subplotspec()
175
+ if gs is None:
176
+ gs = ss.get_topmost_subplotspec().get_gridspec()
177
+ if not isinstance(gs, pgridspec.GridSpec):
178
+ raise ValueError(
179
+ "Input subplotspec must be derived from a ultraplot.GridSpec."
180
+ )
181
+ if ss.get_topmost_subplotspec().get_gridspec() is not gs:
182
+ raise ValueError(
183
+ "Input subplotspec must be derived from the active figure gridspec."
184
+ )
185
+
186
+ # Row and column spec
187
+ elif (
188
+ len(args) == 3
189
+ and all(isinstance(arg, Integral) for arg in args[:2])
190
+ and all(isinstance(arg, Integral) for arg in np.atleast_1d(args[2]))
191
+ ):
192
+ nrows, ncols, num = args
193
+ i, j = np.resize(num, 2)
194
+ if gs is None:
195
+ gs = pgridspec.GridSpec(nrows, ncols)
196
+ orows, ocols = gs.get_geometry()
197
+ if orows % nrows:
198
+ raise ValueError(
199
+ f"The input number of rows {nrows} does not divide the "
200
+ f"figure gridspec number of rows {orows}."
201
+ )
202
+ if ocols % ncols:
203
+ raise ValueError(
204
+ f"The input number of columns {ncols} does not divide the "
205
+ f"figure gridspec number of columns {ocols}."
206
+ )
207
+ if any(_ < 1 or _ > nrows * ncols for _ in (i, j)):
208
+ raise ValueError(
209
+ "The input subplot indices must fall between "
210
+ f"1 and {nrows * ncols}. Instead got {i} and {j}."
211
+ )
212
+ rowfact, colfact = orows // nrows, ocols // ncols
213
+ irow, icol = divmod(i - 1, ncols) # convert to zero-based
214
+ jrow, jcol = divmod(j - 1, ncols)
215
+ irow, icol = irow * rowfact, icol * colfact
216
+ jrow, jcol = (jrow + 1) * rowfact - 1, (jcol + 1) * colfact - 1
217
+ ss = gs[irow : jrow + 1, icol : jcol + 1]
218
+
219
+ else:
220
+ raise ValueError(f"Invalid add_subplot positional arguments {args!r}.")
221
+
222
+ # Add the subplot
223
+ # NOTE: Must assign unique label to each subplot or else subsequent calls
224
+ # to add_subplot() in mpl < 3.4 may return an already-drawn subplot in the
225
+ # wrong location due to gridspec override.
226
+ self.gridspec = gs # trigger layout adjustment
227
+ self.counter += 1
228
+ kwargs.setdefault("label", f"subplot_{self.counter}")
229
+ kwargs.setdefault("number", 1 + max(self.subplot_dict, default=0))
230
+ kwargs.pop("refwidth", None) # TODO: remove this
231
+
232
+ # Use container approach for external projections to make them
233
+ # ultraplot-compatible. Skip projections that start with "ultraplot_"
234
+ # as these are already Ultraplot axes classes.
235
+ projection_name = kwargs.get("projection")
236
+ external_axes_class = None
237
+ external_axes_kwargs = {}
238
+
239
+ if projection_name and isinstance(projection_name, str):
240
+ if not projection_name.startswith("ultraplot_"):
241
+ try:
242
+ proj_class = mproj.get_projection_class(projection_name)
243
+ if not issubclass(proj_class, paxes.Axes):
244
+ external_axes_class = proj_class
245
+ external_axes_kwargs["projection"] = projection_name
246
+
247
+ from .axes.container import create_external_axes_container
248
+
249
+ container_name = f"_ultraplot_container_{projection_name}"
250
+ if container_name not in mproj.get_projection_names():
251
+ container_class = create_external_axes_container(
252
+ proj_class, projection_name=container_name
253
+ )
254
+ mproj.register_projection(container_class)
255
+
256
+ kwargs["projection"] = container_name
257
+ kwargs["external_axes_class"] = external_axes_class
258
+ kwargs["external_axes_kwargs"] = external_axes_kwargs
259
+ except (KeyError, ValueError):
260
+ pass
261
+
262
+ kwargs.pop("_subplot_spec", None)
263
+
264
+ # NOTE: Skip past Figure.add_subplot (which routes back here) to the
265
+ # matplotlib implementation. Using super() rather than naming the
266
+ # matplotlib class keeps any mixin between Figure and matplotlib's
267
+ # Figure in a subclass MRO from being bypassed.
268
+ from .figure import Figure
269
+
270
+ ax = super(Figure, fig).add_subplot(ss, **kwargs)
271
+ if ax.number:
272
+ self.subplot_dict[ax.number] = ax
273
+ return ax
274
+
275
+ def add_subplots(
276
+ self,
277
+ array=None,
278
+ nrows=1,
279
+ ncols=1,
280
+ order="C",
281
+ proj=None,
282
+ projection=None,
283
+ proj_kw=None,
284
+ projection_kw=None,
285
+ backend=None,
286
+ basemap=None,
287
+ **kwargs,
288
+ ):
289
+ """
290
+ The driver function for adding multiple subplots.
291
+ """
292
+ fig = self.figure
293
+
294
+ # Helper to normalize per-axes arguments into {num: value} dicts.
295
+ # Accepts 'string', {1: 'string1', (2, 3): 'string2'}, or lists.
296
+ def _axes_dict(naxs, input, kw=False, default=None):
297
+ if not kw: # 'string' or {1: 'string1', (2, 3): 'string2'}
298
+ if np.iterable(input) and not isinstance(input, (str, dict)):
299
+ input = {num + 1: item for num, item in enumerate(input)}
300
+ elif not isinstance(input, dict):
301
+ input = {range(1, naxs + 1): input}
302
+ else: # {key: value} or {1: {key: value1}, (2, 3): {key: value2}}
303
+ nested = [isinstance(_, dict) for _ in input.values()]
304
+ if not any(nested): # any([]) == False
305
+ input = {range(1, naxs + 1): input.copy()}
306
+ elif not all(nested):
307
+ raise ValueError(f"Invalid input {input!r}.")
308
+ # Unfurl keys that contain multiple axes numbers
309
+ output = {}
310
+ for nums, item in input.items():
311
+ nums = np.atleast_1d(nums)
312
+ for num in nums.flat:
313
+ output[num] = item.copy() if kw else item
314
+ # Fill with default values
315
+ for num in range(1, naxs + 1):
316
+ if num not in output:
317
+ output[num] = {} if kw else default
318
+ if output.keys() != set(range(1, naxs + 1)):
319
+ raise ValueError(
320
+ f"Have {naxs} axes, but {input!r} includes props for the axes: "
321
+ + ", ".join(map(repr, sorted(output)))
322
+ + "."
323
+ )
324
+ return output
325
+
326
+ # Build the subplot array
327
+ # NOTE: Currently this may ignore user-input nrows/ncols without warning
328
+ if order not in ("C", "F"): # better error message
329
+ raise ValueError(f"Invalid order={order!r}. Options are 'C' or 'F'.")
330
+ gs = None
331
+ if array is None or isinstance(array, mgridspec.GridSpec):
332
+ if array is not None:
333
+ gs, nrows, ncols = array, array.nrows, array.ncols
334
+ array = np.arange(1, nrows * ncols + 1)[..., None]
335
+ array = array.reshape((nrows, ncols), order=order)
336
+ else:
337
+ array = np.atleast_1d(array)
338
+ array[array == None] = 0 # None or 0 both valid placeholders # noqa: E711
339
+ array = array.astype(int)
340
+ if array.ndim == 1: # interpret as single row or column
341
+ array = array[None, :] if order == "C" else array[:, None]
342
+ elif array.ndim != 2:
343
+ raise ValueError(f"Expected 1D or 2D array of integers. Got {array}.")
344
+
345
+ # Parse input format, gridspec, and projection arguments
346
+ # NOTE: Permit figure format keywords for e.g. 'collabels' (more intuitive)
347
+ nums = np.unique(array[array != 0])
348
+ naxs = len(nums)
349
+ if any(num < 0 or not isinstance(num, Integral) for num in nums.flat):
350
+ raise ValueError(f"Expected array of positive integers. Got {array}.")
351
+ proj = _not_none(projection=projection, proj=proj)
352
+ proj = _axes_dict(naxs, proj, kw=False, default="cartesian")
353
+ proj_kw = _not_none(projection_kw=projection_kw, proj_kw=proj_kw) or {}
354
+ proj_kw = _axes_dict(naxs, proj_kw, kw=True)
355
+ backend = self.parse_backend(backend, basemap)
356
+ backend = _axes_dict(naxs, backend, kw=False)
357
+ axes_kw = {
358
+ num: {"proj": proj[num], "proj_kw": proj_kw[num], "backend": backend[num]}
359
+ for num in proj
360
+ }
361
+ for key in ("gridspec_kw", "subplot_kw"):
362
+ kw = kwargs.pop(key, None)
363
+ if not kw:
364
+ continue
365
+ warnings._warn_ultraplot(
366
+ f"{key!r} is not necessary in ultraplot. Pass the "
367
+ "parameters as keyword arguments instead."
368
+ )
369
+ kwargs.update(kw or {})
370
+ figure_kw = _pop_params(kwargs, fig._format_signature)
371
+ gridspec_kw = _pop_params(kwargs, pgridspec.GridSpec._update_params)
372
+
373
+ # Create or update the gridspec and add subplots with subplotspecs
374
+ # NOTE: The gridspec is added to the figure when we pass the subplotspec
375
+ if gs is None:
376
+ if "layout_array" not in gridspec_kw:
377
+ gridspec_kw = {**gridspec_kw, "layout_array": array}
378
+ gs = pgridspec.GridSpec(*array.shape, **gridspec_kw)
379
+ else:
380
+ gs.update(**gridspec_kw)
381
+ axs = naxs * [None] # list of axes
382
+ axids = [np.where(array == i) for i in np.sort(np.unique(array)) if i > 0]
383
+ axcols = np.array([[x.min(), x.max()] for _, x in axids])
384
+ axrows = np.array([[y.min(), y.max()] for y, _ in axids])
385
+ for idx in range(naxs):
386
+ num = idx + 1
387
+ x0, x1 = axcols[idx, 0], axcols[idx, 1]
388
+ y0, y1 = axrows[idx, 0], axrows[idx, 1]
389
+ ss = gs[y0 : y1 + 1, x0 : x1 + 1]
390
+ kw = {**kwargs, **axes_kw[num], "number": num}
391
+ axs[idx] = fig.add_subplot(ss, **kw)
392
+ fig.format(skip_axes=True, **figure_kw)
393
+ return pgridspec.SubplotGrid(axs)
394
+
395
+ @property
396
+ def subplotgrid(self):
397
+ """A SubplotGrid of numbered subplots sorted by number."""
398
+ return pgridspec.SubplotGrid([s for _, s in sorted(self.subplot_dict.items())])
@@ -0,0 +1 @@
1
+ __version__ = '2.4.1'
@@ -1054,7 +1054,6 @@ class Axes(_ExternalModeMixin, maxes.Axes):
1054
1054
  zorder = _not_none(zorder, 4)
1055
1055
 
1056
1056
  # Parse projection and inherit from the current axes by default
1057
- # NOTE: The _parse_proj method also accepts axes classes.
1058
1057
  proj = _not_none(proj=proj, projection=projection)
1059
1058
  if proj is None:
1060
1059
  if self._name in ("cartopy", "basemap"):
@@ -1492,7 +1491,7 @@ class Axes(_ExternalModeMixin, maxes.Axes):
1492
1491
  child._sharey_setup(parent)
1493
1492
 
1494
1493
  # Global sharing, use the reference subplot where compatible
1495
- ref = self.figure._subplot_dict.get(self.figure._refnum, None)
1494
+ ref = self.figure._get_subplot(self.figure._refnum)
1496
1495
  if self is not ref and ref is not None:
1497
1496
  if self.figure._sharex > 3:
1498
1497
  ok, reason = self.figure._share_axes_compatible(ref, self, "x")
@@ -21,9 +21,11 @@ from typing import Callable, Iterator, TypeVar
21
21
  import cycler
22
22
  import matplotlib.colors as mcolors
23
23
  import matplotlib.dates as mdates
24
+ import matplotlib.font_manager as mfonts
24
25
  import matplotlib.projections.polar as mpolar
25
26
  import matplotlib.scale as mscale
26
27
  import matplotlib.ticker as mticker
28
+ from matplotlib.ft2font import FT2Font
27
29
  import numpy as np
28
30
 
29
31
  from . import colors as pcolors
@@ -184,6 +186,17 @@ def _build_locator_registry() -> dict[str, object]:
184
186
  return registry
185
187
 
186
188
 
189
+ def _get_dms_symbol_kwargs() -> dict[str, str]:
190
+ """Return ASCII DMS symbols when the active font lacks prime glyphs."""
191
+ try:
192
+ path = mfonts.findfont(mfonts.FontProperties())
193
+ font = FT2Font(path)
194
+ has_primes = all(font.get_char_index(ord(symbol)) for symbol in "′″")
195
+ except Exception: # pragma: no cover - font lookup should be reliable
196
+ has_primes = False
197
+ return {} if has_primes else {"minute_symbol": "'", "second_symbol": '"'}
198
+
199
+
187
200
  def _build_formatter_registry() -> dict[str, object]:
188
201
  registry = { # note default LogFormatter uses ugly e+00 notation
189
202
  "none": mticker.NullFormatter,
@@ -227,9 +240,13 @@ def _build_formatter_registry() -> dict[str, object]:
227
240
  if hasattr(mdates, "ConciseDateFormatter"):
228
241
  registry["concise"] = mdates.ConciseDateFormatter
229
242
  if _version_cartopy >= "0.18":
230
- registry["dms"] = partial(pticker.DegreeFormatter, dms=True)
231
- registry["dmslon"] = partial(pticker.LongitudeFormatter, dms=True)
232
- registry["dmslat"] = partial(pticker.LatitudeFormatter, dms=True)
243
+ # Cartopy defaults to U+2032/U+2033 prime glyphs for minutes/seconds.
244
+ # Use them whenever the active font supports them, otherwise use ASCII
245
+ # fallbacks so that the built-in DMS presets never render missing glyphs.
246
+ dms_kwargs = {"dms": True, **_get_dms_symbol_kwargs()}
247
+ registry["dms"] = partial(pticker.DegreeFormatter, **dms_kwargs)
248
+ registry["dmslon"] = partial(pticker.LongitudeFormatter, **dms_kwargs)
249
+ registry["dmslat"] = partial(pticker.LatitudeFormatter, **dms_kwargs)
233
250
  return registry
234
251
 
235
252