ultraplot 2.1.0__tar.gz → 2.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (446) hide show
  1. {ultraplot-2.1.0/ultraplot.egg-info → ultraplot-2.1.2}/PKG-INFO +1 -1
  2. {ultraplot-2.1.0 → ultraplot-2.1.2}/codecov.yml +2 -0
  3. ultraplot-2.1.2/ultraplot/_version.py +1 -0
  4. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/base.py +78 -6
  5. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot.py +49 -14
  6. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/colorbar.py +5 -2
  7. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/gridspec.py +3 -1
  8. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/__init__.py +37 -11
  9. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_2dplots.py +121 -0
  10. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_colorbar.py +31 -0
  11. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_gridspec.py +19 -0
  12. {ultraplot-2.1.0 → ultraplot-2.1.2/ultraplot.egg-info}/PKG-INFO +1 -1
  13. ultraplot-2.1.0/ultraplot/_version.py +0 -1
  14. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/ISSUE_TEMPLATE.md +0 -0
  15. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/dependabot.yml +0 -0
  16. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/micromamba-condarc.yml +0 -0
  17. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/workflows/build-ultraplot.yml +0 -0
  18. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/workflows/main.yml +0 -0
  19. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/workflows/publish-pypi.yml +0 -0
  20. {ultraplot-2.1.0 → ultraplot-2.1.2}/.github/workflows/test-map.yml +0 -0
  21. {ultraplot-2.1.0 → ultraplot-2.1.2}/.gitignore +0 -0
  22. {ultraplot-2.1.0 → ultraplot-2.1.2}/.pre-commit-config.yaml +0 -0
  23. {ultraplot-2.1.0 → ultraplot-2.1.2}/.readthedocs.yml +0 -0
  24. {ultraplot-2.1.0 → ultraplot-2.1.2}/.zenodo.json +0 -0
  25. {ultraplot-2.1.0 → ultraplot-2.1.2}/CITATION.cff +0 -0
  26. {ultraplot-2.1.0 → ultraplot-2.1.2}/CODEOFCONDUCT.md +0 -0
  27. {ultraplot-2.1.0 → ultraplot-2.1.2}/CONTRIBUTING.rst +0 -0
  28. {ultraplot-2.1.0 → ultraplot-2.1.2}/INSTALL.rst +0 -0
  29. {ultraplot-2.1.0 → ultraplot-2.1.2}/LICENSE.txt +0 -0
  30. {ultraplot-2.1.0 → ultraplot-2.1.2}/README.rst +0 -0
  31. {ultraplot-2.1.0 → ultraplot-2.1.2}/UltraPlotLogo.svg +0 -0
  32. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/1dplots.py +0 -0
  33. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/2dplots.py +0 -0
  34. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/Makefile +0 -0
  35. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_ext/notoc.py +0 -0
  36. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_scripts/fetch_releases.py +0 -0
  37. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/custom.css +0 -0
  38. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/custom.js +0 -0
  39. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/cartesian_example.svg +0 -0
  40. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/colorbars_legends_example.svg +0 -0
  41. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/colormaps_example.svg +0 -0
  42. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/panels_example.svg +0 -0
  43. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/projection_example.svg +0 -0
  44. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/example_plots/subplot_example.svg +0 -0
  45. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_blank.svg +0 -0
  46. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_long.png +0 -0
  47. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_long.svg +0 -0
  48. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_social.png +0 -0
  49. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_social.svg +0 -0
  50. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_static/logo_square.png +0 -0
  51. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/_templates/whatsnew_sidebar.html +0 -0
  52. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/about.rst +0 -0
  53. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/api.rst +0 -0
  54. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/basics.py +0 -0
  55. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/cartesian.py +0 -0
  56. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/colorbars_legends.py +0 -0
  57. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/colormaps.py +0 -0
  58. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/colors.py +0 -0
  59. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/conf.py +0 -0
  60. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/configuration.rst +0 -0
  61. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/contributing.rst +0 -0
  62. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/cycles.py +0 -0
  63. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/README.txt +0 -0
  64. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/colors/01_cycle_colormap.py +0 -0
  65. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/colors/02_diverging_colormap.py +0 -0
  66. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/colors/README.txt +0 -0
  67. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/geo/01_robin_tracks.py +0 -0
  68. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/geo/02_orthographic_views.py +0 -0
  69. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/geo/03_projections_features.py +0 -0
  70. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/geo/README.txt +0 -0
  71. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/layouts/01_shared_axes_abc.py +0 -0
  72. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/layouts/02_complex_layout_insets.py +0 -0
  73. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/layouts/03_spanning_labels.py +0 -0
  74. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/layouts/README.txt +0 -0
  75. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/legends_colorbars/01_multi_colorbars.py +0 -0
  76. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/legends_colorbars/02_legend_inset_colorbar.py +0 -0
  77. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/legends_colorbars/03_semantic_legends.py +0 -0
  78. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/legends_colorbars/README.txt +0 -0
  79. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/01_curved_quiver.py +0 -0
  80. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/02_network_graph.py +0 -0
  81. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/03_lollipop.py +0 -0
  82. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/04_datetime_series.py +0 -0
  83. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/05_box_violin.py +0 -0
  84. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/06_ridge_plot.py +0 -0
  85. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/07_radar.py +0 -0
  86. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/07_sankey.py +0 -0
  87. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/08_chord_diagram.py +0 -0
  88. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/08_ternary.py +0 -0
  89. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/09_phylogeny.py +0 -0
  90. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/10_circos_bed.py +0 -0
  91. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/11_topic_ribbon.py +0 -0
  92. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/examples/plot_types/README.txt +0 -0
  93. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/external-links.rst +0 -0
  94. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/faq.rst +0 -0
  95. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/fonts.py +0 -0
  96. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/index.rst +0 -0
  97. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/insets_panels.py +0 -0
  98. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/install.rst +0 -0
  99. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/lazy_loading.rst +0 -0
  100. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/make.bat +0 -0
  101. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/networks.py +0 -0
  102. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/projections.py +0 -0
  103. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/requirements-rtd.txt +0 -0
  104. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/sphinxext/custom_roles.py +0 -0
  105. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/stats.py +0 -0
  106. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/subplots.py +0 -0
  107. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/ultraplotrc +0 -0
  108. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/usage.rst +0 -0
  109. {ultraplot-2.1.0 → ultraplot-2.1.2}/docs/why.rst +0 -0
  110. {ultraplot-2.1.0 → ultraplot-2.1.2}/environment.yml +0 -0
  111. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/PermanentMarker-Regular.ttf +0 -0
  112. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/environment-logo.yml +0 -0
  113. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/logo.py +0 -0
  114. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/run-linter.sh +0 -0
  115. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/webicon.py +0 -0
  116. {ultraplot-2.1.0 → ultraplot-2.1.2}/logo/whyUltraPlot.svg +0 -0
  117. {ultraplot-2.1.0 → ultraplot-2.1.2}/noxfile.py +0 -0
  118. {ultraplot-2.1.0 → ultraplot-2.1.2}/pyproject.toml +0 -0
  119. {ultraplot-2.1.0 → ultraplot-2.1.2}/requirements-minimal.txt +0 -0
  120. {ultraplot-2.1.0 → ultraplot-2.1.2}/setup.cfg +0 -0
  121. {ultraplot-2.1.0 → ultraplot-2.1.2}/tools/ci/build_test_map.py +0 -0
  122. {ultraplot-2.1.0 → ultraplot-2.1.2}/tools/ci/select_tests.py +0 -0
  123. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/__init__.py +0 -0
  124. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/_lazy.py +0 -0
  125. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/__init__.py +0 -0
  126. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/cartesian.py +0 -0
  127. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/container.py +0 -0
  128. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/geo.py +0 -0
  129. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot_types/__init__.py +0 -0
  130. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot_types/circlize.py +0 -0
  131. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot_types/curved_quiver.py +0 -0
  132. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot_types/ribbon.py +0 -0
  133. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/plot_types/sankey.py +0 -0
  134. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/polar.py +0 -0
  135. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/shared.py +0 -0
  136. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/axes/three.py +0 -0
  137. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Algae.rgb +0 -0
  138. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Amp.rgb +0 -0
  139. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/BR.rgb +0 -0
  140. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Balance.rgb +0 -0
  141. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues1_r.xml +0 -0
  142. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues2.xml +0 -0
  143. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues3.xml +0 -0
  144. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues4_r.xml +0 -0
  145. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues5.xml +0 -0
  146. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues6.xml +0 -0
  147. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues7.xml +0 -0
  148. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues8.xml +0 -0
  149. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Blues9.xml +0 -0
  150. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Boreal.json +0 -0
  151. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns1.xml +0 -0
  152. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns2.xml +0 -0
  153. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns3.xml +0 -0
  154. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns4.xml +0 -0
  155. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns5.xml +0 -0
  156. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns6.xml +0 -0
  157. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns7.xml +0 -0
  158. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns8.xml +0 -0
  159. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Browns9.xml +0 -0
  160. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/ColdHot.rgb +0 -0
  161. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Crest.rgb +0 -0
  162. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Curl.rgb +0 -0
  163. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Deep.rgb +0 -0
  164. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Delta.rgb +0 -0
  165. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Dense.rgb +0 -0
  166. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Div.json +0 -0
  167. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/DryWet.json +0 -0
  168. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Dusk.json +0 -0
  169. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Fire.json +0 -0
  170. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Flare.rgb +0 -0
  171. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Glacial.json +0 -0
  172. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens1_r.xml +0 -0
  173. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens2.xml +0 -0
  174. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens3_r.xml +0 -0
  175. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens4.xml +0 -0
  176. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens5.xml +0 -0
  177. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens6_r.xml +0 -0
  178. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens7.xml +0 -0
  179. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Greens8.xml +0 -0
  180. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Haline.rgb +0 -0
  181. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Ice.rgb +0 -0
  182. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/IceFire.rgb +0 -0
  183. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Mako.rgb +0 -0
  184. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Marine.json +0 -0
  185. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Matter.rgb +0 -0
  186. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Mono.txt +0 -0
  187. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/MonoCycle.txt +0 -0
  188. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/NegPos.json +0 -0
  189. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Oranges1.xml +0 -0
  190. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Oranges2.xml +0 -0
  191. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Oranges3.xml +0 -0
  192. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Oranges4.xml +0 -0
  193. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Oxy.rgb +0 -0
  194. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Phase.rgb +0 -0
  195. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Purples1_r.xml +0 -0
  196. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Purples2.xml +0 -0
  197. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Purples3.xml +0 -0
  198. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Reds1.xml +0 -0
  199. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Reds2.xml +0 -0
  200. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Reds3.xml +0 -0
  201. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Reds4.xml +0 -0
  202. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Reds5.xml +0 -0
  203. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Rocket.rgb +0 -0
  204. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Solar.rgb +0 -0
  205. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Speed.rgb +0 -0
  206. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Stellar.json +0 -0
  207. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Sunrise.json +0 -0
  208. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Sunset.json +0 -0
  209. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Tempo.rgb +0 -0
  210. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Thermal.rgb +0 -0
  211. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Turbid.rgb +0 -0
  212. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Vivid.xml +0 -0
  213. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Vlag.rgb +0 -0
  214. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Yellows1.xml +0 -0
  215. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Yellows2.xml +0 -0
  216. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Yellows3.xml +0 -0
  217. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/Yellows4.xml +0 -0
  218. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/acton.txt +0 -0
  219. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/bam.txt +0 -0
  220. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/bamO.txt +0 -0
  221. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/bamako.txt +0 -0
  222. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/batlow.txt +0 -0
  223. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/batlowK.txt +0 -0
  224. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/batlowW.txt +0 -0
  225. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/berlin.txt +0 -0
  226. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/bilbao.txt +0 -0
  227. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/broc.txt +0 -0
  228. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/brocO.txt +0 -0
  229. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/buda.txt +0 -0
  230. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/bukavu.txt +0 -0
  231. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/cork.txt +0 -0
  232. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/corkO.txt +0 -0
  233. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/davos.txt +0 -0
  234. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/devon.txt +0 -0
  235. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/fes.txt +0 -0
  236. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/hawaii.txt +0 -0
  237. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/imola.txt +0 -0
  238. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/lajolla.txt +0 -0
  239. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/lapaz.txt +0 -0
  240. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/lisbon.txt +0 -0
  241. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/nuuk.txt +0 -0
  242. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/oleron.txt +0 -0
  243. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/oslo.txt +0 -0
  244. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/roma.txt +0 -0
  245. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/romaO.txt +0 -0
  246. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/tofino.txt +0 -0
  247. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/tokyo.txt +0 -0
  248. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/turku.txt +0 -0
  249. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/vanimo.txt +0 -0
  250. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/vik.txt +0 -0
  251. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cmaps/vikO.txt +0 -0
  252. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/colors/opencolor.txt +0 -0
  253. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/colors/xkcd.txt +0 -0
  254. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/colors.py +0 -0
  255. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/config.py +0 -0
  256. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/constructor.py +0 -0
  257. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/538.hex +0 -0
  258. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/FlatUI.hex +0 -0
  259. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/Qual1.rgb +0 -0
  260. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/Qual2.rgb +0 -0
  261. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/bmh.hex +0 -0
  262. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/classic.hex +0 -0
  263. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/colorblind.hex +0 -0
  264. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/colorblind10.hex +0 -0
  265. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/default.hex +0 -0
  266. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/ggplot.hex +0 -0
  267. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/seaborn.hex +0 -0
  268. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/cycles/tableau.hex +0 -0
  269. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/demos.py +0 -0
  270. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/externals/__init__.py +0 -0
  271. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/externals/hsluv.py +0 -0
  272. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/figure.py +0 -0
  273. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-Bold.ttf +0 -0
  274. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-ExtraLight.ttf +0 -0
  275. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-Heavy.ttf +0 -0
  276. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-Light.ttf +0 -0
  277. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-Medium.ttf +0 -0
  278. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-Regular.ttf +0 -0
  279. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-SemiBold.ttf +0 -0
  280. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraMath-UltraLight.ttf +0 -0
  281. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Black.ttf +0 -0
  282. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-BlackItalic.ttf +0 -0
  283. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Bold.ttf +0 -0
  284. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-BoldItalic.ttf +0 -0
  285. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-ExtraBold.ttf +0 -0
  286. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-ExtraBoldItalic.ttf +0 -0
  287. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-ExtraLight.ttf +0 -0
  288. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-ExtraLightItalic.ttf +0 -0
  289. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Italic.ttf +0 -0
  290. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Light.ttf +0 -0
  291. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-LightItalic.ttf +0 -0
  292. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Medium.ttf +0 -0
  293. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-MediumItalic.ttf +0 -0
  294. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-Regular.ttf +0 -0
  295. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-SemiBold.ttf +0 -0
  296. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/FiraSans-SemiBoldItalic.ttf +0 -0
  297. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_FIRAMATH.txt +0 -0
  298. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_FIRASANS.txt +0 -0
  299. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_NOTOSANS.txt +0 -0
  300. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_NOTOSERIF.txt +0 -0
  301. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_OPENSANS.txt +0 -0
  302. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_ROBOTO.txt +0 -0
  303. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_SOURCESANS.txt +0 -0
  304. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_SOURCESERIF.txt +0 -0
  305. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_TEXGYRE.txt +0 -0
  306. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/LICENSE_UBUNTU.txt +0 -0
  307. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSans-Bold.ttf +0 -0
  308. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSans-BoldItalic.ttf +0 -0
  309. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSans-Italic.ttf +0 -0
  310. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSans-Regular.ttf +0 -0
  311. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSerif-Bold.ttf +0 -0
  312. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSerif-BoldItalic.ttf +0 -0
  313. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSerif-Italic.ttf +0 -0
  314. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/NotoSerif-Regular.ttf +0 -0
  315. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-Bold.ttf +0 -0
  316. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-BoldItalic.ttf +0 -0
  317. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-Italic.ttf +0 -0
  318. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-Regular.ttf +0 -0
  319. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-Semibold.ttf +0 -0
  320. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  321. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Black.ttf +0 -0
  322. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-BlackItalic.ttf +0 -0
  323. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Bold.ttf +0 -0
  324. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-BoldItalic.ttf +0 -0
  325. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Italic.ttf +0 -0
  326. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Light.ttf +0 -0
  327. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-LightItalic.ttf +0 -0
  328. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Medium.ttf +0 -0
  329. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-MediumItalic.ttf +0 -0
  330. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Roboto-Regular.ttf +0 -0
  331. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-Black.ttf +0 -0
  332. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-BlackItalic.ttf +0 -0
  333. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-Bold.ttf +0 -0
  334. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-BoldItalic.ttf +0 -0
  335. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-ExtraLight.ttf +0 -0
  336. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
  337. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-Italic.ttf +0 -0
  338. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-Light.ttf +0 -0
  339. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-LightItalic.ttf +0 -0
  340. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-Regular.ttf +0 -0
  341. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-SemiBold.ttf +0 -0
  342. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
  343. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-Black.ttf +0 -0
  344. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-BlackItalic.ttf +0 -0
  345. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-Bold.ttf +0 -0
  346. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-BoldItalic.ttf +0 -0
  347. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-ExtraLight.ttf +0 -0
  348. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-ExtraLightItalic.ttf +0 -0
  349. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-Italic.ttf +0 -0
  350. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-Light.ttf +0 -0
  351. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-LightItalic.ttf +0 -0
  352. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-Regular.ttf +0 -0
  353. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-SemiBold.ttf +0 -0
  354. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/SourceSerifPro-SemiBoldItalic.ttf +0 -0
  355. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-Bold.ttf +0 -0
  356. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-BoldItalic.ttf +0 -0
  357. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-Italic.ttf +0 -0
  358. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-Light.ttf +0 -0
  359. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-LightItalic.ttf +0 -0
  360. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-Medium.ttf +0 -0
  361. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-MediumItalic.ttf +0 -0
  362. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/Ubuntu-Regular.ttf +0 -0
  363. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreadventor-bold.ttf +0 -0
  364. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreadventor-bolditalic.ttf +0 -0
  365. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreadventor-italic.ttf +0 -0
  366. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreadventor-regular.ttf +0 -0
  367. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrebonum-bold.ttf +0 -0
  368. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrebonum-bolditalic.ttf +0 -0
  369. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrebonum-italic.ttf +0 -0
  370. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrebonum-regular.ttf +0 -0
  371. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrechorus-mediumitalic.ttf +0 -0
  372. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrecursor-bold.ttf +0 -0
  373. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrecursor-bolditalic.ttf +0 -0
  374. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrecursor-italic.ttf +0 -0
  375. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrecursor-regular.ttf +0 -0
  376. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreheros-bold.ttf +0 -0
  377. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreheros-bolditalic.ttf +0 -0
  378. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreheros-italic.ttf +0 -0
  379. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreheros-regular.ttf +0 -0
  380. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrepagella-bold.ttf +0 -0
  381. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrepagella-bolditalic.ttf +0 -0
  382. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrepagella-italic.ttf +0 -0
  383. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyrepagella-regular.ttf +0 -0
  384. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreschola-bold.ttf +0 -0
  385. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreschola-bolditalic.ttf +0 -0
  386. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreschola-italic.ttf +0 -0
  387. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyreschola-regular.ttf +0 -0
  388. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyretermes-bold.ttf +0 -0
  389. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyretermes-bolditalic.ttf +0 -0
  390. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyretermes-italic.ttf +0 -0
  391. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/fonts/texgyretermes-regular.ttf +0 -0
  392. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/benchmarks.py +0 -0
  393. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/context.py +0 -0
  394. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/docstring.py +0 -0
  395. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/fonts.py +0 -0
  396. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/guides.py +0 -0
  397. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/inputs.py +0 -0
  398. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/labels.py +0 -0
  399. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/rcsetup.py +0 -0
  400. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/versions.py +0 -0
  401. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/internals/warnings.py +0 -0
  402. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/legend.py +0 -0
  403. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/proj.py +0 -0
  404. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/scale.py +0 -0
  405. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/__init__.py +0 -0
  406. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/conftest.py +0 -0
  407. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_1dplots.py +0 -0
  408. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_animation.py +0 -0
  409. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_axes.py +0 -0
  410. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_base.py +0 -0
  411. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_circlize_integration.py +0 -0
  412. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_colormap.py +0 -0
  413. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_colors.py +0 -0
  414. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_config.py +0 -0
  415. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_constructor.py +0 -0
  416. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_demos.py +0 -0
  417. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_docs.py +0 -0
  418. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_external_axes_container_integration.py +0 -0
  419. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_external_container_edge_cases.py +0 -0
  420. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_external_container_mocked.py +0 -0
  421. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_figure.py +0 -0
  422. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_fonts.py +0 -0
  423. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_format.py +0 -0
  424. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_geographic.py +0 -0
  425. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_handlers.py +0 -0
  426. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_imports.py +0 -0
  427. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_imshow.py +0 -0
  428. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_inputs.py +0 -0
  429. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_inset.py +0 -0
  430. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_integration.py +0 -0
  431. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_legend.py +0 -0
  432. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_plot.py +0 -0
  433. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_projections.py +0 -0
  434. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_statistical_plotting.py +0 -0
  435. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_subplots.py +0 -0
  436. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_tickers.py +0 -0
  437. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/tests/test_ultralayout.py +0 -0
  438. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/text.py +0 -0
  439. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/ticker.py +0 -0
  440. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/ui.py +0 -0
  441. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/ultralayout.py +0 -0
  442. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot/utils.py +0 -0
  443. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot.egg-info/SOURCES.txt +0 -0
  444. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot.egg-info/dependency_links.txt +0 -0
  445. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot.egg-info/requires.txt +0 -0
  446. {ultraplot-2.1.0 → ultraplot-2.1.2}/ultraplot.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultraplot
