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.
- ultraplot/__init__.py +115 -0
- ultraplot/__init__.py.rej +58 -0
- ultraplot/axes/__init__.py +42 -0
- ultraplot/axes/base.py +3240 -0
- ultraplot/axes/cartesian.py +1425 -0
- ultraplot/axes/geo.py +1675 -0
- ultraplot/axes/plot.py +4569 -0
- ultraplot/axes/polar.py +381 -0
- ultraplot/axes/shared.py +186 -0
- ultraplot/axes/three.py +34 -0
- ultraplot/cmaps/Algae.rgb +256 -0
- ultraplot/cmaps/Amp.rgb +256 -0
- ultraplot/cmaps/BR.rgb +256 -0
- ultraplot/cmaps/Balance.rgb +256 -0
- ultraplot/cmaps/Blues1_r.xml +17 -0
- ultraplot/cmaps/Blues2.xml +16 -0
- ultraplot/cmaps/Blues3.xml +25 -0
- ultraplot/cmaps/Blues4_r.xml +17 -0
- ultraplot/cmaps/Blues5.xml +16 -0
- ultraplot/cmaps/Blues6.xml +25 -0
- ultraplot/cmaps/Blues7.xml +16 -0
- ultraplot/cmaps/Blues8.xml +17 -0
- ultraplot/cmaps/Blues9.xml +1 -0
- ultraplot/cmaps/Boreal.json +53 -0
- ultraplot/cmaps/Browns1.xml +16 -0
- ultraplot/cmaps/Browns2.xml +26 -0
- ultraplot/cmaps/Browns3.xml +17 -0
- ultraplot/cmaps/Browns4.xml +17 -0
- ultraplot/cmaps/Browns5.xml +26 -0
- ultraplot/cmaps/Browns6.xml +17 -0
- ultraplot/cmaps/Browns7.xml +19 -0
- ultraplot/cmaps/Browns8.xml +11 -0
- ultraplot/cmaps/Browns9.xml +1 -0
- ultraplot/cmaps/ColdHot.rgb +229 -0
- ultraplot/cmaps/Crest.rgb +256 -0
- ultraplot/cmaps/Curl.rgb +512 -0
- ultraplot/cmaps/Deep.rgb +256 -0
- ultraplot/cmaps/Delta.rgb +512 -0
- ultraplot/cmaps/Dense.rgb +256 -0
- ultraplot/cmaps/Div.json +71 -0
- ultraplot/cmaps/DryWet.json +73 -0
- ultraplot/cmaps/Dusk.json +53 -0
- ultraplot/cmaps/Fire.json +53 -0
- ultraplot/cmaps/Flare.rgb +256 -0
- ultraplot/cmaps/Glacial.json +53 -0
- ultraplot/cmaps/Greens1_r.xml +26 -0
- ultraplot/cmaps/Greens2.xml +28 -0
- ultraplot/cmaps/Greens3_r.xml +28 -0
- ultraplot/cmaps/Greens4.xml +17 -0
- ultraplot/cmaps/Greens5.xml +16 -0
- ultraplot/cmaps/Greens6_r.xml +16 -0
- ultraplot/cmaps/Greens7.xml +16 -0
- ultraplot/cmaps/Greens8.xml +26 -0
- ultraplot/cmaps/Haline.rgb +256 -0
- ultraplot/cmaps/Ice.rgb +256 -0
- ultraplot/cmaps/IceFire.rgb +256 -0
- ultraplot/cmaps/Mako.rgb +256 -0
- ultraplot/cmaps/Marine.json +53 -0
- ultraplot/cmaps/Matter.rgb +256 -0
- ultraplot/cmaps/Mono.txt +256 -0
- ultraplot/cmaps/MonoCycle.txt +256 -0
- ultraplot/cmaps/NegPos.json +71 -0
- ultraplot/cmaps/Oranges1.xml +27 -0
- ultraplot/cmaps/Oranges2.xml +26 -0
- ultraplot/cmaps/Oranges3.xml +15 -0
- ultraplot/cmaps/Oranges4.xml +23 -0
- ultraplot/cmaps/Oxy.rgb +256 -0
- ultraplot/cmaps/Phase.rgb +256 -0
- ultraplot/cmaps/Purples1_r.xml +16 -0
- ultraplot/cmaps/Purples2.xml +17 -0
- ultraplot/cmaps/Purples3.xml +18 -0
- ultraplot/cmaps/Reds1.xml +26 -0
- ultraplot/cmaps/Reds2.xml +22 -0
- ultraplot/cmaps/Reds3.xml +23 -0
- ultraplot/cmaps/Reds4.xml +26 -0
- ultraplot/cmaps/Reds5.xml +17 -0
- ultraplot/cmaps/Rocket.rgb +256 -0
- ultraplot/cmaps/Solar.rgb +256 -0
- ultraplot/cmaps/Speed.rgb +256 -0
- ultraplot/cmaps/Stellar.json +53 -0
- ultraplot/cmaps/Sunrise.json +53 -0
- ultraplot/cmaps/Sunset.json +53 -0
- ultraplot/cmaps/Tempo.rgb +256 -0
- ultraplot/cmaps/Thermal.rgb +256 -0
- ultraplot/cmaps/Turbid.rgb +256 -0
- ultraplot/cmaps/Vivid.xml +11 -0
- ultraplot/cmaps/Vlag.rgb +256 -0
- ultraplot/cmaps/Yellows1.xml +17 -0
- ultraplot/cmaps/Yellows2.xml +17 -0
- ultraplot/cmaps/Yellows3.xml +17 -0
- ultraplot/cmaps/Yellows4.xml +17 -0
- ultraplot/cmaps/acton.txt +256 -0
- ultraplot/cmaps/bam.txt +256 -0
- ultraplot/cmaps/bamO.txt +256 -0
- ultraplot/cmaps/bamako.txt +256 -0
- ultraplot/cmaps/batlow.txt +256 -0
- ultraplot/cmaps/batlowK.txt +256 -0
- ultraplot/cmaps/batlowW.txt +256 -0
- ultraplot/cmaps/berlin.txt +256 -0
- ultraplot/cmaps/bilbao.txt +256 -0
- ultraplot/cmaps/broc.txt +256 -0
- ultraplot/cmaps/brocO.txt +256 -0
- ultraplot/cmaps/buda.txt +256 -0
- ultraplot/cmaps/bukavu.txt +256 -0
- ultraplot/cmaps/cork.txt +256 -0
- ultraplot/cmaps/corkO.txt +256 -0
- ultraplot/cmaps/davos.txt +256 -0
- ultraplot/cmaps/devon.txt +256 -0
- ultraplot/cmaps/fes.txt +256 -0
- ultraplot/cmaps/hawaii.txt +256 -0
- ultraplot/cmaps/imola.txt +256 -0
- ultraplot/cmaps/lajolla.txt +256 -0
- ultraplot/cmaps/lapaz.txt +256 -0
- ultraplot/cmaps/lisbon.txt +256 -0
- ultraplot/cmaps/nuuk.txt +256 -0
- ultraplot/cmaps/oleron.txt +256 -0
- ultraplot/cmaps/oslo.txt +256 -0
- ultraplot/cmaps/roma.txt +256 -0
- ultraplot/cmaps/romaO.txt +256 -0
- ultraplot/cmaps/tofino.txt +256 -0
- ultraplot/cmaps/tokyo.txt +256 -0
- ultraplot/cmaps/turku.txt +256 -0
- ultraplot/cmaps/vanimo.txt +256 -0
- ultraplot/cmaps/vik.txt +256 -0
- ultraplot/cmaps/vikO.txt +256 -0
- ultraplot/colors/opencolor.txt +132 -0
- ultraplot/colors/xkcd.txt +951 -0
- ultraplot/colors.py +3241 -0
- ultraplot/colors.py.rej +243 -0
- ultraplot/config.py +1809 -0
- ultraplot/constructor.py +1633 -0
- ultraplot/cycles/538.hex +2 -0
- ultraplot/cycles/FlatUI.hex +1 -0
- ultraplot/cycles/Qual1.rgb +7 -0
- ultraplot/cycles/Qual2.rgb +13 -0
- ultraplot/cycles/bmh.hex +2 -0
- ultraplot/cycles/classic.hex +2 -0
- ultraplot/cycles/colorblind.hex +2 -0
- ultraplot/cycles/colorblind10.hex +2 -0
- ultraplot/cycles/default.hex +2 -0
- ultraplot/cycles/ggplot.hex +1 -0
- ultraplot/cycles/seaborn.hex +2 -0
- ultraplot/cycles/tableau.hex +2 -0
- ultraplot/demos.py +1201 -0
- ultraplot/externals/__init__.py +5 -0
- ultraplot/externals/hsluv.py +330 -0
- ultraplot/figure.py +2102 -0
- ultraplot/fonts/FiraMath-Bold.ttf +0 -0
- ultraplot/fonts/FiraMath-ExtraLight.ttf +0 -0
- ultraplot/fonts/FiraMath-Heavy.ttf +0 -0
- ultraplot/fonts/FiraMath-Light.ttf +0 -0
- ultraplot/fonts/FiraMath-Medium.ttf +0 -0
- ultraplot/fonts/FiraMath-Regular.ttf +0 -0
- ultraplot/fonts/FiraMath-SemiBold.ttf +0 -0
- ultraplot/fonts/FiraMath-UltraLight.ttf +0 -0
- ultraplot/fonts/FiraSans-Black.ttf +0 -0
- ultraplot/fonts/FiraSans-BlackItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-Bold.ttf +0 -0
- ultraplot/fonts/FiraSans-BoldItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-ExtraBold.ttf +0 -0
- ultraplot/fonts/FiraSans-ExtraBoldItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-ExtraLight.ttf +0 -0
- ultraplot/fonts/FiraSans-ExtraLightItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-Italic.ttf +0 -0
- ultraplot/fonts/FiraSans-Light.ttf +0 -0
- ultraplot/fonts/FiraSans-LightItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-Medium.ttf +0 -0
- ultraplot/fonts/FiraSans-MediumItalic.ttf +0 -0
- ultraplot/fonts/FiraSans-Regular.ttf +0 -0
- ultraplot/fonts/FiraSans-SemiBold.ttf +0 -0
- ultraplot/fonts/FiraSans-SemiBoldItalic.ttf +0 -0
- ultraplot/fonts/LICENSE_FIRAMATH.txt +92 -0
- ultraplot/fonts/LICENSE_FIRASANS.txt +97 -0
- ultraplot/fonts/LICENSE_NOTOSANS.txt +202 -0
- ultraplot/fonts/LICENSE_NOTOSERIF.txt +93 -0
- ultraplot/fonts/LICENSE_OPENSANS.txt +202 -0
- ultraplot/fonts/LICENSE_ROBOTO.txt +202 -0
- ultraplot/fonts/LICENSE_SOURCESANS.txt +93 -0
- ultraplot/fonts/LICENSE_SOURCESERIF.txt +93 -0
- ultraplot/fonts/LICENSE_TEXGYRE.txt +29 -0
- ultraplot/fonts/LICENSE_UBUNTU.txt +96 -0
- ultraplot/fonts/NotoSans-Bold.ttf +0 -0
- ultraplot/fonts/NotoSans-BoldItalic.ttf +0 -0
- ultraplot/fonts/NotoSans-Italic.ttf +0 -0
- ultraplot/fonts/NotoSans-Regular.ttf +0 -0
- ultraplot/fonts/NotoSerif-Bold.ttf +0 -0
- ultraplot/fonts/NotoSerif-BoldItalic.ttf +0 -0
- ultraplot/fonts/NotoSerif-Italic.ttf +0 -0
- ultraplot/fonts/NotoSerif-Regular.ttf +0 -0
- ultraplot/fonts/OpenSans-Bold.ttf +0 -0
- ultraplot/fonts/OpenSans-BoldItalic.ttf +0 -0
- ultraplot/fonts/OpenSans-Italic.ttf +0 -0
- ultraplot/fonts/OpenSans-Regular.ttf +0 -0
- ultraplot/fonts/OpenSans-Semibold.ttf +0 -0
- ultraplot/fonts/OpenSans-SemiboldItalic.ttf +0 -0
- ultraplot/fonts/Roboto-Black.ttf +0 -0
- ultraplot/fonts/Roboto-BlackItalic.ttf +0 -0
- ultraplot/fonts/Roboto-Bold.ttf +0 -0
- ultraplot/fonts/Roboto-BoldItalic.ttf +0 -0
- ultraplot/fonts/Roboto-Italic.ttf +0 -0
- ultraplot/fonts/Roboto-Light.ttf +0 -0
- ultraplot/fonts/Roboto-LightItalic.ttf +0 -0
- ultraplot/fonts/Roboto-Medium.ttf +0 -0
- ultraplot/fonts/Roboto-MediumItalic.ttf +0 -0
- ultraplot/fonts/Roboto-Regular.ttf +0 -0
- ultraplot/fonts/SourceSansPro-Black.ttf +0 -0
- ultraplot/fonts/SourceSansPro-BlackItalic.ttf +0 -0
- ultraplot/fonts/SourceSansPro-Bold.ttf +0 -0
- ultraplot/fonts/SourceSansPro-BoldItalic.ttf +0 -0
- ultraplot/fonts/SourceSansPro-ExtraLight.ttf +0 -0
- ultraplot/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
- ultraplot/fonts/SourceSansPro-Italic.ttf +0 -0
- ultraplot/fonts/SourceSansPro-Light.ttf +0 -0
- ultraplot/fonts/SourceSansPro-LightItalic.ttf +0 -0
- ultraplot/fonts/SourceSansPro-Regular.ttf +0 -0
- ultraplot/fonts/SourceSansPro-SemiBold.ttf +0 -0
- ultraplot/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-Black.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-BlackItalic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-Bold.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-BoldItalic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-ExtraLight.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-ExtraLightItalic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-Italic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-Light.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-LightItalic.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-Regular.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-SemiBold.ttf +0 -0
- ultraplot/fonts/SourceSerifPro-SemiBoldItalic.ttf +0 -0
- ultraplot/fonts/Ubuntu-Bold.ttf +0 -0
- ultraplot/fonts/Ubuntu-BoldItalic.ttf +0 -0
- ultraplot/fonts/Ubuntu-Italic.ttf +0 -0
- ultraplot/fonts/Ubuntu-Light.ttf +0 -0
- ultraplot/fonts/Ubuntu-LightItalic.ttf +0 -0
- ultraplot/fonts/Ubuntu-Medium.ttf +0 -0
- ultraplot/fonts/Ubuntu-MediumItalic.ttf +0 -0
- ultraplot/fonts/Ubuntu-Regular.ttf +0 -0
- ultraplot/fonts/texgyreadventor-bold.ttf +0 -0
- ultraplot/fonts/texgyreadventor-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyreadventor-italic.ttf +0 -0
- ultraplot/fonts/texgyreadventor-regular.ttf +0 -0
- ultraplot/fonts/texgyrebonum-bold.ttf +0 -0
- ultraplot/fonts/texgyrebonum-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyrebonum-italic.ttf +0 -0
- ultraplot/fonts/texgyrebonum-regular.ttf +0 -0
- ultraplot/fonts/texgyrechorus-mediumitalic.ttf +0 -0
- ultraplot/fonts/texgyrecursor-bold.ttf +0 -0
- ultraplot/fonts/texgyrecursor-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyrecursor-italic.ttf +0 -0
- ultraplot/fonts/texgyrecursor-regular.ttf +0 -0
- ultraplot/fonts/texgyreheros-bold.ttf +0 -0
- ultraplot/fonts/texgyreheros-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyreheros-italic.ttf +0 -0
- ultraplot/fonts/texgyreheros-regular.ttf +0 -0
- ultraplot/fonts/texgyrepagella-bold.ttf +0 -0
- ultraplot/fonts/texgyrepagella-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyrepagella-italic.ttf +0 -0
- ultraplot/fonts/texgyrepagella-regular.ttf +0 -0
- ultraplot/fonts/texgyreschola-bold.ttf +0 -0
- ultraplot/fonts/texgyreschola-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyreschola-italic.ttf +0 -0
- ultraplot/fonts/texgyreschola-regular.ttf +0 -0
- ultraplot/fonts/texgyretermes-bold.ttf +0 -0
- ultraplot/fonts/texgyretermes-bolditalic.ttf +0 -0
- ultraplot/fonts/texgyretermes-italic.ttf +0 -0
- ultraplot/fonts/texgyretermes-regular.ttf +0 -0
- ultraplot/gridspec.py +1698 -0
- ultraplot/internals/__init__.py +529 -0
- ultraplot/internals/benchmarks.py +26 -0
- ultraplot/internals/context.py +44 -0
- ultraplot/internals/docstring.py +139 -0
- ultraplot/internals/fonts.py +75 -0
- ultraplot/internals/guides.py +167 -0
- ultraplot/internals/inputs.py +862 -0
- ultraplot/internals/labels.py +85 -0
- ultraplot/internals/rcsetup.py +1933 -0
- ultraplot/internals/versions.py +61 -0
- ultraplot/internals/warnings.py +122 -0
- ultraplot/proj.py +325 -0
- ultraplot/scale.py +966 -0
- ultraplot/tests/__init__.py +28 -0
- ultraplot/tests/baseline/test_align_labels.png +0 -0
- ultraplot/tests/baseline/test_aligned_outer_guides.png +0 -0
- ultraplot/tests/baseline/test_aspect_ratios.png +0 -0
- ultraplot/tests/baseline/test_auto_diverging1.png +0 -0
- ultraplot/tests/baseline/test_auto_legend.png +0 -0
- ultraplot/tests/baseline/test_auto_reverse.png +0 -0
- ultraplot/tests/baseline/test_autodiverging3.png +0 -0
- ultraplot/tests/baseline/test_autodiverging4.png +0 -0
- ultraplot/tests/baseline/test_autodiverging5.png +0 -0
- ultraplot/tests/baseline/test_axes_colors.png +0 -0
- ultraplot/tests/baseline/test_bar_vectors.png +0 -0
- ultraplot/tests/baseline/test_bar_width.png +0 -0
- ultraplot/tests/baseline/test_both_ticklabels.png +0 -0
- ultraplot/tests/baseline/test_bounds_ticks.png +0 -0
- ultraplot/tests/baseline/test_boxplot_colors.png +0 -0
- ultraplot/tests/baseline/test_boxplot_vectors.png +0 -0
- ultraplot/tests/baseline/test_cartopy_contours.png +0 -0
- ultraplot/tests/baseline/test_cartopy_labels.png +0 -0
- ultraplot/tests/baseline/test_cartopy_manual.png +0 -0
- ultraplot/tests/baseline/test_centered_legends.png +0 -0
- ultraplot/tests/baseline/test_cmap_cycles.png +0 -0
- ultraplot/tests/baseline/test_colorbar.png +0 -0
- ultraplot/tests/baseline/test_colorbar_ticks.png +0 -0
- ultraplot/tests/baseline/test_colormap_mode.png +0 -0
- ultraplot/tests/baseline/test_column_iteration.png +0 -0
- ultraplot/tests/baseline/test_complex_ticks.png +0 -0
- ultraplot/tests/baseline/test_contour_labels.png +0 -0
- ultraplot/tests/baseline/test_contour_legend_with_label.png +0 -0
- ultraplot/tests/baseline/test_contour_legend_without_label.png +0 -0
- ultraplot/tests/baseline/test_contour_negative.png +0 -0
- ultraplot/tests/baseline/test_contour_single.png +0 -0
- ultraplot/tests/baseline/test_cutoff_ticks.png +0 -0
- ultraplot/tests/baseline/test_data_keyword.png +0 -0
- ultraplot/tests/baseline/test_discrete_ticks.png +0 -0
- ultraplot/tests/baseline/test_discrete_vs_fixed.png +0 -0
- ultraplot/tests/baseline/test_drawing_in_projection_with_globe.png +0 -0
- ultraplot/tests/baseline/test_drawing_in_projection_without_globe.png +0 -0
- ultraplot/tests/baseline/test_edge_fix.png +0 -0
- ultraplot/tests/baseline/test_flow_functions.png +0 -0
- ultraplot/tests/baseline/test_font_adjustments.png +0 -0
- ultraplot/tests/baseline/test_geographic_multiple_projections.png +0 -0
- ultraplot/tests/baseline/test_geographic_single_projection.png +0 -0
- ultraplot/tests/baseline/test_gray_adjustment.png +0 -0
- ultraplot/tests/baseline/test_histogram_legend.png +0 -0
- ultraplot/tests/baseline/test_histogram_types.png +0 -0
- ultraplot/tests/baseline/test_ignore_message.png +0 -0
- ultraplot/tests/baseline/test_inbounds_data.png +0 -0
- ultraplot/tests/baseline/test_init_format.png +0 -0
- ultraplot/tests/baseline/test_inner_title_zorder.png +0 -0
- ultraplot/tests/baseline/test_inset_basic.png +0 -0
- ultraplot/tests/baseline/test_inset_colorbars.png +0 -0
- ultraplot/tests/baseline/test_inset_colors_1.png +0 -0
- ultraplot/tests/baseline/test_inset_colors_2.png +0 -0
- ultraplot/tests/baseline/test_inset_zoom_update.png +0 -0
- ultraplot/tests/baseline/test_invalid_dist.png +0 -0
- ultraplot/tests/baseline/test_invalid_plot.png +0 -0
- ultraplot/tests/baseline/test_keep_guide_labels.png +0 -0
- ultraplot/tests/baseline/test_label_settings.png +0 -0
- ultraplot/tests/baseline/test_level_restriction.png +0 -0
- ultraplot/tests/baseline/test_levels_with_vmin_vmax.png +0 -0
- ultraplot/tests/baseline/test_locale_formatting.png +0 -0
- ultraplot/tests/baseline/test_locale_formatting_en_US.UTF-8.png +0 -0
- ultraplot/tests/baseline/test_manual_labels.png +0 -0
- ultraplot/tests/baseline/test_multi_formatting.png +0 -0
- ultraplot/tests/baseline/test_multiple_calls.png +0 -0
- ultraplot/tests/baseline/test_on_the_fly_mappable.png +0 -0
- ultraplot/tests/baseline/test_outer_align.png +0 -0
- ultraplot/tests/baseline/test_panel_dist.png +0 -0
- ultraplot/tests/baseline/test_panels_suplabels_three_hor_panels.png +0 -0
- ultraplot/tests/baseline/test_panels_with_sharing.png +0 -0
- ultraplot/tests/baseline/test_panels_without_sharing_1.png +0 -0
- ultraplot/tests/baseline/test_panels_without_sharing_2.png +0 -0
- ultraplot/tests/baseline/test_parametric_colors.png +0 -0
- ultraplot/tests/baseline/test_parametric_labels.png +0 -0
- ultraplot/tests/baseline/test_patch_format.png +0 -0
- ultraplot/tests/baseline/test_pie_charts.png +0 -0
- ultraplot/tests/baseline/test_pint_quantities.png +0 -0
- ultraplot/tests/baseline/test_polar_projections.png +0 -0
- ultraplot/tests/baseline/test_projection_dicts.png +0 -0
- ultraplot/tests/baseline/test_qualitative_colormaps_1.png +0 -0
- ultraplot/tests/baseline/test_qualitative_colormaps_2.png +0 -0
- ultraplot/tests/baseline/test_reversed_levels.png +0 -0
- ultraplot/tests/baseline/test_scatter_alpha.png +0 -0
- ultraplot/tests/baseline/test_scatter_args.png +0 -0
- ultraplot/tests/baseline/test_scatter_cycle.png +0 -0
- ultraplot/tests/baseline/test_scatter_inbounds.png +0 -0
- ultraplot/tests/baseline/test_scatter_sizes.png +0 -0
- ultraplot/tests/baseline/test_seaborn_heatmap.png +0 -0
- ultraplot/tests/baseline/test_seaborn_hist.png +0 -0
- ultraplot/tests/baseline/test_seaborn_relational.png +0 -0
- ultraplot/tests/baseline/test_seaborn_swarmplot.png +0 -0
- ultraplot/tests/baseline/test_segmented_norm.png +0 -0
- ultraplot/tests/baseline/test_segmented_norm_ticks.png +0 -0
- ultraplot/tests/baseline/test_share_all_basic.png +0 -0
- ultraplot/tests/baseline/test_singleton_legend.png +0 -0
- ultraplot/tests/baseline/test_span_labels.png +0 -0
- ultraplot/tests/baseline/test_spine_offset.png +0 -0
- ultraplot/tests/baseline/test_spine_side.png +0 -0
- ultraplot/tests/baseline/test_standardized_input.png +0 -0
- ultraplot/tests/baseline/test_statistical_boxplot.png +0 -0
- ultraplot/tests/baseline/test_three_axes.png +0 -0
- ultraplot/tests/baseline/test_tick_direction.png +0 -0
- ultraplot/tests/baseline/test_tick_labels.png +0 -0
- ultraplot/tests/baseline/test_tick_length.png +0 -0
- ultraplot/tests/baseline/test_tick_width.png +0 -0
- ultraplot/tests/baseline/test_title_deflection.png +0 -0
- ultraplot/tests/baseline/test_triangular_functions.png +0 -0
- ultraplot/tests/baseline/test_tuple_handles.png +0 -0
- ultraplot/tests/baseline/test_twin_axes_1.png +0 -0
- ultraplot/tests/baseline/test_twin_axes_2.png +0 -0
- ultraplot/tests/baseline/test_twin_axes_3.png +0 -0
- ultraplot/tests/baseline/test_uneven_levels.png +0 -0
- ultraplot/tests/test_1dplots.py +373 -0
- ultraplot/tests/test_2dplots.py +354 -0
- ultraplot/tests/test_axes.py +179 -0
- ultraplot/tests/test_colorbar.py +253 -0
- ultraplot/tests/test_docs.py +78 -0
- ultraplot/tests/test_format.py +340 -0
- ultraplot/tests/test_geographic.py +116 -0
- ultraplot/tests/test_imshow.py +110 -0
- ultraplot/tests/test_inset.py +28 -0
- ultraplot/tests/test_integration.py +149 -0
- ultraplot/tests/test_legend.py +181 -0
- ultraplot/tests/test_projections.py +138 -0
- ultraplot/tests/test_statistical_plotting.py +77 -0
- ultraplot/tests/test_subplots.py +174 -0
- ultraplot/ticker.py +879 -0
- ultraplot/ui.py +233 -0
- ultraplot/utils.py +912 -0
- ultraplot-0.99.3.dist-info/LICENSE.txt +427 -0
- ultraplot-0.99.3.dist-info/METADATA +88 -0
- ultraplot-0.99.3.dist-info/RECORD +416 -0
- ultraplot-0.99.3.dist-info/WHEEL +5 -0
- ultraplot-0.99.3.dist-info/entry_points.txt +2 -0
- ultraplot-0.99.3.dist-info/top_level.txt +1 -0
ultraplot/axes/polar.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Polar axes using azimuth and radius instead of *x* and *y*.
|
|
4
|
+
"""
|
|
5
|
+
import inspect
|
|
6
|
+
|
|
7
|
+
import matplotlib.projections.polar as mpolar
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from .. import constructor
|
|
11
|
+
from .. import ticker as pticker
|
|
12
|
+
from ..config import rc
|
|
13
|
+
from ..internals import ic # noqa: F401
|
|
14
|
+
from ..internals import _not_none, _pop_rc, docstring
|
|
15
|
+
from . import plot, shared
|
|
16
|
+
|
|
17
|
+
__all__ = ["PolarAxes"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Format docstring
|
|
21
|
+
_format_docstring = """
|
|
22
|
+
r0 : float, default: 0
|
|
23
|
+
The radial origin.
|
|
24
|
+
theta0 : {'N', 'NW', 'W', 'SW', 'S', 'SE', 'E', 'NE'}, optional
|
|
25
|
+
The zero azimuth location.
|
|
26
|
+
thetadir : {1, -1, 'anticlockwise', 'counterclockwise', 'clockwise'}, optional
|
|
27
|
+
The positive azimuth direction. Clockwise corresponds to
|
|
28
|
+
``-1`` and anticlockwise corresponds to ``1``.
|
|
29
|
+
thetamin, thetamax : float, optional
|
|
30
|
+
The lower and upper azimuthal bounds in degrees. If
|
|
31
|
+
``thetamax != thetamin + 360``, this produces a sector plot.
|
|
32
|
+
thetalim : 2-tuple of float or None, optional
|
|
33
|
+
Specifies `thetamin` and `thetamax` at once.
|
|
34
|
+
rmin, rmax : float, optional
|
|
35
|
+
The inner and outer radial limits. If ``r0 != rmin``, this
|
|
36
|
+
produces an annular plot.
|
|
37
|
+
rlim : 2-tuple of float or None, optional
|
|
38
|
+
Specifies `rmin` and `rmax` at once.
|
|
39
|
+
rborder : bool, optional
|
|
40
|
+
Whether to draw the polar axes border. Visibility of the "inner"
|
|
41
|
+
radial spine and "start" and "end" azimuthal spines is controlled
|
|
42
|
+
automatically by matplotlib.
|
|
43
|
+
thetagrid, rgrid, grid : bool, optional
|
|
44
|
+
Whether to draw major gridlines for the azimuthal and radial axis.
|
|
45
|
+
Use the keyword `grid` to toggle both.
|
|
46
|
+
thetagridminor, rgridminor, gridminor : bool, optional
|
|
47
|
+
Whether to draw minor gridlines for the azimuthal and radial axis.
|
|
48
|
+
Use the keyword `gridminor` to toggle both.
|
|
49
|
+
thetagridcolor, rgridcolor, gridcolor : color-spec, optional
|
|
50
|
+
Color for the major and minor azimuthal and radial gridlines.
|
|
51
|
+
Use the keyword `gridcolor` to set both at once.
|
|
52
|
+
thetalocator, rlocator : locator-spec, optional
|
|
53
|
+
Used to determine the azimuthal and radial gridline positions.
|
|
54
|
+
Passed to the `~ultraplot.constructor.Locator` constructor. Can be
|
|
55
|
+
float, list of float, string, or `matplotlib.ticker.Locator` instance.
|
|
56
|
+
thetalines, rlines
|
|
57
|
+
Aliases for `thetalocator`, `rlocator`.
|
|
58
|
+
thetalocator_kw, rlocator_kw : dict-like, optional
|
|
59
|
+
The azimuthal and radial locator settings. Passed to
|
|
60
|
+
`~ultraplot.constructor.Locator`.
|
|
61
|
+
thetaminorlocator, rminorlocator : optional
|
|
62
|
+
As for `thetalocator`, `rlocator`, but for the minor gridlines.
|
|
63
|
+
thetaminorticks, rminorticks : optional
|
|
64
|
+
Aliases for `thetaminorlocator`, `rminorlocator`.
|
|
65
|
+
thetaminorlocator_kw, rminorlocator_kw
|
|
66
|
+
As for `thetalocator_kw`, `rlocator_kw`, but for the minor locator.
|
|
67
|
+
rlabelpos : float, optional
|
|
68
|
+
The azimuth at which radial coordinates are labeled.
|
|
69
|
+
thetaformatter, rformatter : formatter-spec, optional
|
|
70
|
+
Used to determine the azimuthal and radial label format.
|
|
71
|
+
Passed to the `~ultraplot.constructor.Formatter` constructor.
|
|
72
|
+
Can be string, list of string, or `matplotlib.ticker.Formatter`
|
|
73
|
+
instance. Use ``[]``, ``'null'``, or ``'none'`` for no labels.
|
|
74
|
+
thetalabels, rlabels : optional
|
|
75
|
+
Aliases for `thetaformatter`, `rformatter`.
|
|
76
|
+
thetaformatter_kw, rformatter_kw : dict-like, optional
|
|
77
|
+
The azimuthal and radial label formatter settings. Passed to
|
|
78
|
+
`~ultraplot.constructor.Formatter`.
|
|
79
|
+
color : color-spec, default: :rc:`meta.color`
|
|
80
|
+
Color for the axes edge. Propagates to `labelcolor` unless specified
|
|
81
|
+
otherwise (similar to `ultraplot.axes.CartesianAxes.format`).
|
|
82
|
+
labelcolor, gridlabelcolor : color-spec, default: `color` or :rc:`grid.labelcolor`
|
|
83
|
+
Color for the gridline labels.
|
|
84
|
+
labelpad, gridlabelpad : unit-spec, default: :rc:`grid.labelpad`
|
|
85
|
+
The padding between the axes edge and the radial and azimuthal labels.
|
|
86
|
+
%(units.pt)s
|
|
87
|
+
labelsize, gridlabelsize : unit-spec or str, default: :rc:`grid.labelsize`
|
|
88
|
+
Font size for the gridline labels.
|
|
89
|
+
%(units.pt)s
|
|
90
|
+
labelweight, gridlabelweight : str, default: :rc:`grid.labelweight`
|
|
91
|
+
Font weight for the gridline labels.
|
|
92
|
+
"""
|
|
93
|
+
docstring._snippet_manager["polar.format"] = _format_docstring
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class PolarAxes(shared._SharedAxes, plot.PlotAxes, mpolar.PolarAxes):
|
|
97
|
+
"""
|
|
98
|
+
Axes subclass for plotting in polar coordinates. Adds the `~PolarAxes.format`
|
|
99
|
+
method and overrides several existing methods.
|
|
100
|
+
|
|
101
|
+
Important
|
|
102
|
+
---------
|
|
103
|
+
This axes subclass can be used by passing ``proj='polar'``
|
|
104
|
+
to axes-creation commands like `~ultraplot.figure.Figure.add_axes`,
|
|
105
|
+
`~ultraplot.figure.Figure.add_subplot`, and `~ultraplot.figure.Figure.subplots`.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
_name = "polar"
|
|
109
|
+
|
|
110
|
+
@docstring._snippet_manager
|
|
111
|
+
def __init__(self, *args, **kwargs):
|
|
112
|
+
"""
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
*args
|
|
116
|
+
Passed to `matplotlib.axes.Axes`.
|
|
117
|
+
%(polar.format)s
|
|
118
|
+
|
|
119
|
+
Other parameters
|
|
120
|
+
----------------
|
|
121
|
+
%(axes.format)s
|
|
122
|
+
%(rc.init)s
|
|
123
|
+
|
|
124
|
+
See also
|
|
125
|
+
--------
|
|
126
|
+
PolarAxes.format
|
|
127
|
+
ultraplot.axes.Axes
|
|
128
|
+
ultraplot.axes.PlotAxes
|
|
129
|
+
matplotlib.projections.PolarAxes
|
|
130
|
+
ultraplot.figure.Figure.subplot
|
|
131
|
+
ultraplot.figure.Figure.add_subplot
|
|
132
|
+
"""
|
|
133
|
+
# Set tick length to zero so azimuthal labels are not too offset
|
|
134
|
+
# Change default radial axis formatter but keep default theta one
|
|
135
|
+
super().__init__(*args, **kwargs)
|
|
136
|
+
self.yaxis.set_major_formatter(pticker.AutoFormatter())
|
|
137
|
+
self.yaxis.isDefault_majfmt = True
|
|
138
|
+
for axis in (self.xaxis, self.yaxis):
|
|
139
|
+
axis.set_tick_params(which="both", size=0)
|
|
140
|
+
|
|
141
|
+
def _update_formatter(self, x, *, formatter=None, formatter_kw=None):
|
|
142
|
+
"""
|
|
143
|
+
Update the gridline label formatter.
|
|
144
|
+
"""
|
|
145
|
+
# Tick formatter and toggling
|
|
146
|
+
axis = getattr(self, x + "axis")
|
|
147
|
+
formatter_kw = formatter_kw or {}
|
|
148
|
+
if formatter is not None:
|
|
149
|
+
formatter = constructor.Formatter(formatter, **formatter_kw) # noqa: E501
|
|
150
|
+
axis.set_major_formatter(formatter)
|
|
151
|
+
|
|
152
|
+
def _update_limits(self, x, *, min_=None, max_=None, lim=None):
|
|
153
|
+
"""
|
|
154
|
+
Update the limits.
|
|
155
|
+
"""
|
|
156
|
+
# Try to use public API where possible
|
|
157
|
+
r = "theta" if x == "x" else "r"
|
|
158
|
+
min_, max_ = self._min_max_lim(r, min_, max_, lim)
|
|
159
|
+
if min_ is not None:
|
|
160
|
+
getattr(self, f"set_{r}min")(min_)
|
|
161
|
+
if max_ is not None:
|
|
162
|
+
getattr(self, f"set_{r}max")(max_)
|
|
163
|
+
|
|
164
|
+
def _update_locators(
|
|
165
|
+
self,
|
|
166
|
+
x,
|
|
167
|
+
*,
|
|
168
|
+
locator=None,
|
|
169
|
+
locator_kw=None,
|
|
170
|
+
minorlocator=None,
|
|
171
|
+
minorlocator_kw=None,
|
|
172
|
+
):
|
|
173
|
+
"""
|
|
174
|
+
Update the gridline locator.
|
|
175
|
+
"""
|
|
176
|
+
# TODO: Add minor tick 'toggling' as with cartesian axes?
|
|
177
|
+
# NOTE: Must convert theta locator input to radians, then back to deg.
|
|
178
|
+
r = "theta" if x == "x" else "r"
|
|
179
|
+
axis = getattr(self, x + "axis")
|
|
180
|
+
min_ = getattr(self, f"get_{r}min")()
|
|
181
|
+
max_ = getattr(self, f"get_{r}max")()
|
|
182
|
+
for i, (loc, loc_kw) in enumerate(
|
|
183
|
+
zip((locator, minorlocator), (locator_kw, minorlocator_kw))
|
|
184
|
+
):
|
|
185
|
+
if loc is None:
|
|
186
|
+
continue
|
|
187
|
+
# Get locator
|
|
188
|
+
loc_kw = loc_kw or {}
|
|
189
|
+
loc = constructor.Locator(loc, **loc_kw)
|
|
190
|
+
# Sanitize values
|
|
191
|
+
array = loc.tick_values(min_, max_)
|
|
192
|
+
array = array[(array >= min_) & (array <= max_)]
|
|
193
|
+
if x == "x":
|
|
194
|
+
array = np.deg2rad(array)
|
|
195
|
+
if np.isclose(array[-1], min_ + 2 * np.pi): # exclusive if 360 deg
|
|
196
|
+
array = array[:-1]
|
|
197
|
+
# Assign fixed location
|
|
198
|
+
loc = constructor.Locator(array) # convert to FixedLocator
|
|
199
|
+
if i == 0:
|
|
200
|
+
axis.set_major_locator(loc)
|
|
201
|
+
else:
|
|
202
|
+
axis.set_minor_locator(loc)
|
|
203
|
+
|
|
204
|
+
@docstring._snippet_manager
|
|
205
|
+
def format(
|
|
206
|
+
self,
|
|
207
|
+
*,
|
|
208
|
+
r0=None,
|
|
209
|
+
theta0=None,
|
|
210
|
+
thetadir=None,
|
|
211
|
+
thetamin=None,
|
|
212
|
+
thetamax=None,
|
|
213
|
+
thetalim=None,
|
|
214
|
+
rmin=None,
|
|
215
|
+
rmax=None,
|
|
216
|
+
rlim=None,
|
|
217
|
+
thetagrid=None,
|
|
218
|
+
rgrid=None,
|
|
219
|
+
thetagridminor=None,
|
|
220
|
+
rgridminor=None,
|
|
221
|
+
thetagridcolor=None,
|
|
222
|
+
rgridcolor=None,
|
|
223
|
+
rlabelpos=None,
|
|
224
|
+
rscale=None,
|
|
225
|
+
rborder=None,
|
|
226
|
+
thetalocator=None,
|
|
227
|
+
rlocator=None,
|
|
228
|
+
thetalines=None,
|
|
229
|
+
rlines=None,
|
|
230
|
+
thetalocator_kw=None,
|
|
231
|
+
rlocator_kw=None,
|
|
232
|
+
thetaminorlocator=None,
|
|
233
|
+
rminorlocator=None,
|
|
234
|
+
thetaminorlines=None,
|
|
235
|
+
rminorlines=None, # noqa: E501
|
|
236
|
+
thetaminorlocator_kw=None,
|
|
237
|
+
rminorlocator_kw=None,
|
|
238
|
+
thetaformatter=None,
|
|
239
|
+
rformatter=None,
|
|
240
|
+
thetalabels=None,
|
|
241
|
+
rlabels=None,
|
|
242
|
+
thetaformatter_kw=None,
|
|
243
|
+
rformatter_kw=None,
|
|
244
|
+
labelpad=None,
|
|
245
|
+
labelsize=None,
|
|
246
|
+
labelcolor=None,
|
|
247
|
+
labelweight=None,
|
|
248
|
+
**kwargs,
|
|
249
|
+
):
|
|
250
|
+
"""
|
|
251
|
+
Modify axes limits, radial and azimuthal gridlines, and more. Note that
|
|
252
|
+
all of the ``theta`` arguments are specified in degrees, not radians.
|
|
253
|
+
|
|
254
|
+
Parameters
|
|
255
|
+
----------
|
|
256
|
+
%(polar.format)s
|
|
257
|
+
|
|
258
|
+
Other parameters
|
|
259
|
+
----------------
|
|
260
|
+
%(axes.format)s
|
|
261
|
+
%(figure.format)s
|
|
262
|
+
%(rc.format)s
|
|
263
|
+
|
|
264
|
+
See also
|
|
265
|
+
--------
|
|
266
|
+
ultraplot.axes.Axes.format
|
|
267
|
+
ultraplot.config.Configurator.context
|
|
268
|
+
"""
|
|
269
|
+
# NOTE: Here we capture 'label.pad' rc argument normally used for
|
|
270
|
+
# x and y axis labels as shorthand for 'tick.labelpad'.
|
|
271
|
+
rc_kw, rc_mode = _pop_rc(kwargs)
|
|
272
|
+
labelcolor = _not_none(labelcolor, kwargs.get("color", None))
|
|
273
|
+
with rc.context(rc_kw, mode=rc_mode):
|
|
274
|
+
# Not mutable default args
|
|
275
|
+
thetalocator_kw = thetalocator_kw or {}
|
|
276
|
+
thetaminorlocator_kw = thetaminorlocator_kw or {}
|
|
277
|
+
thetaformatter_kw = thetaformatter_kw or {}
|
|
278
|
+
rlocator_kw = rlocator_kw or {}
|
|
279
|
+
rminorlocator_kw = rminorlocator_kw or {}
|
|
280
|
+
rformatter_kw = rformatter_kw or {}
|
|
281
|
+
|
|
282
|
+
# Flexible input
|
|
283
|
+
thetalocator = _not_none(thetalines=thetalines, thetalocator=thetalocator)
|
|
284
|
+
thetaformatter = _not_none(
|
|
285
|
+
thetalabels=thetalabels, thetaformatter=thetaformatter
|
|
286
|
+
) # noqa: E501
|
|
287
|
+
thetaminorlocator = _not_none(
|
|
288
|
+
thetaminorlines=thetaminorlines, thetaminorlocator=thetaminorlocator
|
|
289
|
+
) # noqa: E501
|
|
290
|
+
rlocator = _not_none(rlines=rlines, rlocator=rlocator)
|
|
291
|
+
rformatter = _not_none(rlabels=rlabels, rformatter=rformatter)
|
|
292
|
+
rminorlocator = _not_none(
|
|
293
|
+
rminorlines=rminorlines, rminorlocator=rminorlocator
|
|
294
|
+
) # noqa: E501
|
|
295
|
+
|
|
296
|
+
# Special radius settings
|
|
297
|
+
if r0 is not None:
|
|
298
|
+
self.set_rorigin(r0)
|
|
299
|
+
if rlabelpos is not None:
|
|
300
|
+
self.set_rlabel_position(rlabelpos)
|
|
301
|
+
if rscale is not None:
|
|
302
|
+
self.set_rscale(rscale)
|
|
303
|
+
if rborder is not None:
|
|
304
|
+
self.spines["polar"].set_visible(bool(rborder))
|
|
305
|
+
|
|
306
|
+
# Special azimuth settings
|
|
307
|
+
if theta0 is not None:
|
|
308
|
+
self.set_theta_zero_location(theta0)
|
|
309
|
+
if thetadir is not None:
|
|
310
|
+
self.set_theta_direction(thetadir)
|
|
311
|
+
|
|
312
|
+
# Loop over axes
|
|
313
|
+
for (
|
|
314
|
+
x,
|
|
315
|
+
min_,
|
|
316
|
+
max_,
|
|
317
|
+
lim,
|
|
318
|
+
grid,
|
|
319
|
+
gridminor,
|
|
320
|
+
gridcolor,
|
|
321
|
+
locator,
|
|
322
|
+
locator_kw,
|
|
323
|
+
formatter,
|
|
324
|
+
formatter_kw,
|
|
325
|
+
minorlocator,
|
|
326
|
+
minorlocator_kw,
|
|
327
|
+
) in zip(
|
|
328
|
+
("x", "y"),
|
|
329
|
+
(thetamin, rmin),
|
|
330
|
+
(thetamax, rmax),
|
|
331
|
+
(thetalim, rlim),
|
|
332
|
+
(thetagrid, rgrid),
|
|
333
|
+
(thetagridminor, rgridminor),
|
|
334
|
+
(thetagridcolor, rgridcolor),
|
|
335
|
+
(thetalocator, rlocator),
|
|
336
|
+
(thetalocator_kw, rlocator_kw),
|
|
337
|
+
(thetaformatter, rformatter),
|
|
338
|
+
(thetaformatter_kw, rformatter_kw),
|
|
339
|
+
(thetaminorlocator, rminorlocator),
|
|
340
|
+
(thetaminorlocator_kw, rminorlocator_kw),
|
|
341
|
+
):
|
|
342
|
+
# Axis limits
|
|
343
|
+
self._update_limits(x, min_=min_, max_=max_, lim=lim)
|
|
344
|
+
|
|
345
|
+
# Axis tick settings
|
|
346
|
+
# NOTE: Here use 'grid.labelpad' instead of 'tick.labelpad'. Default
|
|
347
|
+
# offset for grid labels is larger than for tick labels.
|
|
348
|
+
self._update_ticks(
|
|
349
|
+
x,
|
|
350
|
+
grid=grid,
|
|
351
|
+
gridminor=gridminor,
|
|
352
|
+
gridcolor=gridcolor,
|
|
353
|
+
gridpad=True,
|
|
354
|
+
labelpad=labelpad,
|
|
355
|
+
labelcolor=labelcolor,
|
|
356
|
+
labelsize=labelsize,
|
|
357
|
+
labelweight=labelweight,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
# Axis locator
|
|
361
|
+
self._update_locators(
|
|
362
|
+
x,
|
|
363
|
+
locator=locator,
|
|
364
|
+
locator_kw=locator_kw,
|
|
365
|
+
minorlocator=minorlocator,
|
|
366
|
+
minorlocator_kw=minorlocator_kw,
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
# Axis formatter
|
|
370
|
+
self._update_formatter(
|
|
371
|
+
x, formatter=formatter, formatter_kw=formatter_kw
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
# Parent format method
|
|
375
|
+
super().format(rc_kw=rc_kw, rc_mode=rc_mode, **kwargs)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
# Apply signature obfuscation after storing previous signature
|
|
379
|
+
# NOTE: This is needed for __init__
|
|
380
|
+
PolarAxes._format_signatures[PolarAxes] = inspect.signature(PolarAxes.format)
|
|
381
|
+
PolarAxes.format = docstring._obfuscate_kwargs(PolarAxes.format)
|
ultraplot/axes/shared.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
An axes used to jointly format Cartesian and polar axes.
|
|
4
|
+
"""
|
|
5
|
+
# NOTE: We could define these in base.py but idea is projection-specific formatters
|
|
6
|
+
# should never be defined on the base class. Might add to this class later anyway.
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ..config import rc
|
|
10
|
+
from ..internals import ic # noqa: F401
|
|
11
|
+
from ..internals import _pop_kwargs
|
|
12
|
+
from ..utils import _fontsize_to_pt, _not_none, units
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _SharedAxes(object):
|
|
16
|
+
"""
|
|
17
|
+
Mix-in class with methods shared between `~ultraplot.axes.CartesianAxes`
|
|
18
|
+
and `~ultraplot.axes.PolarAxes`.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _min_max_lim(key, min_=None, max_=None, lim=None):
|
|
23
|
+
"""
|
|
24
|
+
Translate and standardize minimum, maximum, and limit keyword arguments.
|
|
25
|
+
"""
|
|
26
|
+
if lim is None:
|
|
27
|
+
lim = (None, None)
|
|
28
|
+
if not np.iterable(lim) or not len(lim) == 2:
|
|
29
|
+
raise ValueError(f"Invalid {key}{lim!r}. Must be 2-tuple of values.")
|
|
30
|
+
min_ = _not_none(**{f"{key}min": min_, f"{key}lim_0": lim[0]})
|
|
31
|
+
max_ = _not_none(**{f"{key}max": max_, f"{key}lim_1": lim[1]})
|
|
32
|
+
return min_, max_
|
|
33
|
+
|
|
34
|
+
def _update_background(self, x=None, tickwidth=None, tickwidthratio=None, **kwargs):
|
|
35
|
+
"""
|
|
36
|
+
Update the background patch and spines.
|
|
37
|
+
"""
|
|
38
|
+
# Update the background patch
|
|
39
|
+
kw_face, kw_edge = rc._get_background_props(**kwargs)
|
|
40
|
+
self.patch.update(kw_face)
|
|
41
|
+
if x is None:
|
|
42
|
+
opts = self.spines
|
|
43
|
+
elif x == "x":
|
|
44
|
+
opts = ("bottom", "top", "inner", "polar")
|
|
45
|
+
else:
|
|
46
|
+
opts = ("left", "right", "start", "end")
|
|
47
|
+
for opt in opts:
|
|
48
|
+
self.spines.get(opt, {}).update(kw_edge)
|
|
49
|
+
|
|
50
|
+
# Update the tick colors
|
|
51
|
+
axis = "both" if x is None else x
|
|
52
|
+
x = _not_none(x, "x")
|
|
53
|
+
obj = getattr(self, x + "axis")
|
|
54
|
+
edgecolor = kw_edge.get("edgecolor", None)
|
|
55
|
+
if edgecolor is not None:
|
|
56
|
+
self.tick_params(axis=axis, which="both", color=edgecolor)
|
|
57
|
+
|
|
58
|
+
# Update the tick widths
|
|
59
|
+
# NOTE: Only use 'linewidth' if it was explicitly passed. Do not
|
|
60
|
+
# include 'linewidth' inferred from rc['axes.linewidth'] setting.
|
|
61
|
+
kwmajor = getattr(obj, "_major_tick_kw", {}) # graceful fallback if API changes
|
|
62
|
+
kwminor = getattr(obj, "_minor_tick_kw", {})
|
|
63
|
+
if "linewidth" in kwargs:
|
|
64
|
+
tickwidth = _not_none(tickwidth, kwargs["linewidth"])
|
|
65
|
+
tickwidth = _not_none(tickwidth, rc.find("tick.width", context=True))
|
|
66
|
+
tickwidthratio = _not_none(
|
|
67
|
+
tickwidthratio, rc.find("tick.widthratio", context=True)
|
|
68
|
+
) # noqa: E501
|
|
69
|
+
tickwidth_prev = kwmajor.get("width", rc[x + "tick.major.width"])
|
|
70
|
+
if tickwidth_prev == 0:
|
|
71
|
+
tickwidthratio_prev = rc["tick.widthratio"] # no other way of knowing
|
|
72
|
+
else:
|
|
73
|
+
tickwidthratio_prev = (
|
|
74
|
+
kwminor.get("width", rc[x + "tick.minor.width"]) / tickwidth_prev
|
|
75
|
+
) # noqa: E501
|
|
76
|
+
for which in ("major", "minor"):
|
|
77
|
+
kwticks = {}
|
|
78
|
+
if tickwidth is not None or tickwidthratio is not None:
|
|
79
|
+
tickwidth = _not_none(tickwidth, tickwidth_prev)
|
|
80
|
+
kwticks["width"] = tickwidth = units(tickwidth, "pt")
|
|
81
|
+
if tickwidth == 0: # avoid unnecessary padding
|
|
82
|
+
kwticks["size"] = 0
|
|
83
|
+
elif which == "minor":
|
|
84
|
+
tickwidthratio = _not_none(tickwidthratio, tickwidthratio_prev)
|
|
85
|
+
kwticks["width"] *= tickwidthratio
|
|
86
|
+
self.tick_params(axis=axis, which=which, **kwticks)
|
|
87
|
+
|
|
88
|
+
def _update_ticks(
|
|
89
|
+
self,
|
|
90
|
+
x,
|
|
91
|
+
*,
|
|
92
|
+
grid=None,
|
|
93
|
+
gridminor=None,
|
|
94
|
+
gridpad=None,
|
|
95
|
+
gridcolor=None,
|
|
96
|
+
ticklen=None,
|
|
97
|
+
ticklenratio=None,
|
|
98
|
+
tickdir=None,
|
|
99
|
+
tickcolor=None,
|
|
100
|
+
labeldir=None,
|
|
101
|
+
labelpad=None,
|
|
102
|
+
labelcolor=None,
|
|
103
|
+
labelsize=None,
|
|
104
|
+
labelweight=None,
|
|
105
|
+
):
|
|
106
|
+
"""
|
|
107
|
+
Update the gridlines and labels. Set `gridpad` to ``True`` to use grid padding.
|
|
108
|
+
"""
|
|
109
|
+
# Filter out text properties
|
|
110
|
+
axis = "both" if x is None else x
|
|
111
|
+
kwtext = rc._get_ticklabel_props(axis)
|
|
112
|
+
kwtext_extra = _pop_kwargs(kwtext, "weight", "family")
|
|
113
|
+
kwtext = {"label" + key: value for key, value in kwtext.items()}
|
|
114
|
+
if labelcolor is not None:
|
|
115
|
+
kwtext["labelcolor"] = labelcolor
|
|
116
|
+
if labelsize is not None:
|
|
117
|
+
kwtext["labelsize"] = labelsize
|
|
118
|
+
if labelweight is not None:
|
|
119
|
+
kwtext_extra["weight"] = labelweight
|
|
120
|
+
|
|
121
|
+
# Apply tick settings with tick_params when possible
|
|
122
|
+
x = _not_none(x, "x")
|
|
123
|
+
obj = getattr(self, x + "axis")
|
|
124
|
+
kwmajor = getattr(obj, "_major_tick_kw", {}) # graceful fallback if API changes
|
|
125
|
+
kwminor = getattr(obj, "_minor_tick_kw", {})
|
|
126
|
+
ticklen_prev = kwmajor.get("size", rc[x + "tick.major.size"])
|
|
127
|
+
if ticklen_prev == 0:
|
|
128
|
+
ticklenratio_prev = rc["tick.lenratio"] # no other way of knowing
|
|
129
|
+
else:
|
|
130
|
+
ticklenratio_prev = (
|
|
131
|
+
kwminor.get("size", rc[x + "tick.minor.size"]) / ticklen_prev
|
|
132
|
+
) # noqa: E501
|
|
133
|
+
for b, which in zip((grid, gridminor), ("major", "minor")):
|
|
134
|
+
# Tick properties
|
|
135
|
+
# NOTE: Must make 'tickcolor' overwrite 'labelcolor' or else 'color'
|
|
136
|
+
# passed to __init__ will not apply correctly. Annoying but unavoidable
|
|
137
|
+
kwticks = rc._get_tickline_props(axis, which=which)
|
|
138
|
+
if labelpad is not None:
|
|
139
|
+
kwticks["pad"] = labelpad
|
|
140
|
+
if tickcolor is not None:
|
|
141
|
+
kwticks["color"] = tickcolor
|
|
142
|
+
if ticklen is not None or ticklenratio is not None:
|
|
143
|
+
ticklen = _not_none(ticklen, ticklen_prev)
|
|
144
|
+
kwticks["size"] = ticklen = units(ticklen, "pt")
|
|
145
|
+
if ticklen > 0 and which == "minor":
|
|
146
|
+
ticklenratio = _not_none(ticklenratio, ticklenratio_prev)
|
|
147
|
+
kwticks["size"] *= ticklenratio
|
|
148
|
+
if gridpad: # use grid.labelpad instead of tick.labelpad
|
|
149
|
+
kwticks.pop("pad", None)
|
|
150
|
+
pad = rc.find("grid.labelpad", context=True)
|
|
151
|
+
if pad is not None:
|
|
152
|
+
kwticks["pad"] = units(pad, "pt")
|
|
153
|
+
|
|
154
|
+
# Tick direction properties
|
|
155
|
+
# NOTE: These have no x and y-specific versions but apply here anyway
|
|
156
|
+
if labeldir == "in": # put tick labels inside the plot
|
|
157
|
+
tickdir = "in"
|
|
158
|
+
kwticks.setdefault(
|
|
159
|
+
"pad",
|
|
160
|
+
-rc[f"{axis}tick.major.size"]
|
|
161
|
+
- _not_none(labelpad, rc[f"{axis}tick.major.pad"])
|
|
162
|
+
- _fontsize_to_pt(rc[f"{axis}tick.labelsize"]),
|
|
163
|
+
)
|
|
164
|
+
if tickdir is not None:
|
|
165
|
+
kwticks["direction"] = tickdir
|
|
166
|
+
|
|
167
|
+
# Gridline properties
|
|
168
|
+
# NOTE: Internally ax.grid() passes gridOn to ax.tick_params() but this
|
|
169
|
+
# is undocumented and might have weird side effects. Just use ax.grid()
|
|
170
|
+
b = rc._get_gridline_bool(b, axis=axis, which=which)
|
|
171
|
+
if b is not None:
|
|
172
|
+
self.grid(b, axis=axis, which=which)
|
|
173
|
+
kwlines = rc._get_gridline_props(which=which)
|
|
174
|
+
if "axisbelow" in kwlines:
|
|
175
|
+
self.set_axisbelow(kwlines.pop("axisbelow"))
|
|
176
|
+
if gridcolor is not None:
|
|
177
|
+
kwlines["grid_color"] = gridcolor
|
|
178
|
+
|
|
179
|
+
# Apply tick and gridline properties
|
|
180
|
+
kwticks.pop("ndivs", None) # not in mpl
|
|
181
|
+
self.tick_params(axis=axis, which=which, **kwticks, **kwlines, **kwtext)
|
|
182
|
+
|
|
183
|
+
# Apply settings that can't be controlled with tick_params
|
|
184
|
+
if kwtext_extra:
|
|
185
|
+
for lab in obj.get_ticklabels():
|
|
186
|
+
lab.update(kwtext_extra)
|
ultraplot/axes/three.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
The "3D" axes class.
|
|
4
|
+
"""
|
|
5
|
+
from . import base, shared
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
9
|
+
except ImportError:
|
|
10
|
+
Axes3D = object
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ThreeAxes(shared._SharedAxes, base.Axes, Axes3D):
|
|
14
|
+
"""
|
|
15
|
+
Simple mix-in of `ultraplot.axes.Axes` with `~mpl_toolkits.mplot3d.axes3d.Axes3D`.
|
|
16
|
+
|
|
17
|
+
Important
|
|
18
|
+
---------
|
|
19
|
+
Note that this subclass does *not* implement the `~ultraplot.axes.PlotAxes`
|
|
20
|
+
plotting overrides. This axes subclass can be used by passing ``proj='3d'`` or
|
|
21
|
+
``proj='three'`` to axes-creation commands like `~ultraplot.figure.Figure.add_axes`,
|
|
22
|
+
`~ultraplot.figure.Figure.add_subplot`, and `~ultraplot.figure.Figure.subplots`.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# TODO: Figure out a way to have internal Axes3D calls to plotting commands
|
|
26
|
+
# access the overrides rather than the originals? May be impossible.
|
|
27
|
+
_name = "three"
|
|
28
|
+
_name_aliases = ("3d",)
|
|
29
|
+
|
|
30
|
+
def __init__(self, *args, **kwargs):
|
|
31
|
+
import mpl_toolkits.mplot3d # noqa: F401 verify package is available
|
|
32
|
+
|
|
33
|
+
kwargs.setdefault("alpha", 0.0)
|
|
34
|
+
super().__init__(*args, **kwargs)
|