ultraplot 0.99.3__py3-none-any.whl

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 (416) hide show
  1. ultraplot/__init__.py +115 -0
  2. ultraplot/__init__.py.rej +58 -0
  3. ultraplot/axes/__init__.py +42 -0
  4. ultraplot/axes/base.py +3240 -0
  5. ultraplot/axes/cartesian.py +1425 -0
  6. ultraplot/axes/geo.py +1675 -0
  7. ultraplot/axes/plot.py +4569 -0
  8. ultraplot/axes/polar.py +381 -0
  9. ultraplot/axes/shared.py +186 -0
  10. ultraplot/axes/three.py +34 -0
  11. ultraplot/cmaps/Algae.rgb +256 -0
  12. ultraplot/cmaps/Amp.rgb +256 -0
  13. ultraplot/cmaps/BR.rgb +256 -0
  14. ultraplot/cmaps/Balance.rgb +256 -0
  15. ultraplot/cmaps/Blues1_r.xml +17 -0
  16. ultraplot/cmaps/Blues2.xml +16 -0
  17. ultraplot/cmaps/Blues3.xml +25 -0
  18. ultraplot/cmaps/Blues4_r.xml +17 -0
  19. ultraplot/cmaps/Blues5.xml +16 -0
  20. ultraplot/cmaps/Blues6.xml +25 -0
  21. ultraplot/cmaps/Blues7.xml +16 -0
  22. ultraplot/cmaps/Blues8.xml +17 -0
  23. ultraplot/cmaps/Blues9.xml +1 -0
  24. ultraplot/cmaps/Boreal.json +53 -0
  25. ultraplot/cmaps/Browns1.xml +16 -0
  26. ultraplot/cmaps/Browns2.xml +26 -0
  27. ultraplot/cmaps/Browns3.xml +17 -0
  28. ultraplot/cmaps/Browns4.xml +17 -0
  29. ultraplot/cmaps/Browns5.xml +26 -0
  30. ultraplot/cmaps/Browns6.xml +17 -0
  31. ultraplot/cmaps/Browns7.xml +19 -0
  32. ultraplot/cmaps/Browns8.xml +11 -0
  33. ultraplot/cmaps/Browns9.xml +1 -0
  34. ultraplot/cmaps/ColdHot.rgb +229 -0
  35. ultraplot/cmaps/Crest.rgb +256 -0
  36. ultraplot/cmaps/Curl.rgb +512 -0
  37. ultraplot/cmaps/Deep.rgb +256 -0
  38. ultraplot/cmaps/Delta.rgb +512 -0
  39. ultraplot/cmaps/Dense.rgb +256 -0
  40. ultraplot/cmaps/Div.json +71 -0
  41. ultraplot/cmaps/DryWet.json +73 -0
  42. ultraplot/cmaps/Dusk.json +53 -0
  43. ultraplot/cmaps/Fire.json +53 -0
  44. ultraplot/cmaps/Flare.rgb +256 -0
  45. ultraplot/cmaps/Glacial.json +53 -0
  46. ultraplot/cmaps/Greens1_r.xml +26 -0
  47. ultraplot/cmaps/Greens2.xml +28 -0
  48. ultraplot/cmaps/Greens3_r.xml +28 -0
  49. ultraplot/cmaps/Greens4.xml +17 -0
  50. ultraplot/cmaps/Greens5.xml +16 -0
  51. ultraplot/cmaps/Greens6_r.xml +16 -0
  52. ultraplot/cmaps/Greens7.xml +16 -0
  53. ultraplot/cmaps/Greens8.xml +26 -0
  54. ultraplot/cmaps/Haline.rgb +256 -0
  55. ultraplot/cmaps/Ice.rgb +256 -0
  56. ultraplot/cmaps/IceFire.rgb +256 -0
  57. ultraplot/cmaps/Mako.rgb +256 -0
  58. ultraplot/cmaps/Marine.json +53 -0
  59. ultraplot/cmaps/Matter.rgb +256 -0
  60. ultraplot/cmaps/Mono.txt +256 -0
  61. ultraplot/cmaps/MonoCycle.txt +256 -0
  62. ultraplot/cmaps/NegPos.json +71 -0
  63. ultraplot/cmaps/Oranges1.xml +27 -0
  64. ultraplot/cmaps/Oranges2.xml +26 -0
  65. ultraplot/cmaps/Oranges3.xml +15 -0
  66. ultraplot/cmaps/Oranges4.xml +23 -0
  67. ultraplot/cmaps/Oxy.rgb +256 -0
  68. ultraplot/cmaps/Phase.rgb +256 -0
  69. ultraplot/cmaps/Purples1_r.xml +16 -0
  70. ultraplot/cmaps/Purples2.xml +17 -0
  71. ultraplot/cmaps/Purples3.xml +18 -0
  72. ultraplot/cmaps/Reds1.xml +26 -0
  73. ultraplot/cmaps/Reds2.xml +22 -0
  74. ultraplot/cmaps/Reds3.xml +23 -0
  75. ultraplot/cmaps/Reds4.xml +26 -0
  76. ultraplot/cmaps/Reds5.xml +17 -0
  77. ultraplot/cmaps/Rocket.rgb +256 -0
  78. ultraplot/cmaps/Solar.rgb +256 -0
  79. ultraplot/cmaps/Speed.rgb +256 -0
  80. ultraplot/cmaps/Stellar.json +53 -0
  81. ultraplot/cmaps/Sunrise.json +53 -0
  82. ultraplot/cmaps/Sunset.json +53 -0
  83. ultraplot/cmaps/Tempo.rgb +256 -0
  84. ultraplot/cmaps/Thermal.rgb +256 -0
  85. ultraplot/cmaps/Turbid.rgb +256 -0
  86. ultraplot/cmaps/Vivid.xml +11 -0
  87. ultraplot/cmaps/Vlag.rgb +256 -0
  88. ultraplot/cmaps/Yellows1.xml +17 -0
  89. ultraplot/cmaps/Yellows2.xml +17 -0
  90. ultraplot/cmaps/Yellows3.xml +17 -0
  91. ultraplot/cmaps/Yellows4.xml +17 -0
  92. ultraplot/cmaps/acton.txt +256 -0
  93. ultraplot/cmaps/bam.txt +256 -0
  94. ultraplot/cmaps/bamO.txt +256 -0
  95. ultraplot/cmaps/bamako.txt +256 -0
  96. ultraplot/cmaps/batlow.txt +256 -0
  97. ultraplot/cmaps/batlowK.txt +256 -0
  98. ultraplot/cmaps/batlowW.txt +256 -0
  99. ultraplot/cmaps/berlin.txt +256 -0
  100. ultraplot/cmaps/bilbao.txt +256 -0
  101. ultraplot/cmaps/broc.txt +256 -0
  102. ultraplot/cmaps/brocO.txt +256 -0
  103. ultraplot/cmaps/buda.txt +256 -0
  104. ultraplot/cmaps/bukavu.txt +256 -0
  105. ultraplot/cmaps/cork.txt +256 -0
  106. ultraplot/cmaps/corkO.txt +256 -0
  107. ultraplot/cmaps/davos.txt +256 -0
  108. ultraplot/cmaps/devon.txt +256 -0
  109. ultraplot/cmaps/fes.txt +256 -0
  110. ultraplot/cmaps/hawaii.txt +256 -0
  111. ultraplot/cmaps/imola.txt +256 -0
  112. ultraplot/cmaps/lajolla.txt +256 -0
  113. ultraplot/cmaps/lapaz.txt +256 -0
  114. ultraplot/cmaps/lisbon.txt +256 -0
  115. ultraplot/cmaps/nuuk.txt +256 -0
  116. ultraplot/cmaps/oleron.txt +256 -0
  117. ultraplot/cmaps/oslo.txt +256 -0
  118. ultraplot/cmaps/roma.txt +256 -0
  119. ultraplot/cmaps/romaO.txt +256 -0
  120. ultraplot/cmaps/tofino.txt +256 -0
  121. ultraplot/cmaps/tokyo.txt +256 -0
  122. ultraplot/cmaps/turku.txt +256 -0
  123. ultraplot/cmaps/vanimo.txt +256 -0
  124. ultraplot/cmaps/vik.txt +256 -0
  125. ultraplot/cmaps/vikO.txt +256 -0
  126. ultraplot/colors/opencolor.txt +132 -0
  127. ultraplot/colors/xkcd.txt +951 -0
  128. ultraplot/colors.py +3241 -0
  129. ultraplot/colors.py.rej +243 -0
  130. ultraplot/config.py +1809 -0
  131. ultraplot/constructor.py +1633 -0
  132. ultraplot/cycles/538.hex +2 -0
  133. ultraplot/cycles/FlatUI.hex +1 -0
  134. ultraplot/cycles/Qual1.rgb +7 -0
  135. ultraplot/cycles/Qual2.rgb +13 -0
  136. ultraplot/cycles/bmh.hex +2 -0
  137. ultraplot/cycles/classic.hex +2 -0
  138. ultraplot/cycles/colorblind.hex +2 -0
  139. ultraplot/cycles/colorblind10.hex +2 -0
  140. ultraplot/cycles/default.hex +2 -0
  141. ultraplot/cycles/ggplot.hex +1 -0
  142. ultraplot/cycles/seaborn.hex +2 -0
  143. ultraplot/cycles/tableau.hex +2 -0
  144. ultraplot/demos.py +1201 -0
  145. ultraplot/externals/__init__.py +5 -0
  146. ultraplot/externals/hsluv.py +330 -0
  147. ultraplot/figure.py +2102 -0
  148. ultraplot/fonts/FiraMath-Bold.ttf +0 -0
  149. ultraplot/fonts/FiraMath-ExtraLight.ttf +0 -0
  150. ultraplot/fonts/FiraMath-Heavy.ttf +0 -0
  151. ultraplot/fonts/FiraMath-Light.ttf +0 -0
  152. ultraplot/fonts/FiraMath-Medium.ttf +0 -0
  153. ultraplot/fonts/FiraMath-Regular.ttf +0 -0
  154. ultraplot/fonts/FiraMath-SemiBold.ttf +0 -0
  155. ultraplot/fonts/FiraMath-UltraLight.ttf +0 -0
  156. ultraplot/fonts/FiraSans-Black.ttf +0 -0
  157. ultraplot/fonts/FiraSans-BlackItalic.ttf +0 -0
  158. ultraplot/fonts/FiraSans-Bold.ttf +0 -0
  159. ultraplot/fonts/FiraSans-BoldItalic.ttf +0 -0
  160. ultraplot/fonts/FiraSans-ExtraBold.ttf +0 -0
  161. ultraplot/fonts/FiraSans-ExtraBoldItalic.ttf +0 -0
  162. ultraplot/fonts/FiraSans-ExtraLight.ttf +0 -0
  163. ultraplot/fonts/FiraSans-ExtraLightItalic.ttf +0 -0
  164. ultraplot/fonts/FiraSans-Italic.ttf +0 -0
  165. ultraplot/fonts/FiraSans-Light.ttf +0 -0
  166. ultraplot/fonts/FiraSans-LightItalic.ttf +0 -0
  167. ultraplot/fonts/FiraSans-Medium.ttf +0 -0
  168. ultraplot/fonts/FiraSans-MediumItalic.ttf +0 -0
  169. ultraplot/fonts/FiraSans-Regular.ttf +0 -0
  170. ultraplot/fonts/FiraSans-SemiBold.ttf +0 -0
  171. ultraplot/fonts/FiraSans-SemiBoldItalic.ttf +0 -0
  172. ultraplot/fonts/LICENSE_FIRAMATH.txt +92 -0
  173. ultraplot/fonts/LICENSE_FIRASANS.txt +97 -0
  174. ultraplot/fonts/LICENSE_NOTOSANS.txt +202 -0
  175. ultraplot/fonts/LICENSE_NOTOSERIF.txt +93 -0
  176. ultraplot/fonts/LICENSE_OPENSANS.txt +202 -0
  177. ultraplot/fonts/LICENSE_ROBOTO.txt +202 -0
  178. ultraplot/fonts/LICENSE_SOURCESANS.txt +93 -0
  179. ultraplot/fonts/LICENSE_SOURCESERIF.txt +93 -0
  180. ultraplot/fonts/LICENSE_TEXGYRE.txt +29 -0
  181. ultraplot/fonts/LICENSE_UBUNTU.txt +96 -0
  182. ultraplot/fonts/NotoSans-Bold.ttf +0 -0
  183. ultraplot/fonts/NotoSans-BoldItalic.ttf +0 -0
  184. ultraplot/fonts/NotoSans-Italic.ttf +0 -0
  185. ultraplot/fonts/NotoSans-Regular.ttf +0 -0
  186. ultraplot/fonts/NotoSerif-Bold.ttf +0 -0
  187. ultraplot/fonts/NotoSerif-BoldItalic.ttf +0 -0
  188. ultraplot/fonts/NotoSerif-Italic.ttf +0 -0
  189. ultraplot/fonts/NotoSerif-Regular.ttf +0 -0
  190. ultraplot/fonts/OpenSans-Bold.ttf +0 -0
  191. ultraplot/fonts/OpenSans-BoldItalic.ttf +0 -0
  192. ultraplot/fonts/OpenSans-Italic.ttf +0 -0
  193. ultraplot/fonts/OpenSans-Regular.ttf +0 -0
  194. ultraplot/fonts/OpenSans-Semibold.ttf +0 -0
  195. ultraplot/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  196. ultraplot/fonts/Roboto-Black.ttf +0 -0
  197. ultraplot/fonts/Roboto-BlackItalic.ttf +0 -0
  198. ultraplot/fonts/Roboto-Bold.ttf +0 -0
  199. ultraplot/fonts/Roboto-BoldItalic.ttf +0 -0
  200. ultraplot/fonts/Roboto-Italic.ttf +0 -0
  201. ultraplot/fonts/Roboto-Light.ttf +0 -0
  202. ultraplot/fonts/Roboto-LightItalic.ttf +0 -0
  203. ultraplot/fonts/Roboto-Medium.ttf +0 -0
  204. ultraplot/fonts/Roboto-MediumItalic.ttf +0 -0
  205. ultraplot/fonts/Roboto-Regular.ttf +0 -0
  206. ultraplot/fonts/SourceSansPro-Black.ttf +0 -0
  207. ultraplot/fonts/SourceSansPro-BlackItalic.ttf +0 -0
  208. ultraplot/fonts/SourceSansPro-Bold.ttf +0 -0
  209. ultraplot/fonts/SourceSansPro-BoldItalic.ttf +0 -0
  210. ultraplot/fonts/SourceSansPro-ExtraLight.ttf +0 -0
  211. ultraplot/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
  212. ultraplot/fonts/SourceSansPro-Italic.ttf +0 -0
  213. ultraplot/fonts/SourceSansPro-Light.ttf +0 -0
  214. ultraplot/fonts/SourceSansPro-LightItalic.ttf +0 -0
  215. ultraplot/fonts/SourceSansPro-Regular.ttf +0 -0
  216. ultraplot/fonts/SourceSansPro-SemiBold.ttf +0 -0
  217. ultraplot/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
  218. ultraplot/fonts/SourceSerifPro-Black.ttf +0 -0
  219. ultraplot/fonts/SourceSerifPro-BlackItalic.ttf +0 -0
  220. ultraplot/fonts/SourceSerifPro-Bold.ttf +0 -0
  221. ultraplot/fonts/SourceSerifPro-BoldItalic.ttf +0 -0
  222. ultraplot/fonts/SourceSerifPro-ExtraLight.ttf +0 -0
  223. ultraplot/fonts/SourceSerifPro-ExtraLightItalic.ttf +0 -0
  224. ultraplot/fonts/SourceSerifPro-Italic.ttf +0 -0
  225. ultraplot/fonts/SourceSerifPro-Light.ttf +0 -0
  226. ultraplot/fonts/SourceSerifPro-LightItalic.ttf +0 -0
  227. ultraplot/fonts/SourceSerifPro-Regular.ttf +0 -0
  228. ultraplot/fonts/SourceSerifPro-SemiBold.ttf +0 -0
  229. ultraplot/fonts/SourceSerifPro-SemiBoldItalic.ttf +0 -0
  230. ultraplot/fonts/Ubuntu-Bold.ttf +0 -0
  231. ultraplot/fonts/Ubuntu-BoldItalic.ttf +0 -0
  232. ultraplot/fonts/Ubuntu-Italic.ttf +0 -0
  233. ultraplot/fonts/Ubuntu-Light.ttf +0 -0
  234. ultraplot/fonts/Ubuntu-LightItalic.ttf +0 -0
  235. ultraplot/fonts/Ubuntu-Medium.ttf +0 -0
  236. ultraplot/fonts/Ubuntu-MediumItalic.ttf +0 -0
  237. ultraplot/fonts/Ubuntu-Regular.ttf +0 -0
  238. ultraplot/fonts/texgyreadventor-bold.ttf +0 -0
  239. ultraplot/fonts/texgyreadventor-bolditalic.ttf +0 -0
  240. ultraplot/fonts/texgyreadventor-italic.ttf +0 -0
  241. ultraplot/fonts/texgyreadventor-regular.ttf +0 -0
  242. ultraplot/fonts/texgyrebonum-bold.ttf +0 -0
  243. ultraplot/fonts/texgyrebonum-bolditalic.ttf +0 -0
  244. ultraplot/fonts/texgyrebonum-italic.ttf +0 -0
  245. ultraplot/fonts/texgyrebonum-regular.ttf +0 -0
  246. ultraplot/fonts/texgyrechorus-mediumitalic.ttf +0 -0
  247. ultraplot/fonts/texgyrecursor-bold.ttf +0 -0
  248. ultraplot/fonts/texgyrecursor-bolditalic.ttf +0 -0
  249. ultraplot/fonts/texgyrecursor-italic.ttf +0 -0
  250. ultraplot/fonts/texgyrecursor-regular.ttf +0 -0
  251. ultraplot/fonts/texgyreheros-bold.ttf +0 -0
  252. ultraplot/fonts/texgyreheros-bolditalic.ttf +0 -0
  253. ultraplot/fonts/texgyreheros-italic.ttf +0 -0
  254. ultraplot/fonts/texgyreheros-regular.ttf +0 -0
  255. ultraplot/fonts/texgyrepagella-bold.ttf +0 -0
  256. ultraplot/fonts/texgyrepagella-bolditalic.ttf +0 -0
  257. ultraplot/fonts/texgyrepagella-italic.ttf +0 -0
  258. ultraplot/fonts/texgyrepagella-regular.ttf +0 -0
  259. ultraplot/fonts/texgyreschola-bold.ttf +0 -0
  260. ultraplot/fonts/texgyreschola-bolditalic.ttf +0 -0
  261. ultraplot/fonts/texgyreschola-italic.ttf +0 -0
  262. ultraplot/fonts/texgyreschola-regular.ttf +0 -0
  263. ultraplot/fonts/texgyretermes-bold.ttf +0 -0
  264. ultraplot/fonts/texgyretermes-bolditalic.ttf +0 -0
  265. ultraplot/fonts/texgyretermes-italic.ttf +0 -0
  266. ultraplot/fonts/texgyretermes-regular.ttf +0 -0
  267. ultraplot/gridspec.py +1698 -0
  268. ultraplot/internals/__init__.py +529 -0
  269. ultraplot/internals/benchmarks.py +26 -0
  270. ultraplot/internals/context.py +44 -0
  271. ultraplot/internals/docstring.py +139 -0
  272. ultraplot/internals/fonts.py +75 -0
  273. ultraplot/internals/guides.py +167 -0
  274. ultraplot/internals/inputs.py +862 -0
  275. ultraplot/internals/labels.py +85 -0
  276. ultraplot/internals/rcsetup.py +1933 -0
  277. ultraplot/internals/versions.py +61 -0
  278. ultraplot/internals/warnings.py +122 -0
  279. ultraplot/proj.py +325 -0
  280. ultraplot/scale.py +966 -0
  281. ultraplot/tests/__init__.py +28 -0
  282. ultraplot/tests/baseline/test_align_labels.png +0 -0
  283. ultraplot/tests/baseline/test_aligned_outer_guides.png +0 -0
  284. ultraplot/tests/baseline/test_aspect_ratios.png +0 -0
  285. ultraplot/tests/baseline/test_auto_diverging1.png +0 -0
  286. ultraplot/tests/baseline/test_auto_legend.png +0 -0
  287. ultraplot/tests/baseline/test_auto_reverse.png +0 -0
  288. ultraplot/tests/baseline/test_autodiverging3.png +0 -0
  289. ultraplot/tests/baseline/test_autodiverging4.png +0 -0
  290. ultraplot/tests/baseline/test_autodiverging5.png +0 -0
  291. ultraplot/tests/baseline/test_axes_colors.png +0 -0
  292. ultraplot/tests/baseline/test_bar_vectors.png +0 -0
  293. ultraplot/tests/baseline/test_bar_width.png +0 -0
  294. ultraplot/tests/baseline/test_both_ticklabels.png +0 -0
  295. ultraplot/tests/baseline/test_bounds_ticks.png +0 -0
  296. ultraplot/tests/baseline/test_boxplot_colors.png +0 -0
  297. ultraplot/tests/baseline/test_boxplot_vectors.png +0 -0
  298. ultraplot/tests/baseline/test_cartopy_contours.png +0 -0
  299. ultraplot/tests/baseline/test_cartopy_labels.png +0 -0
  300. ultraplot/tests/baseline/test_cartopy_manual.png +0 -0
  301. ultraplot/tests/baseline/test_centered_legends.png +0 -0
  302. ultraplot/tests/baseline/test_cmap_cycles.png +0 -0
  303. ultraplot/tests/baseline/test_colorbar.png +0 -0
  304. ultraplot/tests/baseline/test_colorbar_ticks.png +0 -0
  305. ultraplot/tests/baseline/test_colormap_mode.png +0 -0
  306. ultraplot/tests/baseline/test_column_iteration.png +0 -0
  307. ultraplot/tests/baseline/test_complex_ticks.png +0 -0
  308. ultraplot/tests/baseline/test_contour_labels.png +0 -0
  309. ultraplot/tests/baseline/test_contour_legend_with_label.png +0 -0
  310. ultraplot/tests/baseline/test_contour_legend_without_label.png +0 -0
  311. ultraplot/tests/baseline/test_contour_negative.png +0 -0
  312. ultraplot/tests/baseline/test_contour_single.png +0 -0
  313. ultraplot/tests/baseline/test_cutoff_ticks.png +0 -0
  314. ultraplot/tests/baseline/test_data_keyword.png +0 -0
  315. ultraplot/tests/baseline/test_discrete_ticks.png +0 -0
  316. ultraplot/tests/baseline/test_discrete_vs_fixed.png +0 -0
  317. ultraplot/tests/baseline/test_drawing_in_projection_with_globe.png +0 -0
  318. ultraplot/tests/baseline/test_drawing_in_projection_without_globe.png +0 -0
  319. ultraplot/tests/baseline/test_edge_fix.png +0 -0
  320. ultraplot/tests/baseline/test_flow_functions.png +0 -0
  321. ultraplot/tests/baseline/test_font_adjustments.png +0 -0
  322. ultraplot/tests/baseline/test_geographic_multiple_projections.png +0 -0
  323. ultraplot/tests/baseline/test_geographic_single_projection.png +0 -0
  324. ultraplot/tests/baseline/test_gray_adjustment.png +0 -0
  325. ultraplot/tests/baseline/test_histogram_legend.png +0 -0
  326. ultraplot/tests/baseline/test_histogram_types.png +0 -0
  327. ultraplot/tests/baseline/test_ignore_message.png +0 -0
  328. ultraplot/tests/baseline/test_inbounds_data.png +0 -0
  329. ultraplot/tests/baseline/test_init_format.png +0 -0
  330. ultraplot/tests/baseline/test_inner_title_zorder.png +0 -0
  331. ultraplot/tests/baseline/test_inset_basic.png +0 -0
  332. ultraplot/tests/baseline/test_inset_colorbars.png +0 -0
  333. ultraplot/tests/baseline/test_inset_colors_1.png +0 -0
  334. ultraplot/tests/baseline/test_inset_colors_2.png +0 -0
  335. ultraplot/tests/baseline/test_inset_zoom_update.png +0 -0
  336. ultraplot/tests/baseline/test_invalid_dist.png +0 -0
  337. ultraplot/tests/baseline/test_invalid_plot.png +0 -0
  338. ultraplot/tests/baseline/test_keep_guide_labels.png +0 -0
  339. ultraplot/tests/baseline/test_label_settings.png +0 -0
  340. ultraplot/tests/baseline/test_level_restriction.png +0 -0
  341. ultraplot/tests/baseline/test_levels_with_vmin_vmax.png +0 -0
  342. ultraplot/tests/baseline/test_locale_formatting.png +0 -0
  343. ultraplot/tests/baseline/test_locale_formatting_en_US.UTF-8.png +0 -0
  344. ultraplot/tests/baseline/test_manual_labels.png +0 -0
  345. ultraplot/tests/baseline/test_multi_formatting.png +0 -0
  346. ultraplot/tests/baseline/test_multiple_calls.png +0 -0
  347. ultraplot/tests/baseline/test_on_the_fly_mappable.png +0 -0
  348. ultraplot/tests/baseline/test_outer_align.png +0 -0
  349. ultraplot/tests/baseline/test_panel_dist.png +0 -0
  350. ultraplot/tests/baseline/test_panels_suplabels_three_hor_panels.png +0 -0
  351. ultraplot/tests/baseline/test_panels_with_sharing.png +0 -0
  352. ultraplot/tests/baseline/test_panels_without_sharing_1.png +0 -0
  353. ultraplot/tests/baseline/test_panels_without_sharing_2.png +0 -0
  354. ultraplot/tests/baseline/test_parametric_colors.png +0 -0
  355. ultraplot/tests/baseline/test_parametric_labels.png +0 -0
  356. ultraplot/tests/baseline/test_patch_format.png +0 -0
  357. ultraplot/tests/baseline/test_pie_charts.png +0 -0
  358. ultraplot/tests/baseline/test_pint_quantities.png +0 -0
  359. ultraplot/tests/baseline/test_polar_projections.png +0 -0
  360. ultraplot/tests/baseline/test_projection_dicts.png +0 -0
  361. ultraplot/tests/baseline/test_qualitative_colormaps_1.png +0 -0
  362. ultraplot/tests/baseline/test_qualitative_colormaps_2.png +0 -0
  363. ultraplot/tests/baseline/test_reversed_levels.png +0 -0
  364. ultraplot/tests/baseline/test_scatter_alpha.png +0 -0
  365. ultraplot/tests/baseline/test_scatter_args.png +0 -0
  366. ultraplot/tests/baseline/test_scatter_cycle.png +0 -0
  367. ultraplot/tests/baseline/test_scatter_inbounds.png +0 -0
  368. ultraplot/tests/baseline/test_scatter_sizes.png +0 -0
  369. ultraplot/tests/baseline/test_seaborn_heatmap.png +0 -0
  370. ultraplot/tests/baseline/test_seaborn_hist.png +0 -0
  371. ultraplot/tests/baseline/test_seaborn_relational.png +0 -0
  372. ultraplot/tests/baseline/test_seaborn_swarmplot.png +0 -0
  373. ultraplot/tests/baseline/test_segmented_norm.png +0 -0
  374. ultraplot/tests/baseline/test_segmented_norm_ticks.png +0 -0
  375. ultraplot/tests/baseline/test_share_all_basic.png +0 -0
  376. ultraplot/tests/baseline/test_singleton_legend.png +0 -0
  377. ultraplot/tests/baseline/test_span_labels.png +0 -0
  378. ultraplot/tests/baseline/test_spine_offset.png +0 -0
  379. ultraplot/tests/baseline/test_spine_side.png +0 -0
  380. ultraplot/tests/baseline/test_standardized_input.png +0 -0
  381. ultraplot/tests/baseline/test_statistical_boxplot.png +0 -0
  382. ultraplot/tests/baseline/test_three_axes.png +0 -0
  383. ultraplot/tests/baseline/test_tick_direction.png +0 -0
  384. ultraplot/tests/baseline/test_tick_labels.png +0 -0
  385. ultraplot/tests/baseline/test_tick_length.png +0 -0
  386. ultraplot/tests/baseline/test_tick_width.png +0 -0
  387. ultraplot/tests/baseline/test_title_deflection.png +0 -0
  388. ultraplot/tests/baseline/test_triangular_functions.png +0 -0
  389. ultraplot/tests/baseline/test_tuple_handles.png +0 -0
  390. ultraplot/tests/baseline/test_twin_axes_1.png +0 -0
  391. ultraplot/tests/baseline/test_twin_axes_2.png +0 -0
  392. ultraplot/tests/baseline/test_twin_axes_3.png +0 -0
  393. ultraplot/tests/baseline/test_uneven_levels.png +0 -0
  394. ultraplot/tests/test_1dplots.py +373 -0
  395. ultraplot/tests/test_2dplots.py +354 -0
  396. ultraplot/tests/test_axes.py +179 -0
  397. ultraplot/tests/test_colorbar.py +253 -0
  398. ultraplot/tests/test_docs.py +78 -0
  399. ultraplot/tests/test_format.py +340 -0
  400. ultraplot/tests/test_geographic.py +116 -0
  401. ultraplot/tests/test_imshow.py +110 -0
  402. ultraplot/tests/test_inset.py +28 -0
  403. ultraplot/tests/test_integration.py +149 -0
  404. ultraplot/tests/test_legend.py +181 -0
  405. ultraplot/tests/test_projections.py +138 -0
  406. ultraplot/tests/test_statistical_plotting.py +77 -0
  407. ultraplot/tests/test_subplots.py +174 -0
  408. ultraplot/ticker.py +879 -0
  409. ultraplot/ui.py +233 -0
  410. ultraplot/utils.py +912 -0
  411. ultraplot-0.99.3.dist-info/LICENSE.txt +427 -0
  412. ultraplot-0.99.3.dist-info/METADATA +88 -0
  413. ultraplot-0.99.3.dist-info/RECORD +416 -0
  414. ultraplot-0.99.3.dist-info/WHEEL +5 -0
  415. ultraplot-0.99.3.dist-info/entry_points.txt +2 -0
  416. ultraplot-0.99.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,116 @@