3
- Version: 2.1.0
3
+ Version: 2.1.2
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>
@@ -23,6 +23,8 @@ coverage:
23
23
  - "!logo/*"
24
24
  - "!docs/*"
25
25
  - "!ultraplot/tests/*"
26
+ - "!ultraplot/demos.py"
27
+
26
28
 
27
29
  tests:
28
30
  target: 95.0%
@@ -0,0 +1 @@
1
+ __version__ = '2.1.2'
@@ -3149,19 +3149,31 @@ class Axes(_ExternalModeMixin, maxes.Axes):
3149
3149
  self._colorbar_fill.update_ticks(manual_only=True) # only if needed
3150
3150
  if self._inset_parent is not None and self._inset_zoom:
3151
3151
  self.indicate_inset_zoom()
3152
+ needs_inset_reflow = bool(getattr(self, "_inset_colorbar_needs_reflow", False))
3153
+ has_inset_frame = bool(
3154
+ getattr(self, "_inset_colorbar_frame", None) is not None
3155
+ and getattr(self, "_inset_colorbar_obj", None)
3156
+ )
3152
3157
  super().draw(renderer, *args, **kwargs)
3153
- if getattr(self, "_inset_colorbar_obj", None) and getattr(
3154
- self, "_inset_colorbar_needs_reflow", False
3155
- ):
3156
- self._inset_colorbar_needs_reflow = False
3158
+ if has_inset_frame:
3159
+ if not needs_inset_reflow:
3160
+ needs_inset_reflow = _inset_colorbar_frame_needs_reflow(
3161
+ self._inset_colorbar_obj,
3162
+ labelloc=getattr(self, "_inset_colorbar_labelloc", None),
3163
+ renderer=renderer,
3164
+ )
3165
+ if has_inset_frame and needs_inset_reflow:
3157
3166
  _reflow_inset_colorbar_frame(
3158
3167
  self._inset_colorbar_obj,
3159
3168
  labelloc=getattr(self, "_inset_colorbar_labelloc", None),
3160
3169
  ticklen=getattr(
3161
3170
  self, "_inset_colorbar_ticklen", units(rc["tick.len"], "pt")
3162
3171
  ),
3172
+ renderer=renderer,
3163
3173
  )