1
+ import ultraplot as plt, numpy as np
2
+ import pytest
3
+
4
+
5
+ @pytest.mark.mpl_image_compare
6
+ def test_geographic_single_projection():
7
+ fig = plt.figure(refwidth=3)
8
+ axs = fig.subplots(nrows=2, proj="robin", proj_kw={"lon_0": 180})
9
+ # proj = pplt.Proj('robin', lon_0=180)
10
+ # axs = pplt.subplots(nrows=2, proj=proj) # equivalent to above
11
+ axs.format(
12
+ suptitle="Figure with single projection",
13
+ land=True,
14
+ latlines=30,
15
+ lonlines=60,
16
+ )
17
+ return fig
18
+
19
+
20
+ @pytest.mark.mpl_image_compare
21
+ def test_geographic_multiple_projections():
22
+ fig = plt.figure()
23
+ # Add projections
24
+ gs = plt.GridSpec(ncols=2, nrows=3, hratios=(1, 1, 1.4))
25
+ for i, proj in enumerate(("cyl", "hammer", "npstere")):
26
+ ax1 = fig.subplot(gs[i, 0], proj=proj, basemap=True) # basemap
27
+ ax2 = fig.subplot(gs[i, 1], proj=proj) # cartopy
28
+
29
+ # Format projections
30
+ fig.format(
31
+ land=True,
32
+ suptitle="Figure with several projections",
33
+ toplabels=("Basemap projections", "Cartopy projections"),
34
+ toplabelweight="normal",
35
+ latlines=30,
36
+ lonlines=60,
37
+ lonlabels="b",
38
+ latlabels="r", # or lonlabels=True, labels=True, etc.
39
+ )
40
+ fig.subplotgrid[-2:].format(
41
+ latlines=20, lonlines=30
42
+ ) # dense gridlines for polar plots
43
+ plt.rc.reset()
44
+ return fig
45
+
46
+
47
+ @pytest.mark.mpl_image_compare
48
+ def test_drawing_in_projection_without_globe():
49
+ # Fake data with unusual longitude seam location and without coverage over poles
50
+ offset = -40
51
+ lon = plt.arange(offset, 360 + offset - 1, 60)
52
+ lat = plt.arange(-60, 60 + 1, 30)
53
+ state = np.random.RandomState(51423)
54
+ data = state.rand(len(lat), len(lon))
55
+
56
+ globe = False
57
+ string = "with" if globe else "without"
58
+ gs = plt.GridSpec(nrows=2, ncols=2)
59
+ fig = plt.figure(refwidth=2.5)
60
+ for i, ss in enumerate(gs):
61
+ ax = fig.subplot(ss, proj="kav7", basemap=(i % 2))
62
+ cmap = ("sunset", "sunrise")[i % 2]
63
+ if i > 1:
64
+ ax.pcolor(lon, lat, data, cmap=cmap, globe=globe, extend="both")
65
+ else:
66
+ m = ax.contourf(lon, lat, data, cmap=cmap, globe=globe, extend="both")
67
+ fig.colorbar(m, loc="b", span=i + 1, label="values", extendsize="1.7em")
68
+ fig.format(
69
+ suptitle=f"Geophysical data {string} global coverage",
70
+ toplabels=("Cartopy example", "Basemap example"),
71
+ leftlabels=("Filled contours", "Grid boxes"),
72
+ toplabelweight="normal",
73
+ leftlabelweight="normal",
74
+ coast=True,
75
+ lonlines=90,
76
+ abc="A.",
77
+ abcloc="ul",
78
+ abcborder=False,
79
+ )
80
+ return fig
81
+
82
+
83
+ @pytest.mark.mpl_image_compare
84
+ def test_drawing_in_projection_with_globe():
85
+ # Fake data with unusual longitude seam location and without coverage over poles
86
+ offset = -40
87
+ lon = plt.arange(offset, 360 + offset - 1, 60)
88
+ lat = plt.arange(-60, 60 + 1, 30)
89
+ state = np.random.RandomState(51423)
90
+ data = state.rand(len(lat), len(lon))
91
+
92
+ globe = True
93
+ string = "with" if globe else "without"
94
+ gs = plt.GridSpec(nrows=2, ncols=2)
95
+ fig = plt.figure(refwidth=2.5)
96
+ for i, ss in enumerate(gs):
97
+ ax = fig.subplot(ss, proj="kav7", basemap=(i % 2))
98
+ cmap = ("sunset", "sunrise")[i % 2]
99
+ if i > 1:
100
+ ax.pcolor(lon, lat, data, cmap=cmap, globe=globe, extend="both")
101
+ else:
102
+ m = ax.contourf(lon, lat, data, cmap=cmap, globe=globe, extend="both")
103
+ fig.colorbar(m, loc="b", span=i + 1, label="values", extendsize="1.7em")
104
+ fig.format(
105
+ suptitle=f"Geophysical data {string} global coverage",
106
+ toplabels=("Cartopy example", "Basemap example"),
107
+ leftlabels=("Filled contours", "Grid boxes"),
108
+ toplabelweight="normal",
109
+ leftlabelweight="normal",
110
+ coast=True,
111
+ lonlines=90,
112
+ abc="A.",
113
+ abcloc="ul",
114
+ abcborder=False,
115
+ )
116
+ return fig
@@ -0,0 +1,110 @@
1
+ import pytest
2
+
3
+ import ultraplot as plt, numpy as np
4
+ from matplotlib.testing import setup
5
+
6
+
7
+ @pytest.fixture()
8
+ def setup_mpl():
9
+ setup()
10
+ plt.clf()
11
+
12
+
13
+ @pytest.mark.mpl_image_compare
14
+ def test_standardized_input():
15
+ # Sample data
16
+ state = np.random.RandomState(51423)
17
+ x = y = np.array([-10, -5, 0, 5, 10])
18
+ xedges = plt.edges(x)
19
+ yedges = plt.edges(y)
20
+ data = state.rand(y.size, x.size) # "center" coordinates
21
+ lim = (np.min(xedges), np.max(xedges))
22
+
23
+ with plt.rc.context({"cmap": "Grays", "cmap.levels": 21}):
24
+ # Figure
25
+ fig = plt.figure(refwidth=2.3, share=False)
26
+ axs = fig.subplots(ncols=2, nrows=2)
27
+ axs.format(
28
+ xlabel="xlabel",
29
+ ylabel="ylabel",
30
+ xlim=lim,
31
+ ylim=lim,
32
+ xlocator=5,
33
+ ylocator=5,
34
+ suptitle="Standardized input demonstration",
35
+ toplabels=("Coordinate centers", "Coordinate edges"),
36
+ )
37
+
38
+ # Plot using both centers and edges as coordinates
39
+ axs[0].pcolormesh(x, y, data)
40
+ axs[1].pcolormesh(xedges, yedges, data)
41
+ axs[2].contourf(x, y, data)
42
+ axs[3].contourf(xedges, yedges, data)
43
+ fig.show()
44
+ return fig
45
+
46
+
47
+ @pytest.mark.mpl_image_compare
48
+ def test_inbounds_data():
49
+ # Sample data
50
+ cmap = "turku_r"
51
+ state = np.random.RandomState(51423)
52
+ N = 80
53
+ x = y = np.arange(N + 1)
54
+ data = 10 + (state.normal(0, 3, size=(N, N))).cumsum(axis=0).cumsum(axis=1)
55
+ xlim = ylim = (0, 25)
56
+
57
+ # Plot the data
58
+ fig, axs = plt.subplots(
59
+ [[0, 1, 1, 0], [2, 2, 3, 3]],
60
+ wratios=(1.3, 1, 1, 1.3),
61
+ span=False,
62
+ refwidth=2.2,
63
+ )
64
+ axs[0].fill_between(
65
+ xlim,
66
+ *ylim,
67
+ zorder=3,
68
+ edgecolor="red",
69
+ facecolor=plt.set_alpha("red", 0.2),
70
+ )
71
+ for i, ax in enumerate(axs):
72
+ inbounds = i == 1
73
+ title = f"Restricted lims inbounds={inbounds}"
74
+ title += " (default)" if inbounds else ""
75
+ ax.format(
76
+ xlim=(None if i == 0 else xlim),
77
+ ylim=(None if i == 0 else ylim),
78
+ title=("Default axis limits" if i == 0 else title),
79
+ )
80
+ ax.pcolor(x, y, data, cmap=cmap, inbounds=inbounds)
81
+ fig.format(
82
+ xlabel="xlabel",
83
+ ylabel="ylabel",
84
+ suptitle="Default vmin/vmax restricted to in-bounds data",
85
+ )
86
+ fig.show()
87
+ return fig
88
+
89
+
90
+ @pytest.mark.mpl_image_compare
91
+ def test_colorbar():
92
+ # Sample data
93
+ state = np.random.RandomState(51423)
94
+ data = 10 + state.normal(0, 1, size=(33, 33)).cumsum(axis=0).cumsum(axis=1)
95
+
96
+ # Figure
97
+ fig, axs = plt.subplots([[1, 1, 2, 2], [0, 3, 3, 0]], ref=3, refwidth=2.3)
98
+ axs.format(yformatter="none", suptitle="Discrete vs. smooth colormap levels")
99
+
100
+ # Pcolor
101
+ axs[0].pcolor(data, cmap="viridis", colorbar="l")
102
+ axs[0].set_title("Pcolor plot\ndiscrete=True (default)")
103
+ axs[1].pcolor(data, discrete=False, cmap="viridis", colorbar="r")
104
+ axs[1].set_title("Pcolor plot\ndiscrete=False")
105
+
106
+ # Imshow
107
+ m = axs[2].imshow(data, cmap="oslo", colorbar="b")
108
+ axs[2].format(title="Imshow plot\ndiscrete=False (default)", yformatter="auto")
109
+ fig.show()
110
+ return fig
@@ -0,0 +1,28 @@
1
+ import ultraplot as pplt, numpy as np, pytest
2
+
3
+
4
+ @pytest.mark.mpl_image_compare
5
+ def test_inset_basic():
6
+ # Demonstrate that complex arrangements preserve
7
+ # spacing, aspect ratios, and axis sharing
8
+ gs = pplt.GridSpec(nrows=2, ncols=2)
9
+ fig = pplt.figure(refwidth=1.5, share=False)
10
+ for ss, side in zip(gs, "tlbr"):
11
+ ax = fig.add_subplot(ss)
12
+ px = ax.panel_axes(side, width="3em")
13
+ fig.format(
14
+ xlim=(0, 1),
15
+ ylim=(0, 1),
16
+ xlabel="xlabel",
17
+ ylabel="ylabel",
18
+ xticks=0.2,
19
+ yticks=0.2,
20
+ title="Title",
21
+ suptitle="Complex arrangement of panels",
22
+ toplabels=("Column 1", "Column 2"),
23
+ abc=True,
24
+ abcloc="ul",
25
+ titleloc="uc",
26
+ titleabove=False,
27
+ )
28
+ return fig
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test xarray, pandas, pint, seaborn integration.
4
+ """
5
+ import numpy as np, pandas as pd, seaborn as sns
6
+ import xarray as xr
7
+ import ultraplot as pplt, pytest
8
+ import pint
9
+
10
+ state = np.random.RandomState(51423)
11
+
12
+
13
+ @pytest.mark.mpl_image_compare
14
+ def test_pint_quantities():
15
+ """
16
+ Ensure auto-formatting and column iteration both work.
17
+ """
18
+ pplt.rc.unitformat = "~H"
19
+ ureg = pint.UnitRegistry()
20
+ fig, ax = pplt.subplots()
21
+ ax.plot(
22
+ np.arange(10),
23
+ state.rand(10) * ureg.km,
24
+ "C0",
25
+ np.arange(10),
26
+ state.rand(10) * ureg.m * 1e2,
27
+ "C1",
28
+ )
29
+ return fig
30
+
31
+
32
+ @pytest.mark.mpl_image_compare
33
+ def test_data_keyword():
34
+ """
35
+ Make sure `data` keywords work properly.
36
+ """
37
+ N = 10
38
+ M = 20
39
+ ds = xr.Dataset(
40
+ {"z": (("x", "y"), state.rand(N, M))},
41
+ coords={
42
+ "x": ("x", np.arange(N) * 10, {"long_name": "longitude"}),
43
+ "y": ("y", np.arange(M) * 5, {"long_name": "latitude"}),
44
+ },
45
+ )
46
+ fig, ax = pplt.subplots()
47
+ # ax.pcolor('z', data=ds, order='F')
48
+ ax.pcolor(z="z", data=ds, transpose=True)
49
+ ax.format(xformatter="deglat", yformatter="deglon")
50
+ return fig
51
+
52
+
53
+ @pytest.mark.mpl_image_compare
54
+ def test_keep_guide_labels():
55
+ """
56
+ Preserve metadata when passing mappables and handles to colorbar and
57
+ legend subsequently.
58
+ """
59
+ fig, ax = pplt.subplots()
60
+ df = pd.DataFrame(state.rand(5, 5))
61
+ df.name = "variable"
62
+ m = ax.pcolor(df)
63
+ ax.colorbar(m)
64
+
65
+ fig, ax = pplt.subplots()
66
+ for k in ("foo", "bar", "baz"):
67
+ s = pd.Series(state.rand(5), index=list("abcde"), name=k)
68
+ ax.plot(
69
+ s,
70
+ legend="ul",
71
+ legend_kw={
72
+ "lw": 5,
73
+ "ew": 2,
74
+ "ec": "r",
75
+ "fc": "w",
76
+ "handle_kw": {"marker": "d"},
77
+ },
78
+ )
79
+ return fig
80
+
81
+
82
+ @pytest.mark.mpl_image_compare
83
+ def test_seaborn_swarmplot():
84
+ """
85
+ Test seaborn swarm plots.
86
+ """
87
+ tips = sns.load_dataset("tips")
88
+ fig = pplt.figure(refwidth=3)
89
+ ax = fig.subplot()
90
+ sns.swarmplot(ax=ax, x="day", y="total_bill", data=tips, palette="cubehelix")
91
+ # fig, ax = pplt.subplots()
92
+ # sns.swarmplot(y=state.normal(size=100), ax=ax)
93
+ return fig
94
+
95
+
96
+ @pytest.mark.mpl_image_compare
97
+ def test_seaborn_hist():
98
+ """
99
+ Test seaborn histograms.
100
+ """
101
+ fig, axs = pplt.subplots(ncols=2, nrows=2)
102
+ sns.histplot(state.normal(size=100), ax=axs[0])
103
+ sns.kdeplot(x=state.rand(100), y=state.rand(100), ax=axs[1])
104
+ penguins = sns.load_dataset("penguins")
105
+ sns.histplot(
106
+ data=penguins, x="flipper_length_mm", hue="species", multiple="stack", ax=axs[2]
107
+ )
108
+ sns.kdeplot(
109
+ data=penguins, x="flipper_length_mm", hue="species", multiple="stack", ax=axs[3]
110
+ )
111
+ return fig
112
+
113
+
114
+ @pytest.mark.mpl_image_compare
115
+ def test_seaborn_relational():
116
+ """
117
+ Test scatter plots. Disabling seaborn detection creates mismatch between marker
118
+ sizes and legend.
119
+ """
120
+ fig = pplt.figure()
121
+ ax = fig.subplot()
122
+ sns.set_theme(style="white")
123
+ # Load the example mpg dataset
124
+ mpg = sns.load_dataset("mpg")
125
+ # Plot miles per gallon against horsepower with other semantics
126
+ sns.scatterplot(
127
+ x="horsepower",
128
+ y="mpg",
129
+ hue="origin",
130
+ size="weight",
131
+ sizes=(40, 400),
132
+ alpha=0.5,
133
+ palette="muted",
134
+ # legend='bottom',
135
+ # height=6,
136
+ data=mpg,
137
+ ax=ax,
138
+ )
139
+ return fig
140
+
141
+
142
+ @pytest.mark.mpl_image_compare
143
+ def test_seaborn_heatmap():
144
+ """
145
+ Test seaborn heatmaps. This should work thanks to backwards compatibility support.
146
+ """
147
+ fig, ax = pplt.subplots()
148
+ sns.heatmap(state.normal(size=(50, 50)), ax=ax[0])
149
+ return fig
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test legends.
4
+ """
5
+ import numpy as np, pandas as pd, ultraplot as pplt, pytest
6
+
7
+ state = np.random.RandomState(51423)
8
+
9
+
10
+ @pytest.mark.mpl_image_compare
11
+ def test_auto_legend():
12
+ """
13
+ Test retrieval of legends from panels, insets, etc.
14
+ """
15
+ fig, ax = pplt.subplots()
16
+ ax.line(state.rand(5, 3), labels=list("abc"))
17
+ px = ax.panel_axes("right", share=False)
18
+ px.linex(state.rand(5, 3), labels=list("xyz"))
19
+ # px.legend(loc='r')
20
+ ix = ax.inset_axes((-0.2, 0.8, 0.5, 0.5), zoom=False)
21
+ ix.line(state.rand(5, 2), labels=list("pq"))
22
+ ax.legend(loc="b", order="F", edgecolor="red9", edgewidth=3)
23
+ return fig
24
+
25
+
26
+ @pytest.mark.mpl_image_compare
27
+ def test_singleton_legend():
28
+ """
29
+ Test behavior when singleton lists are passed.
30
+ Ensure this does not trigger centered-row legends.
31
+ """
32
+ fig, ax = pplt.subplots()
33
+ h1 = ax.plot([0, 1, 2], label="a")
34
+ h2 = ax.plot([0, 1, 1], label="b")
35
+ ax.legend(loc="best")
36
+ ax.legend([h1, h2], loc="bottom")
37
+ return fig
38
+
39
+
40
+ @pytest.mark.mpl_image_compare
41
+ def test_centered_legends():
42
+ """
43
+ Test success of algorithm.
44
+ """
45
+ # Basic centered legends
46
+ fig, axs = pplt.subplots(ncols=2, nrows=2, axwidth=2)
47
+ hs = axs[0].plot(state.rand(10, 6))
48
+ locs = ["l", "t", "r", "uc", "ul", "ll"]
49
+ locs = ["l", "t", "uc", "ll"]
50
+ labels = ["a", "bb", "ccc", "ddddd", "eeeeeeee", "fffffffff"]
51
+ for ax, loc in zip(axs, locs):
52
+ ax.legend(hs, loc=loc, ncol=3, labels=labels, center=True)
53
+
54
+ # Pass centered legends with keywords or list-of-list input.
55
+ fig, ax = pplt.subplots()
56
+ hs = ax.plot(state.rand(10, 5), labels=list("abcde"))
57
+ ax.legend(hs, center=True, loc="b")
58
+ ax.legend(hs + hs[:1], loc="r", ncol=1)
59
+ ax.legend([hs[:2], hs[2:], hs[0]], loc="t")
60
+ return fig
61
+
62
+
63
+ @pytest.mark.mpl_image_compare
64
+ def test_manual_labels():
65
+ """
66
+ Test mixed auto and manual labels. Passing labels but no handles does nothing
67
+ This is breaking change but probably best. We should not be "guessing" the
68
+ order objects were drawn in then assigning labels to them. Similar to using
69
+ OO interface and rejecting pyplot "current axes" and "current figure".
70
+ """
71
+ fig, ax = pplt.subplots()
72
+ (h1,) = ax.plot([0, 1, 2], label="label1")
73
+ (h2,) = ax.plot([0, 1, 1], label="label2")
74
+ for loc in ("best", "bottom"):
75
+ ax.legend([h1, h2], loc=loc, labels=[None, "override"])
76
+ fig, ax = pplt.subplots()
77
+ ax.plot([0, 1, 2])
78
+ ax.plot([0, 1, 1])
79
+ for loc in ("best", "bottom"):
80
+ # ax.legend(loc=loc, labels=['a', 'b'])
81
+ ax.legend(["a", "b"], loc=loc) # same as above
82
+ return fig
83
+
84
+
85
+ @pytest.mark.mpl_image_compare
86
+ def test_contour_legend_with_label():
87
+ """
88
+ Support contour element labels. If has no label should trigger warning.
89
+ """
90
+ figs = []
91
+ label = "label"
92
+
93
+ fig, axs = pplt.subplots(ncols=2)
94
+ ax = axs[0]
95
+ ax.contour(state.rand(5, 5), color="k", label=label, legend="b")
96
+ ax = axs[1]
97
+ ax.pcolor(state.rand(5, 5), label=label, legend="b")
98
+ return fig
99
+
100
+
101
+ @pytest.mark.mpl_image_compare
102
+ def test_contour_legend_without_label():
103
+ """
104
+ Support contour element labels. If has no label should trigger warning.
105
+ """
106
+ figs = []
107
+ label = None
108
+
109
+ fig, axs = pplt.subplots(ncols=2)
110
+ ax = axs[0]
111
+ ax.contour(state.rand(5, 5), color="k", label=label, legend="b")
112
+ ax = axs[1]
113
+ ax.pcolor(state.rand(5, 5), label=label, legend="b")
114
+ return fig
115
+
116
+
117
+ @pytest.mark.mpl_image_compare
118
+ def test_histogram_legend():
119
+ """
120
+ Support complex histogram legends.
121
+ """
122
+ pplt.rc.inlinefmt = "svg"
123
+ fig, ax = pplt.subplots()
124
+ res = ax.hist(
125
+ state.rand(500, 2), 4, labels=("label", "other"), edgefix=True, legend="b"
126
+ )
127
+ ax.legend(res, loc="r", ncol=1) # should issue warning after ignoring numpy arrays
128
+ df = pd.DataFrame(
129
+ {"length": [1.5, 0.5, 1.2, 0.9, 3], "width": [0.7, 0.2, 0.15, 0.2, 1.1]},
130
+ index=["pig", "rabbit", "duck", "chicken", "horse"],
131
+ )
132
+ fig, axs = pplt.subplots(ncols=3)
133
+ ax = axs[0]
134
+ res = ax.hist(df, bins=3, legend=True, lw=3)
135
+ ax.legend(loc="b")
136
+ for ax, meth in zip(axs[1:], ("bar", "area")):
137
+ hs = getattr(ax, meth)(df, legend="ul", lw=3)
138
+ ax.legend(hs, loc="b")
139
+ return fig
140
+
141
+
142
+ @pytest.mark.mpl_image_compare
143
+ def test_multiple_calls():
144
+ """
145
+ Test successive plotting additions to guides.
146
+ """
147
+ fig, ax = pplt.subplots()
148
+ ax.pcolor(state.rand(10, 10), colorbar="b")
149
+ ax.pcolor(state.rand(10, 5), cmap="grays", colorbar="b")
150
+ ax.pcolor(state.rand(10, 5), cmap="grays", colorbar="b")
151
+
152
+ fig, ax = pplt.subplots()
153
+ data = state.rand(10, 5)
154
+ for i in range(data.shape[1]):
155
+ ax.plot(data[:, i], colorbar="b", label=f"x{i}", colorbar_kw={"label": "hello"})
156
+ return fig
157
+
158
+
159
+ @pytest.mark.mpl_image_compare
160
+ def test_tuple_handles():
161
+ """
162
+ Test tuple legend handles.
163
+ """
164
+ from matplotlib import legend_handler
165
+
166
+ fig, ax = pplt.subplots(refwidth=3, abc="A.", abcloc="ul", span=False)
167
+ patches = ax.fill_between(state.rand(10, 3), stack=True)
168
+ lines = ax.line(1 + 0.5 * (state.rand(10, 3) - 0.5).cumsum(axis=0))
169
+ # ax.legend([(handles[0], lines[1])], ['joint label'], loc='bottom', queue=True)
170
+ for hs in (lines, patches):
171
+ ax.legend(
172
+ [tuple(hs[:3]) if len(hs) == 3 else hs],
173
+ ["joint label"],
174
+ loc="bottom",
175
+ queue=True,
176
+ ncol=1,
177
+ handlelength=4.5,
178
+ handleheight=1.5,
179
+ handler_map={tuple: legend_handler.HandlerTuple(pad=0, ndivide=3)},
180
+ )
181
+ return fig