3164
- self.figure.canvas.draw_idle()
3174
+ self._inset_colorbar_needs_reflow = False
3175
+ # Re-draw synchronously so the current render pass sees reflowed bounds.
3176
+ super().draw(renderer, *args, **kwargs)
3165
3177
 
3166
3178
  def get_tightbbox(self, renderer, *args, **kwargs):
3167
3179
  # Perform extra post-processing steps
@@ -4581,11 +4593,71 @@ def _apply_inset_colorbar_layout(
4581
4593
  frame.set_bounds(*bounds_frame)
4582
4594
 
4583
4595
 
4596
+ def _inset_colorbar_frame_needs_reflow(colorbar, *, labelloc: str, renderer) -> bool:
4597
+ cax = colorbar.ax
4598
+ layout = getattr(cax, "_inset_colorbar_layout", None)
4599
+ frame = getattr(cax, "_inset_colorbar_frame", None)
4600
+ if not layout or frame is None:
4601
+ return False
4602
+
4603
+ orientation = layout["orientation"]
4604
+ loc = layout["loc"]
4605
+ ticklocation = layout["ticklocation"]
4606
+ labelloc_layout = labelloc if isinstance(labelloc, str) else ticklocation
4607
+ bboxes = []
4608
+
4609
+ longaxis = _get_colorbar_long_axis(colorbar)
4610
+ try:
4611
+ bbox = longaxis.get_tightbbox(renderer)
4612
+ except Exception:
4613
+ bbox = None
4614
+ if bbox is not None:
4615
+ bboxes.append(bbox)
4616
+
4617
+ label_axis = _get_axis_for(
4618
+ labelloc_layout, loc, orientation=orientation, ax=colorbar
4619
+ )
4620
+ if label_axis.label.get_text():
4621
+ try:
4622
+ bboxes.append(label_axis.label.get_window_extent(renderer=renderer))
4623
+ except Exception:
4624
+ pass
4625
+
4626
+ for artist in (
4627
+ getattr(colorbar, "outline", None),
4628
+ getattr(colorbar, "solids", None),
4629
+ getattr(colorbar, "dividers", None),
4630
+ ):
4631
+ if artist is None:
4632
+ continue
4633
+ try:
4634
+ bboxes.append(artist.get_window_extent(renderer=renderer))
4635
+ except Exception:
4636
+ pass
4637
+
4638
+ if not bboxes:
4639
+ return False
4640
+
4641
+ x0 = min(bbox.x0 for bbox in bboxes)
4642
+ y0 = min(bbox.y0 for bbox in bboxes)
4643
+ x1 = max(bbox.x1 for bbox in bboxes)
4644
+ y1 = max(bbox.y1 for bbox in bboxes)
4645
+ frame_bbox = frame.get_window_extent(renderer=renderer)
4646
+ tol = 1.0
4647
+ return (
4648
+ frame_bbox.x0 > x0 + tol
4649
+ or frame_bbox.y0 > y0 + tol
4650
+ or frame_bbox.x1 < x1 - tol
4651
+ or frame_bbox.y1 < y1 - tol
4652
+ )
4653
+
4654
+
4584
4655
  def _reflow_inset_colorbar_frame(
4585
4656
  colorbar,
4586
4657
  *,
4587
4658
  labelloc: str,
4588
4659
  ticklen: float,
4660
+ renderer=None,
4589
4661
  ):
4590
4662
  cax = colorbar.ax
4591
4663
  layout = getattr(cax, "_inset_colorbar_layout", None)
@@ -4623,7 +4695,7 @@ def _reflow_inset_colorbar_frame(
4623
4695
  cb_width = width
4624
4696
  cb_height = length
4625
4697
 
4626
- renderer = cax.figure._get_renderer()
4698
+ renderer = renderer or cax.figure._get_renderer()
4627
4699
  if hasattr(colorbar, "update_ticks"):
4628
4700
  colorbar.update_ticks(manual_only=True)
4629
4701
  bboxes = []
@@ -4141,6 +4141,7 @@ class PlotAxes(base.Axes):
4141
4141
  # NOTE: Unlike xarray, but like matplotlib, vmin and vmax only approximately
4142
4142
  # determine level range. Levels are selected with Locator.tick_values().
4143
4143
  levels = None # unused
4144
+ explicit_limits = False
4144
4145
  isdiverging = False
4145
4146
  if not discrete and not skip_autolev:
4146
4147
  vmin, vmax, kwargs = self._parse_level_lim(
@@ -4150,7 +4151,15 @@ class PlotAxes(base.Axes):
4150
4151
  if abs(np.sign(vmax) - np.sign(vmin)) == 2:
4151
4152
  isdiverging = True
4152
4153
  if discrete:
4153
- levels, vmin, vmax, norm, norm_kw, kwargs = self._parse_level_vals(
4154
+ (
4155
+ levels,
4156
+ vmin,
4157
+ vmax,
4158
+ norm,
4159
+ norm_kw,
4160
+ explicit_limits,
4161
+ kwargs,
4162
+ ) = self._parse_level_vals(
4154
4163
  *args,
4155
4164
  vmin=vmin,
4156
4165
  vmax=vmax,
@@ -4199,6 +4208,7 @@ class PlotAxes(base.Axes):
4199
4208
  center_levels=center_levels,
4200
4209
  extend=extend,
4201
4210
  min_levels=min_levels,
4211
+ explicit_limits=explicit_limits,
4202
4212
  **kwargs,
4203
4213
  )
4204
4214
  params = _pop_params(kwargs, *self._level_parsers, ignore_internal=True)
@@ -4462,7 +4472,6 @@ class PlotAxes(base.Axes):
4462
4472
  center_levels = _not_none(center_levels, rc["colorbar.center_levels"])
4463
4473
  vmin = _not_none(vmin=vmin, norm_kw_vmin=norm_kw.pop("vmin", None))
4464
4474
  vmax = _not_none(vmax=vmax, norm_kw_vmax=norm_kw.pop("vmax", None))
4465
- norm = constructor.Norm(norm or "linear", **norm_kw)
4466
4475
  symmetric = _not_none(
4467
4476
  symmetric=symmetric,
4468
4477
  locator_kw_symmetric=locator_kw.pop("symmetric", None),
@@ -4555,6 +4564,8 @@ class PlotAxes(base.Axes):
4555
4564
  nozero=False,
4556
4565
  norm=None,
4557
4566
  norm_kw=None,
4567
+ vmin=None,
4568
+ vmax=None,
4558
4569
  skip_autolev=False,
4559
4570
  min_levels=None,
4560
4571
  center_levels=None,
@@ -4577,7 +4588,9 @@ class PlotAxes(base.Axes):
4577
4588
  Whether to remove out non-positive, non-negative, and zero-valued
4578
4589
  levels. The latter is useful for single-color contour plots.
4579
4590
  norm, norm_kw : optional
4580
- Passed to `Norm`. Used to possbily infer levels or to convert values.
4591
+ Passed to `Norm`. Used to possibly infer levels or to convert values.
4592
+ vmin, vmax : float, optional
4593
+ The user input normalization range.
4581
4594
  skip_autolev : bool, optional
4582
4595
  Whether to skip automatic level generation.
4583
4596
  min_levels : int, optional
@@ -4587,6 +4600,8 @@ class PlotAxes(base.Axes):
4587
4600
  -------
4588
4601
  levels : list of float
4589
4602
  The level edges.
4603
+ explicit_limits : bool
4604
+ Whether the user explicitly provided `vmin` and/or `vmax`.
4590
4605
  **kwargs
4591
4606
  Unused arguments.
4592
4607
  """
@@ -4625,7 +4640,9 @@ class PlotAxes(base.Axes):
4625
4640
  return array
4626
4641
 
4627
4642
  # Parse input arguments and resolve incompatibilities
4628
- vmin = vmax = None
4643
+ explicit_limits = vmin is not None or vmax is not None
4644
+ line_contours = min_levels == 1
4645
+ keep_explicit_line_limits = line_contours and explicit_limits
4629
4646
  levels = _not_none(N=N, levels=levels, norm_kw_levs=norm_kw.pop("levels", None))
4630
4647
  if positive and negative:
4631
4648
  warnings._warn_ultraplot(
@@ -4684,6 +4701,8 @@ class PlotAxes(base.Axes):
4684
4701
  levels, kwargs = self._parse_level_num(
4685
4702
  *args,
4686
4703
  levels=levels,
4704
+ vmin=vmin,
4705
+ vmax=vmax,
4687
4706
  norm=norm,
4688
4707
  norm_kw=norm_kw,
4689
4708
  extend=extend,
@@ -4696,8 +4715,8 @@ class PlotAxes(base.Axes):
4696
4715
  levels = values = None
4697
4716
 
4698
4717
  # Determine default colorbar locator and norm and apply filters
4699
- # NOTE: DiscreteNorm does not currently support vmin and
4700
- # vmax different from level list minimum and maximum.
4718
+ # NOTE: Preserve explicit vmin/vmax only for line contours, where levels
4719
+ # represent contour values rather than filled bins.
4701
4720
  # NOTE: The level restriction should have no effect if levels were generated
4702
4721
  # automatically. However want to apply these to manual-input levels as well.
4703
4722
  if levels is not None:
@@ -4705,15 +4724,21 @@ class PlotAxes(base.Axes):
4705
4724
  if len(levels) == 0: # skip
4706
4725
  pass
4707
4726
  elif len(levels) == 1: # use central colormap color
4708
- vmin, vmax = levels[0] - 1, levels[0] + 1
4727
+ if not keep_explicit_line_limits or vmin is None:
4728
+ vmin = levels[0] - 1
4729
+ if not keep_explicit_line_limits or vmax is None:
4730
+ vmax = levels[0] + 1
4709
4731
  else: # use minimum and maximum
4710
- vmin, vmax = np.min(levels), np.max(levels)
4732
+ if not keep_explicit_line_limits or vmin is None:
4733
+ vmin = np.min(levels)
4734
+ if not keep_explicit_line_limits or vmax is None:
4735
+ vmax = np.max(levels)
4711
4736
  if not np.allclose(levels[1] - levels[0], np.diff(levels)):
4712
4737
  norm = _not_none(norm, "segmented")
4713
4738
  if norm in ("segments", "segmented"):
4714
4739
  norm_kw["levels"] = levels
4715
4740
 
4716
- return levels, vmin, vmax, norm, norm_kw, kwargs
4741
+ return levels, vmin, vmax, norm, norm_kw, explicit_limits, kwargs
4717
4742
 
4718
4743
  @staticmethod
4719
4744
  def _parse_level_norm(
@@ -4726,6 +4751,7 @@ class PlotAxes(base.Axes):
4726
4751
  discrete_ticks=None,
4727
4752
  discrete_labels=None,
4728
4753
  center_levels=None,
4754
+ explicit_limits=False,
4729
4755
  **kwargs,
4730
4756
  ):
4731
4757
  """
@@ -4748,11 +4774,14 @@ class PlotAxes(base.Axes):
4748
4774
  The colorbar locations to tick.
4749
4775
  discrete_labels : array-like, optional
4750
4776
  The colorbar tick labels.
4777
+ explicit_limits : bool, optional
4778
+ Whether `vmin`/`vmax` were explicitly provided by the user.
4751
4779
 
4752
4780
  Returns
4753
4781
  -------
4754
- norm : `~ultraplot.colors.DiscreteNorm`
4755
- The discrete normalizer.
4782
+ norm : `~ultraplot.colors.DiscreteNorm` or `~matplotlib.colors.Normalize`
4783
+ The discrete normalizer, or the original continuous normalizer when
4784
+ line contours have explicit limits or use qualitative color lists.
4756
4785
  cmap : `~matplotlib.colors.Colormap`
4757
4786
  The possibly-modified colormap.
4758
4787
  kwargs
@@ -4814,10 +4843,16 @@ class PlotAxes(base.Axes):
4814
4843
  elif extend == "max":
4815
4844
  unique = "neither"
4816
4845
 
4817
- # Generate DiscreteNorm and update "child" norm with vmin and vmax from
4818
- # levels. This lets the colorbar set tick locations properly!
4846
+ # Generate DiscreteNorm for filled-contour style bins. For line contours
4847
+ # with explicit limits or qualitative color lists, keep the continuous
4848
+ # normalizer to preserve one-to-one value->color mapping.
4819
4849
  center_levels = _not_none(center_levels, rc["colorbar.center_levels"])
4820
- if not isinstance(norm, mcolors.BoundaryNorm) and len(levels) > 1:
4850
+ preserve_line_mapping = min_levels == 1 and (explicit_limits or qualitative)
4851
+ if (
4852
+ not preserve_line_mapping
4853
+ and not isinstance(norm, mcolors.BoundaryNorm)
4854
+ and len(levels) > 1
4855
+ ):
4821
4856
  norm = pcolors.DiscreteNorm(
4822
4857
  levels,
4823
4858
  norm=norm,
@@ -347,7 +347,9 @@ class UltraColorbar:
347
347
  cax._inset_colorbar_obj = obj
348
348
  cax._inset_colorbar_labelloc = labelloc
349
349
  cax._inset_colorbar_ticklen = ticklen
350
- _register_inset_colorbar_reflow(ax.figure)
350
+ has_frame = getattr(cax, "_inset_colorbar_frame", None) is not None
351
+ if has_frame:
352
+ _register_inset_colorbar_reflow(ax.figure)
351
353
  kw_outline = {"edgecolor": color, "linewidth": linewidth}
352
354
  if obj.outline is not None:
353
355
  obj.outline.update(kw_outline)
@@ -958,6 +960,7 @@ def _reflow_inset_colorbar_frame(
958
960
  *,
959
961
  labelloc: Optional[str],
960
962
  ticklen: float,
963
+ renderer=None,
961
964
  ):
962
965
  cax = colorbar.ax
963
966
  layout = getattr(cax, "_inset_colorbar_layout", None)
@@ -995,7 +998,7 @@ def _reflow_inset_colorbar_frame(
995
998
  cb_width = width
996
999
  cb_height = length
997
1000
 
998
- renderer = cax.figure._get_renderer()
1001
+ renderer = renderer or cax.figure._get_renderer()
999
1002
  if hasattr(colorbar, "update_ticks"):
1000
1003
  colorbar.update_ticks(manual_only=True)
1001
1004
  bboxes = []
@@ -1988,9 +1988,11 @@ class SubplotGrid(MutableSequence, list):
1988
1988
  elif not isinstance(objs, list):
1989
1989
  objs = [objs]
1990
1990
 
1991
+ # Spanning subplots can appear more than once in the sliced slot grid.
1992
+ # De-duplicate while preserving order so method dispatch does not repeat.
1993
+ objs = list(dict.fromkeys(objs))
1991
1994
  if len(objs) == 1:
1992
1995
  return objs[0]
1993
- objs = [obj for obj in objs if obj is not None]
1994
1996
  return SubplotGrid(objs)
1995
1997
 
1996
1998
  def __setitem__(self, key, value):
@@ -4,6 +4,7 @@ Internal utilities.
4
4
  """
5
5
 
6
6
  # Import statements
7
+ import functools
7
8
  import inspect
8
9
  from importlib import import_module
9
10
  from numbers import Integral, Real
@@ -155,6 +156,40 @@ _alias_maps = {
155
156
  },
156
157
  }
157
158
 
159
+
160
+ _INTERNAL_POP_PARAMS = frozenset(
161
+ {
162
+ "default_cmap",
163
+ "default_discrete",
164
+ "inbounds",
165
+ "plot_contours",
166
+ "plot_lines",
167
+ "skip_autolev",
168
+ "to_centers",
169
+ }
170
+ )
171
+
172
+
173
+ @functools.lru_cache(maxsize=256)
174
+ def _signature_cached(func):
175
+ """
176
+ Cache inspect.signature lookups for hot utility paths.
177
+ """
178
+ return inspect.signature(func)
179
+
180
+
181
+ def _get_signature(func):
182
+ """
183
+ Return a signature, normalizing bound methods to their underlying function.
184
+ """
185
+ key = getattr(func, "__func__", func)
186
+ try:
187
+ return _signature_cached(key)
188
+ except TypeError:
189
+ # Some callable objects may be unhashable for lru_cache keys.
190
+ return inspect.signature(func)
191
+
192
+
158
193
  _LAZY_ATTRS = {
159
194
  "benchmarks": ("benchmarks", None),
160
195
  "context": ("context", None),
@@ -224,28 +259,19 @@ def _pop_params(kwargs, *funcs, ignore_internal=False):
224
259
  """
225
260
  Pop parameters of the input functions or methods.
226
261
  """
227
- internal_params = {
228
- "default_cmap",
229
- "default_discrete",
230
- "inbounds",
231
- "plot_contours",
232
- "plot_lines",
233
- "skip_autolev",
234
- "to_centers",
235
- }
236
262
  output = {}
237
263
  for func in funcs:
238
264
  if isinstance(func, inspect.Signature):
239
265
  sig = func
240
266
  elif callable(func):
241
- sig = inspect.signature(func)
267
+ sig = _get_signature(func)
242
268
  elif func is None:
243
269
  continue
244
270
  else:
245
271
  raise RuntimeError(f"Internal error. Invalid function {func!r}.")
246
272
  for key in sig.parameters:
247
273
  value = kwargs.pop(key, None)
248
- if ignore_internal and key in internal_params:
274
+ if ignore_internal and key in _INTERNAL_POP_PARAMS:
249
275
  continue
250
276
  if value is not None:
251
277
  output[key] = value
@@ -6,6 +6,7 @@ Test 2D plotting overrides.
6
6
  import numpy as np
7
7
  import pytest
8
8
  import xarray as xr
9
+ from matplotlib.colors import Normalize
9
10
 
10
11
  import ultraplot as uplt, warnings
11
12
 
@@ -291,6 +292,126 @@ def test_levels_with_vmin_vmax(rng):
291
292
  return fig
292
293
 
293
294
 
295
+ def test_contour_levels_respect_explicit_vmin_vmax():
296
+ """
297
+ Explicit `vmin` and `vmax` should be preserved for line contours.
298
+ """
299
+ data = np.linspace(0, 10, 25).reshape((5, 5))
300
+ levels = [2, 4, 6]
301
+ _, ax = uplt.subplots()
302
+ m = ax.contour(data, levels=levels, cmap="viridis", vmin=0, vmax=10)
303
+ assert m.norm.vmin == pytest.approx(0)
304
+ assert m.norm.vmax == pytest.approx(10)
305
+ assert m.norm(3) == pytest.approx(0.3)
306
+ assert m.norm(5) == pytest.approx(0.5)
307
+
308
+
309
+ def test_contour_levels_default_stretch():
310
+ """
311
+ Without explicit limits, level bins should continue to span full cmap range.
312
+ """
313
+ data = np.linspace(0, 10, 25).reshape((5, 5))
314
+ levels = [2, 4, 6]
315
+ _, ax = uplt.subplots()
316
+ m = ax.contourf(data, levels=levels, cmap="viridis")
317
+ assert m.norm(3) == pytest.approx(0.0)
318
+ assert m.norm(5) == pytest.approx(1.0)
319
+
320
+
321
+ def test_contour_levels_default_use_discrete_norm():
322
+ """
323
+ Line contours should retain DiscreteNorm behavior unless limits are explicit.
324
+ """
325
+ data = np.linspace(0, 10, 25).reshape((5, 5))
326
+ levels = [2, 4, 6]
327
+ _, ax = uplt.subplots()
328
+ m = ax.contour(data, levels=levels, cmap="viridis")
329
+ assert hasattr(m.norm, "_norm")
330
+ assert m.norm(3) == pytest.approx(0.0)
331
+ assert m.norm(5) == pytest.approx(1.0)
332
+
333
+
334
+ def test_contourf_levels_keep_level_range_with_explicit_vmin_vmax():
335
+ """
336
+ Filled contour bins keep level-based discrete scaling.
337
+ """
338
+ data = np.linspace(0, 10, 25).reshape((5, 5))
339
+ levels = [2, 4, 6]
340
+ _, ax = uplt.subplots()
341
+ m = ax.contourf(data, levels=levels, cmap="viridis", vmin=0, vmax=10)
342
+ assert m.norm.vmin == pytest.approx(2)
343
+ assert m.norm.vmax == pytest.approx(6)
344
+ assert m.norm._norm.vmin == pytest.approx(2)
345
+ assert m.norm._norm.vmax == pytest.approx(6)
346
+ assert m.norm(3) == pytest.approx(0.0)
347
+ assert m.norm(5) == pytest.approx(1.0)
348
+
349
+
350
+ def test_contour_explicit_colors_match_levels():
351
+ """
352
+ Explicit contour line colors should map one-to-one with contour levels.
353
+ """
354
+ x = np.linspace(-1, 1, 100)
355
+ y = np.linspace(-1, 1, 100)
356
+ X, Y = np.meshgrid(x, y)
357
+ Z = np.exp(-(X**2 + Y**2))
358
+ levels = [0.3, 0.6, 0.9]
359
+ turbo = uplt.Colormap("turbo")
360
+ colors = turbo(Normalize(vmin=0, vmax=1)(levels))
361
+ _, ax = uplt.subplots()
362
+ m = ax.contour(X, Y, Z, levels=levels, colors=colors, linewidths=1)
363
+ assert np.allclose(np.asarray(m.get_edgecolor()), colors)
364
+
365
+
366
+ def test_tricontour_default_use_discrete_norm():
367
+ """
368
+ Triangular line contours should default to DiscreteNorm bin mapping.
369
+ """
370
+ rng = np.random.default_rng(51423)
371
+ x = rng.random(40)
372
+ y = rng.random(40)
373
+ z = np.sin(3 * x) + np.cos(3 * y)
374
+ levels = [-1.0, 0.0, 1.0]
375
+ _, ax = uplt.subplots()
376
+ m = ax.tricontour(x, y, z, levels=levels, cmap="viridis")
377
+ assert hasattr(m.norm, "_norm")
378
+ assert m.norm(-0.5) == pytest.approx(0.0)
379
+ assert m.norm(0.5) == pytest.approx(1.0)
380
+
381
+
382
+ def test_tricontour_levels_respect_explicit_vmin_vmax():
383
+ """
384
+ Triangular line contours preserve explicit normalization limits.
385
+ """
386
+ rng = np.random.default_rng(51423)
387
+ x = rng.random(40)
388
+ y = rng.random(40)
389
+ z = np.sin(3 * x) + np.cos(3 * y)
390
+ levels = [-1.0, 0.0, 1.0]
391
+ _, ax = uplt.subplots()
392
+ m = ax.tricontour(x, y, z, levels=levels, cmap="viridis", vmin=-2, vmax=2)
393
+ assert m.norm.vmin == pytest.approx(-2)
394
+ assert m.norm.vmax == pytest.approx(2)
395
+ assert m.norm(-0.5) == pytest.approx(0.375)
396
+ assert m.norm(0.5) == pytest.approx(0.625)
397
+
398
+
399
+ def test_tricontour_explicit_colors_match_levels():
400
+ """
401
+ Explicit triangular contour colors should map one-to-one with levels.
402
+ """
403
+ rng = np.random.default_rng(51423)
404
+ x = rng.random(40)
405
+ y = rng.random(40)
406
+ z = np.sin(3 * x) + np.cos(3 * y)
407
+ levels = [-1.0, 0.0, 1.0]
408
+ turbo = uplt.Colormap("turbo")
409
+ colors = turbo(Normalize(vmin=-2, vmax=2)(levels))
410
+ _, ax = uplt.subplots()
411
+ m = ax.tricontour(x, y, z, levels=levels, colors=colors, linewidths=1)
412
+ assert np.allclose(np.asarray(m.get_edgecolor()), colors)
413
+
414
+
294
415
  @pytest.mark.mpl_image_compare
295
416
  def test_level_restriction(rng):
296
417
  """
@@ -97,6 +97,37 @@ def test_inset_colorbar_frame_wraps_label(rng, orientation, labelloc):
97
97
  assert frame_bbox.y1 >= label_bbox.y1 - tol
98
98
 
99
99
 
100
+ def test_inset_colorbar_frame_wraps_label_with_refaspect(rng):
101
+ """
102
+ Inset colorbar frame should include the label when figure sizing is refaspect-driven.
103
+ """
104
+ from ultraplot.axes.base import _get_axis_for
105
+
106
+ fig, ax = uplt.subplots(refaspect=2)
107
+ data = rng.random((20, 30))
108
+ m = ax.pcolormesh(data, vmin=0, vmax=1)
109
+ cb = ax.colorbar(m, loc="ul", label="title", frameon=True)
110
+ fig.canvas.draw()
111
+
112
+ frame = cb.ax._inset_colorbar_frame
113
+ assert frame is not None
114
+
115
+ renderer = fig.canvas.get_renderer()
116
+ frame_bbox = frame.get_window_extent(renderer)
117
+ layout = cb.ax._inset_colorbar_layout
118
+ labelloc = cb.ax._inset_colorbar_labelloc
119
+ labelloc_layout = labelloc if isinstance(labelloc, str) else layout["ticklocation"]
120
+ label_axis = _get_axis_for(
121
+ labelloc_layout, layout["loc"], orientation=layout["orientation"], ax=cb
122
+ )
123
+ label_bbox = label_axis.label.get_window_extent(renderer)
124
+ tol = 1.0
125
+ assert frame_bbox.x0 <= label_bbox.x0 + tol
126
+ assert frame_bbox.x1 >= label_bbox.x1 - tol
127
+ assert frame_bbox.y0 <= label_bbox.y0 + tol
128
+ assert frame_bbox.y1 >= label_bbox.y1 - tol
129
+
130
+
100
131
  from itertools import product
101
132
 
102
133
 
@@ -126,3 +126,22 @@ def test_gridspec_slicing():
126
126
  # subset_mixed[4] -> Row 1, Col 0 -> Number 5 (since 4 cols per row)
127
127
  assert subset_mixed[0].number == 1
128
128
  assert subset_mixed[4].number == 5
129
+
130
+
131
+ def test_gridspec_spanning_slice_deduplicates_axes():
132
+ import numpy as np
133
+
134
+ fig, axs = uplt.subplots(np.array([[1, 1, 2], [3, 4, 5]]))
135
+
136
+ # The first two slots in the top row refer to the same spanning subplot.
137
+ ax = axs[0, :2]
138
+ assert isinstance(ax, uplt.axes.Axes)
139
+ assert ax is axs[0, 0]
140
+
141
+ data = np.array([[0.1, 0.2], [0.4, 0.5], [0.7, 0.8]])
142
+ ax.scatter(data[:, 0], data[:, 1], c="grey", label="data", legend=True)
143
+ fig.canvas.draw()
144
+
145
+ legend = ax.get_legend()
146
+ assert legend is not None
147
+ assert [t.get_text() for t in legend.texts] == ["data"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultraplot
3
- Version: 2.1.0
3
+ Version: 2.1.2
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>
@@ -1 +0,0 @@
1
- __version__ = '2.1.0'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes