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/demos.py
ADDED
|
@@ -0,0 +1,1201 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Functions for displaying colors and fonts.
|
|
4
|
+
"""
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
import cycler
|
|
9
|
+
import matplotlib.colors as mcolors
|
|
10
|
+
import matplotlib.font_manager as mfonts
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
from . import colors as pcolors
|
|
14
|
+
from . import constructor, ui
|
|
15
|
+
from .config import _get_data_folders, rc
|
|
16
|
+
from .internals import ic # noqa: F401
|
|
17
|
+
from .internals import _not_none, _version_mpl, docstring, warnings
|
|
18
|
+
from .utils import to_rgb, to_xyz
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"show_cmaps",
|
|
22
|
+
"show_channels",
|
|
23
|
+
"show_colors",
|
|
24
|
+
"show_colorspaces",
|
|
25
|
+
"show_cycles",
|
|
26
|
+
"show_fonts",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Tables and constants
|
|
31
|
+
FAMILY_TEXGYRE = (
|
|
32
|
+
"TeX Gyre Heros", # sans-serif
|
|
33
|
+
"TeX Gyre Schola", # serif
|
|
34
|
+
"TeX Gyre Bonum",
|
|
35
|
+
"TeX Gyre Termes",
|
|
36
|
+
"TeX Gyre Pagella",
|
|
37
|
+
"TeX Gyre Chorus", # cursive
|
|
38
|
+
"TeX Gyre Adventor", # fantasy
|
|
39
|
+
"TeX Gyre Cursor", # monospace
|
|
40
|
+
)
|
|
41
|
+
COLOR_TABLE = {
|
|
42
|
+
# NOTE: Just want the names but point to the dictionaries because
|
|
43
|
+
# they don't get filled until after __init__ imports this module.
|
|
44
|
+
"base": mcolors.BASE_COLORS,
|
|
45
|
+
"css4": mcolors.CSS4_COLORS,
|
|
46
|
+
"opencolor": pcolors.COLORS_OPEN,
|
|
47
|
+
"xkcd": pcolors.COLORS_XKCD,
|
|
48
|
+
}
|
|
49
|
+
CYCLE_TABLE = {
|
|
50
|
+
"Matplotlib defaults": (
|
|
51
|
+
"default",
|
|
52
|
+
"classic",
|
|
53
|
+
),
|
|
54
|
+
"Matplotlib stylesheets": (
|
|
55
|
+
# NOTE: Do not include 'solarized' because colors are terrible for
|
|
56
|
+
# colorblind folks.
|
|
57
|
+
"colorblind",
|
|
58
|
+
"colorblind10",
|
|
59
|
+
"tableau",
|
|
60
|
+
"ggplot",
|
|
61
|
+
"538",
|
|
62
|
+
"seaborn",
|
|
63
|
+
"bmh",
|
|
64
|
+
),
|
|
65
|
+
"ColorBrewer2.0 qualitative": (
|
|
66
|
+
"Accent",
|
|
67
|
+
"Dark2",
|
|
68
|
+
"Paired",
|
|
69
|
+
"Pastel1",
|
|
70
|
+
"Pastel2",
|
|
71
|
+
"Set1",
|
|
72
|
+
"Set2",
|
|
73
|
+
"Set3",
|
|
74
|
+
"tab10",
|
|
75
|
+
"tab20",
|
|
76
|
+
"tab20b",
|
|
77
|
+
"tab20c",
|
|
78
|
+
),
|
|
79
|
+
"Other qualitative": (
|
|
80
|
+
"FlatUI",
|
|
81
|
+
"Qual1",
|
|
82
|
+
"Qual2",
|
|
83
|
+
),
|
|
84
|
+
}
|
|
85
|
+
CMAP_TABLE = {
|
|
86
|
+
# NOTE: No longer rename colorbrewer greys map, just redirect 'grays'
|
|
87
|
+
# to 'greys' in colormap database.
|
|
88
|
+
"Grayscale": ( # assorted origin, but they belong together
|
|
89
|
+
"Greys",
|
|
90
|
+
"Mono",
|
|
91
|
+
"MonoCycle",
|
|
92
|
+
),
|
|
93
|
+
"Matplotlib sequential": (
|
|
94
|
+
"viridis",
|
|
95
|
+
"plasma",
|
|
96
|
+
"inferno",
|
|
97
|
+
"magma",
|
|
98
|
+
"cividis",
|
|
99
|
+
),
|
|
100
|
+
"Matplotlib cyclic": ("twilight",),
|
|
101
|
+
"Seaborn sequential": (
|
|
102
|
+
"Rocket",
|
|
103
|
+
"Flare",
|
|
104
|
+
"Mako",
|
|
105
|
+
"Crest",
|
|
106
|
+
),
|
|
107
|
+
"Seaborn diverging": (
|
|
108
|
+
"IceFire",
|
|
109
|
+
"Vlag",
|
|
110
|
+
),
|
|
111
|
+
"ultraplot sequential": (
|
|
112
|
+
"Fire",
|
|
113
|
+
"Stellar",
|
|
114
|
+
"Glacial",
|
|
115
|
+
"Dusk",
|
|
116
|
+
"Marine",
|
|
117
|
+
"Boreal",
|
|
118
|
+
"Sunrise",
|
|
119
|
+
"Sunset",
|
|
120
|
+
),
|
|
121
|
+
"ultraplot diverging": (
|
|
122
|
+
"Div",
|
|
123
|
+
"NegPos",
|
|
124
|
+
"DryWet",
|
|
125
|
+
),
|
|
126
|
+
"Other sequential": ("cubehelix", "turbo"),
|
|
127
|
+
"Other diverging": (
|
|
128
|
+
"BR",
|
|
129
|
+
"ColdHot",
|
|
130
|
+
"CoolWarm",
|
|
131
|
+
),
|
|
132
|
+
"cmOcean sequential": (
|
|
133
|
+
"Oxy",
|
|
134
|
+
"Thermal",
|
|
135
|
+
"Dense",
|
|
136
|
+
"Ice",
|
|
137
|
+
"Haline",
|
|
138
|
+
"Deep",
|
|
139
|
+
"Algae",
|
|
140
|
+
"Tempo",
|
|
141
|
+
"Speed",
|
|
142
|
+
"Turbid",
|
|
143
|
+
"Solar",
|
|
144
|
+
"Matter",
|
|
145
|
+
"Amp",
|
|
146
|
+
),
|
|
147
|
+
"cmOcean diverging": (
|
|
148
|
+
"Balance",
|
|
149
|
+
"Delta",
|
|
150
|
+
"Curl",
|
|
151
|
+
),
|
|
152
|
+
"cmOcean cyclic": ("Phase",),
|
|
153
|
+
"Scientific colour maps sequential": (
|
|
154
|
+
"batlow",
|
|
155
|
+
"batlowK",
|
|
156
|
+
"batlowW",
|
|
157
|
+
"devon",
|
|
158
|
+
"davos",
|
|
159
|
+
"oslo",
|
|
160
|
+
"lapaz",
|
|
161
|
+
"acton",
|
|
162
|
+
"lajolla",
|
|
163
|
+
"bilbao",
|
|
164
|
+
"tokyo",
|
|
165
|
+
"turku",
|
|
166
|
+
"bamako",
|
|
167
|
+
"nuuk",
|
|
168
|
+
"hawaii",
|
|
169
|
+
"buda",
|
|
170
|
+
"imola",
|
|
171
|
+
"oleron",
|
|
172
|
+
"bukavu",
|
|
173
|
+
"fes",
|
|
174
|
+
),
|
|
175
|
+
"Scientific colour maps diverging": (
|
|
176
|
+
"roma",
|
|
177
|
+
"broc",
|
|
178
|
+
"cork",
|
|
179
|
+
"vik",
|
|
180
|
+
"bam",
|
|
181
|
+
"lisbon",
|
|
182
|
+
"tofino",
|
|
183
|
+
"berlin",
|
|
184
|
+
"vanimo",
|
|
185
|
+
),
|
|
186
|
+
"Scientific colour maps cyclic": (
|
|
187
|
+
"romaO",
|
|
188
|
+
"brocO",
|
|
189
|
+
"corkO",
|
|
190
|
+
"vikO",
|
|
191
|
+
"bamO",
|
|
192
|
+
),
|
|
193
|
+
"ColorBrewer2.0 sequential": (
|
|
194
|
+
"Purples",
|
|
195
|
+
"Blues",
|
|
196
|
+
"Greens",
|
|
197
|
+
"Oranges",
|
|
198
|
+
"Reds",
|
|
199
|
+
"YlOrBr",
|
|
200
|
+
"YlOrRd",
|
|
201
|
+
"OrRd",
|
|
202
|
+
"PuRd",
|
|
203
|
+
"RdPu",
|
|
204
|
+
"BuPu",
|
|
205
|
+
"PuBu",
|
|
206
|
+
"PuBuGn",
|
|
207
|
+
"BuGn",
|
|
208
|
+
"GnBu",
|
|
209
|
+
"YlGnBu",
|
|
210
|
+
"YlGn",
|
|
211
|
+
),
|
|
212
|
+
"ColorBrewer2.0 diverging": (
|
|
213
|
+
"Spectral",
|
|
214
|
+
"PiYG",
|
|
215
|
+
"PRGn",
|
|
216
|
+
"BrBG",
|
|
217
|
+
"PuOr",
|
|
218
|
+
"RdGY",
|
|
219
|
+
"RdBu",
|
|
220
|
+
"RdYlBu",
|
|
221
|
+
"RdYlGn",
|
|
222
|
+
),
|
|
223
|
+
"SciVisColor blues": (
|
|
224
|
+
"Blues1",
|
|
225
|
+
"Blues2",
|
|
226
|
+
"Blues3",
|
|
227
|
+
"Blues4",
|
|
228
|
+
"Blues5",
|
|
229
|
+
"Blues6",
|
|
230
|
+
"Blues7",
|
|
231
|
+
"Blues8",
|
|
232
|
+
"Blues9",
|
|
233
|
+
"Blues10",
|
|
234
|
+
"Blues11",
|
|
235
|
+
),
|
|
236
|
+
"SciVisColor greens": (
|
|
237
|
+
"Greens1",
|
|
238
|
+
"Greens2",
|
|
239
|
+
"Greens3",
|
|
240
|
+
"Greens4",
|
|
241
|
+
"Greens5",
|
|
242
|
+
"Greens6",
|
|
243
|
+
"Greens7",
|
|
244
|
+
"Greens8",
|
|
245
|
+
),
|
|
246
|
+
"SciVisColor yellows": (
|
|
247
|
+
"Yellows1",
|
|
248
|
+
"Yellows2",
|
|
249
|
+
"Yellows3",
|
|
250
|
+
"Yellows4",
|
|
251
|
+
),
|
|
252
|
+
"SciVisColor oranges": (
|
|
253
|
+
"Oranges1",
|
|
254
|
+
"Oranges2",
|
|
255
|
+
"Oranges3",
|
|
256
|
+
"Oranges4",
|
|
257
|
+
),
|
|
258
|
+
"SciVisColor browns": (
|
|
259
|
+
"Browns1",
|
|
260
|
+
"Browns2",
|
|
261
|
+
"Browns3",
|
|
262
|
+
"Browns4",
|
|
263
|
+
"Browns5",
|
|
264
|
+
"Browns6",
|
|
265
|
+
"Browns7",
|
|
266
|
+
"Browns8",
|
|
267
|
+
"Browns9",
|
|
268
|
+
),
|
|
269
|
+
"SciVisColor reds": (
|
|
270
|
+
"Reds1",
|
|
271
|
+
"Reds2",
|
|
272
|
+
"Reds3",
|
|
273
|
+
"Reds4",
|
|
274
|
+
"Reds5",
|
|
275
|
+
),
|
|
276
|
+
"SciVisColor purples": (
|
|
277
|
+
"Purples1",
|
|
278
|
+
"Purples2",
|
|
279
|
+
"Purples3",
|
|
280
|
+
),
|
|
281
|
+
# Builtin colormaps that re hidden by default. Some are really bad, some
|
|
282
|
+
# are segmented maps that should be cycles, and some are just uninspiring.
|
|
283
|
+
"MATLAB": (
|
|
284
|
+
"bone",
|
|
285
|
+
"cool",
|
|
286
|
+
"copper",
|
|
287
|
+
"autumn",
|
|
288
|
+
"flag",
|
|
289
|
+
"prism",
|
|
290
|
+
"jet",
|
|
291
|
+
"hsv",
|
|
292
|
+
"hot",
|
|
293
|
+
"spring",
|
|
294
|
+
"summer",
|
|
295
|
+
"winter",
|
|
296
|
+
"pink",
|
|
297
|
+
"gray",
|
|
298
|
+
),
|
|
299
|
+
"GNUplot": (
|
|
300
|
+
"gnuplot",
|
|
301
|
+
"gnuplot2",
|
|
302
|
+
"ocean",
|
|
303
|
+
"afmhot",
|
|
304
|
+
"rainbow",
|
|
305
|
+
),
|
|
306
|
+
"GIST": (
|
|
307
|
+
"gist_earth",
|
|
308
|
+
"gist_gray",
|
|
309
|
+
"gist_heat",
|
|
310
|
+
"gist_ncar",
|
|
311
|
+
"gist_rainbow",
|
|
312
|
+
"gist_stern",
|
|
313
|
+
"gist_yarg",
|
|
314
|
+
),
|
|
315
|
+
"Other": (
|
|
316
|
+
"binary",
|
|
317
|
+
"bwr",
|
|
318
|
+
"brg", # appear to be custom matplotlib
|
|
319
|
+
"Wistia",
|
|
320
|
+
"CMRmap", # individually released
|
|
321
|
+
"seismic",
|
|
322
|
+
"terrain",
|
|
323
|
+
"nipy_spectral", # origin ambiguous
|
|
324
|
+
"tab10",
|
|
325
|
+
"tab20",
|
|
326
|
+
"tab20b",
|
|
327
|
+
"tab20c", # merged colormap cycles
|
|
328
|
+
),
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
# Docstring snippets
|
|
332
|
+
_colorbar_docstring = """
|
|
333
|
+
length : unit-spec, optional
|
|
334
|
+
The length of each colorbar.
|
|
335
|
+
%(units.in)s
|
|
336
|
+
width : float or str, optional
|
|
337
|
+
The width of each colorbar.
|
|
338
|
+
%(units.in)s
|
|
339
|
+
rasterized : bool, default: :rc:`colorbar.rasterized`
|
|
340
|
+
Whether to rasterize the colorbar solids. This increases rendering
|
|
341
|
+
time and decreases file sizes for vector graphics.
|
|
342
|
+
"""
|
|
343
|
+
docstring._snippet_manager["demos.cmaps"] = ", ".join(f"``{s!r}``" for s in CMAP_TABLE)
|
|
344
|
+
docstring._snippet_manager["demos.cycles"] = ", ".join(
|
|
345
|
+
f"``{s!r}``" for s in CYCLE_TABLE
|
|
346
|
+
) # noqa: E501
|
|
347
|
+
docstring._snippet_manager["demos.colors"] = ", ".join(
|
|
348
|
+
f"``{s!r}``" for s in COLOR_TABLE
|
|
349
|
+
) # noqa: E501
|
|
350
|
+
docstring._snippet_manager["demos.colorbar"] = _colorbar_docstring
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def show_channels(
|
|
354
|
+
*args,
|
|
355
|
+
N=100,
|
|
356
|
+
rgb=False,
|
|
357
|
+
saturation=True,
|
|
358
|
+
minhue=0,
|
|
359
|
+
maxsat=500,
|
|
360
|
+
width=100,
|
|
361
|
+
refwidth=1.7,
|
|
362
|
+
):
|
|
363
|
+
"""
|
|
364
|
+
Show how arbitrary colormap(s) vary with respect to the hue, chroma,
|
|
365
|
+
luminance, HSL saturation, and HPL saturation channels, and optionally
|
|
366
|
+
the red, blue and green channels. Adapted from `this example \
|
|
367
|
+
<https://matplotlib.org/stable/tutorials/colors/colormaps.html#lightness-of-matplotlib-colormaps>`__.
|
|
368
|
+
|
|
369
|
+
Parameters
|
|
370
|
+
----------
|
|
371
|
+
*args : colormap-spec, default: :rc:`image.cmap`
|
|
372
|
+
Positional arguments are colormap names or objects.
|
|
373
|
+
N : int, optional
|
|
374
|
+
The number of markers to draw for each colormap.
|
|
375
|
+
rgb : bool, optional
|
|
376
|
+
Whether to also show the red, green, and blue channels in the bottom row.
|
|
377
|
+
saturation : bool, optional
|
|
378
|
+
Whether to show the HSL and HPL saturation channels alongside the raw chroma.
|
|
379
|
+
minhue : float, optional
|
|
380
|
+
The minimum hue. This lets you rotate the hue plot cyclically.
|
|
381
|
+
maxsat : float, optional
|
|
382
|
+
The maximum saturation. Use this to truncate large saturation values.
|
|
383
|
+
width : int, optional
|
|
384
|
+
The width of each colormap line in points.
|
|
385
|
+
refwidth : int or str, optional
|
|
386
|
+
The width of each subplot. Passed to `~ultraplot.ui.subplots`.
|
|
387
|
+
|
|
388
|
+
Returns
|
|
389
|
+
-------
|
|
390
|
+
ultraplot.figure.Figure
|
|
391
|
+
The figure.
|
|
392
|
+
ultraplot.gridspec.SubplotGrid
|
|
393
|
+
The subplot grid.
|
|
394
|
+
|
|
395
|
+
See also
|
|
396
|
+
--------
|
|
397
|
+
show_cmaps
|
|
398
|
+
show_colorspaces
|
|
399
|
+
"""
|
|
400
|
+
# Figure and plot
|
|
401
|
+
if not args:
|
|
402
|
+
raise ValueError("At least one positional argument required.")
|
|
403
|
+
array = [[1, 1, 2, 2, 3, 3]]
|
|
404
|
+
labels = ("Hue", "Chroma", "Luminance")
|
|
405
|
+
if saturation:
|
|
406
|
+
array += [[0, 4, 4, 5, 5, 0]]
|
|
407
|
+
labels += ("HSL saturation", "HPL saturation")
|
|
408
|
+
if rgb:
|
|
409
|
+
array += [np.array([4, 4, 5, 5, 6, 6]) + 2 * int(saturation)]
|
|
410
|
+
labels += ("Red", "Green", "Blue")
|
|
411
|
+
fig, axs = ui.subplots(
|
|
412
|
+
array=array,
|
|
413
|
+
refwidth=refwidth,
|
|
414
|
+
wratios=(1.5, 1, 1, 1, 1, 1.5),
|
|
415
|
+
share="labels",
|
|
416
|
+
span=False,
|
|
417
|
+
innerpad=1,
|
|
418
|
+
)
|
|
419
|
+
# Iterate through colormaps
|
|
420
|
+
mc = ms = mp = 0
|
|
421
|
+
cmaps = []
|
|
422
|
+
for cmap in args:
|
|
423
|
+
# Get colormap and avoid registering new names
|
|
424
|
+
name = cmap if isinstance(cmap, str) else getattr(cmap, "name", None)
|
|
425
|
+
cmap = constructor.Colormap(cmap, N=N) # arbitrary cmap argument
|
|
426
|
+
if name is not None:
|
|
427
|
+
cmap.name = name
|
|
428
|
+
cmap._init()
|
|
429
|
+
cmaps.append(cmap)
|
|
430
|
+
|
|
431
|
+
# Get clipped RGB table
|
|
432
|
+
x = np.linspace(0, 1, N)
|
|
433
|
+
lut = cmap._lut[:-3, :3].copy()
|
|
434
|
+
rgb_data = lut.T # 3 by N
|
|
435
|
+
hcl_data = np.array([to_xyz(color, space="hcl") for color in lut]).T # 3 by N
|
|
436
|
+
hsl_data = [to_xyz(color, space="hsl")[1] for color in lut]
|
|
437
|
+
hpl_data = [to_xyz(color, space="hpl")[1] for color in lut]
|
|
438
|
+
|
|
439
|
+
# Plot channels
|
|
440
|
+
# If rgb is False, the zip will just truncate the other iterables
|
|
441
|
+
data = tuple(hcl_data)
|
|
442
|
+
if saturation:
|
|
443
|
+
data += (hsl_data, hpl_data)
|
|
444
|
+
if rgb:
|
|
445
|
+
data += tuple(rgb_data)
|
|
446
|
+
for ax, y, label in zip(axs, data, labels):
|
|
447
|
+
ylim, ylocator = None, None
|
|
448
|
+
if label in ("Red", "Green", "Blue"):
|
|
449
|
+
ylim = (0, 1)
|
|
450
|
+
ylocator = 0.2
|
|
451
|
+
elif label == "Luminance":
|
|
452
|
+
ylim = (0, 100)
|
|
453
|
+
ylocator = 20
|
|
454
|
+
elif label == "Hue":
|
|
455
|
+
ylim = (minhue, minhue + 360)
|
|
456
|
+
ylocator = 90
|
|
457
|
+
y = y - 720
|
|
458
|
+
for _ in range(3): # rotate up to 1080 degrees
|
|
459
|
+
y[y < minhue] += 360
|
|
460
|
+
else:
|
|
461
|
+
if "HSL" in label:
|
|
462
|
+
m = ms = max(min(max(ms, max(y)), maxsat), 100)
|
|
463
|
+
elif "HPL" in label:
|
|
464
|
+
m = mp = max(min(max(mp, max(y)), maxsat), 100)
|
|
465
|
+
else:
|
|
466
|
+
m = mc = max(min(max(mc, max(y)), maxsat), 100)
|
|
467
|
+
ylim = (0, m)
|
|
468
|
+
ylocator = ("maxn", 5)
|
|
469
|
+
ax.scatter(x, y, c=x, cmap=cmap, s=width, linewidths=0)
|
|
470
|
+
ax.format(title=label, ylim=ylim, ylocator=ylocator)
|
|
471
|
+
|
|
472
|
+
# Formatting
|
|
473
|
+
suptitle = (
|
|
474
|
+
", ".join(repr(cmap.name) for cmap in cmaps[:-1])
|
|
475
|
+
+ (", and " if len(cmaps) > 2 else " and " if len(cmaps) == 2 else " ")
|
|
476
|
+
+ f"{repr(cmaps[-1].name)} colormap"
|
|
477
|
+
+ ("s" if len(cmaps) > 1 else "")
|
|
478
|
+
)
|
|
479
|
+
axs.format(
|
|
480
|
+
xlocator=0.25,
|
|
481
|
+
xformatter="null",
|
|
482
|
+
suptitle=f"{suptitle} by channel",
|
|
483
|
+
ylim=None,
|
|
484
|
+
ytickminor=False,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
# Colorbar on the bottom
|
|
488
|
+
for cmap in cmaps:
|
|
489
|
+
fig.colorbar(
|
|
490
|
+
cmap,
|
|
491
|
+
loc="b",
|
|
492
|
+
span=(2, 5),
|
|
493
|
+
locator="null",
|
|
494
|
+
label=cmap.name,
|
|
495
|
+
labelweight="bold",
|
|
496
|
+
)
|
|
497
|
+
return fig, axs
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def show_colorspaces(*, luminance=None, saturation=None, hue=None, refwidth=2):
|
|
501
|
+
"""
|
|
502
|
+
Generate hue-saturation, hue-luminance, and luminance-saturation
|
|
503
|
+
cross-sections for the HCL, HSL, and HPL colorspaces.
|
|
504
|
+
|
|
505
|
+
Parameters
|
|
506
|
+
----------
|
|
507
|
+
luminance : float, default: 50
|
|
508
|
+
If passed, saturation-hue cross-sections are drawn for
|
|
509
|
+
this luminance. Must be between ``0`` and ``100``.
|
|
510
|
+
saturation : float, optional
|
|
511
|
+
If passed, luminance-hue cross-sections are drawn for this
|
|
512
|
+
saturation. Must be between ``0`` and ``100``.
|
|
513
|
+
hue : float, optional
|
|
514
|
+
If passed, luminance-saturation cross-sections
|
|
515
|
+
are drawn for this hue. Must be between ``0`` and ``360``.
|
|
516
|
+
refwidth : str or float, optional
|
|
517
|
+
Average width of each subplot. Units are interpreted by
|
|
518
|
+
`~ultraplot.utils.units`.
|
|
519
|
+
|
|
520
|
+
Returns
|
|
521
|
+
-------
|
|
522
|
+
ultraplot.figure.Figure
|
|
523
|
+
The figure.
|
|
524
|
+
ultraplot.gridspec.SubplotGrid
|
|
525
|
+
The subplot grid.
|
|
526
|
+
|
|
527
|
+
See also
|
|
528
|
+
--------
|
|
529
|
+
show_cmaps
|
|
530
|
+
show_channels
|
|
531
|
+
"""
|
|
532
|
+
# Get colorspace properties
|
|
533
|
+
hues = np.linspace(0, 360, 361)
|
|
534
|
+
sats = np.linspace(0, 120, 120)
|
|
535
|
+
lums = np.linspace(0, 99.99, 101)
|
|
536
|
+
if luminance is None and saturation is None and hue is None:
|
|
537
|
+
luminance = 50
|
|
538
|
+
_not_none(luminance=luminance, saturation=saturation, hue=hue) # warning
|
|
539
|
+
if luminance is not None:
|
|
540
|
+
hsl = np.concatenate(
|
|
541
|
+
(
|
|
542
|
+
np.repeat(hues[:, None], len(sats), axis=1)[..., None],
|
|
543
|
+
np.repeat(sats[None, :], len(hues), axis=0)[..., None],
|
|
544
|
+
np.ones((len(hues), len(sats)))[..., None] * luminance,
|
|
545
|
+
),
|
|
546
|
+
axis=2,
|
|
547
|
+
)
|
|
548
|
+
suptitle = f"Hue-saturation cross-section for luminance {luminance}"
|
|
549
|
+
xlabel, ylabel = "hue", "saturation"
|
|
550
|
+
xloc, yloc = 60, 20
|
|
551
|
+
elif saturation is not None:
|
|
552
|
+
hsl = np.concatenate(
|
|
553
|
+
(
|
|
554
|
+
np.repeat(hues[:, None], len(lums), axis=1)[..., None],
|
|
555
|
+
np.ones((len(hues), len(lums)))[..., None] * saturation,
|
|
556
|
+
np.repeat(lums[None, :], len(hues), axis=0)[..., None],
|
|
557
|
+
),
|
|
558
|
+
axis=2,
|
|
559
|
+
)
|
|
560
|
+
suptitle = f"Hue-luminance cross-section for saturation {saturation}"
|
|
561
|
+
xlabel, ylabel = "hue", "luminance"
|
|
562
|
+
xloc, yloc = 60, 20
|
|
563
|
+
elif hue is not None:
|
|
564
|
+
hsl = np.concatenate(
|
|
565
|
+
(
|
|
566
|
+
np.ones((len(lums), len(sats)))[..., None] * hue,
|
|
567
|
+
np.repeat(sats[None, :], len(lums), axis=0)[..., None],
|
|
568
|
+
np.repeat(lums[:, None], len(sats), axis=1)[..., None],
|
|
569
|
+
),
|
|
570
|
+
axis=2,
|
|
571
|
+
)
|
|
572
|
+
suptitle = "Luminance-saturation cross-section"
|
|
573
|
+
xlabel, ylabel = "luminance", "saturation"
|
|
574
|
+
xloc, yloc = 20, 20
|
|
575
|
+
|
|
576
|
+
# Make figure, with black indicating invalid values
|
|
577
|
+
# Note we invert the x-y ordering for imshow
|
|
578
|
+
fig, axs = ui.subplots(refwidth=refwidth, ncols=3, share=False, innerpad=0.5)
|
|
579
|
+
for ax, space in zip(axs, ("hcl", "hsl", "hpl")):
|
|
580
|
+
rgba = np.ones((*hsl.shape[:2][::-1], 4)) # RGBA
|
|
581
|
+
for j in range(hsl.shape[0]):
|
|
582
|
+
for k in range(hsl.shape[1]):
|
|
583
|
+
rgb_jk = to_rgb(hsl[j, k, :], space)
|
|
584
|
+
if not all(0 <= c <= 1 for c in rgb_jk):
|
|
585
|
+
rgba[k, j, 3] = 0 # black cell
|
|
586
|
+
else:
|
|
587
|
+
rgba[k, j, :3] = rgb_jk
|
|
588
|
+
ax.imshow(rgba, origin="lower", aspect="auto")
|
|
589
|
+
ax.format(
|
|
590
|
+
xlabel=xlabel,
|
|
591
|
+
ylabel=ylabel,
|
|
592
|
+
suptitle=suptitle,
|
|
593
|
+
grid=False,
|
|
594
|
+
xtickminor=False,
|
|
595
|
+
ytickminor=False,
|
|
596
|
+
xlocator=xloc,
|
|
597
|
+
ylocator=yloc,
|
|
598
|
+
facecolor="k",
|
|
599
|
+
title=space.upper(),
|
|
600
|
+
)
|
|
601
|
+
return fig, axs
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
@warnings._rename_kwargs("0.8.0", categories="include")
|
|
605
|
+
@warnings._rename_kwargs("0.10.0", rasterize="rasterized")
|
|
606
|
+
def _draw_bars(
|
|
607
|
+
cmaps,
|
|
608
|
+
*,
|
|
609
|
+
source,
|
|
610
|
+
unknown="User",
|
|
611
|
+
include=None,
|
|
612
|
+
ignore=None,
|
|
613
|
+
length=4.0,
|
|
614
|
+
width=0.2,
|
|
615
|
+
N=None,
|
|
616
|
+
rasterized=None,
|
|
617
|
+
):
|
|
618
|
+
"""
|
|
619
|
+
Draw colorbars for "colormaps" and "color cycles". This is called by
|
|
620
|
+
`show_cycles` and `show_cmaps`.
|
|
621
|
+
"""
|
|
622
|
+
# Categorize the input names
|
|
623
|
+
table = {unknown: []} if unknown else {}
|
|
624
|
+
table.update({cat: [None] * len(names) for cat, names in source.items()})
|
|
625
|
+
for cmap in cmaps:
|
|
626
|
+
cat = None
|
|
627
|
+
name = cmap.name or "_no_name"
|
|
628
|
+
name = name.lower()
|
|
629
|
+
for opt, names in source.items():
|
|
630
|
+
names = list(map(str.lower, names))
|
|
631
|
+
if name in names:
|
|
632
|
+
i, cat = names.index(name), opt
|
|
633
|
+
if cat:
|
|
634
|
+
table[cat][i] = cmap
|
|
635
|
+
elif unknown:
|
|
636
|
+
table[unknown].append(cmap)
|
|
637
|
+
|
|
638
|
+
# Filter out certain categories
|
|
639
|
+
options = set(map(str.lower, source))
|
|
640
|
+
if ignore is None:
|
|
641
|
+
ignore = ("matlab", "gnuplot", "gist", "other")
|
|
642
|
+
if isinstance(include, str):
|
|
643
|
+
include = (include,)
|
|
644
|
+
if isinstance(ignore, str):
|
|
645
|
+
ignore = (ignore,)
|
|
646
|
+
if include is None:
|
|
647
|
+
include = options - set(map(str.lower, ignore))
|
|
648
|
+
else:
|
|
649
|
+
include = set(map(str.lower, include))
|
|
650
|
+
if any(cat not in options and cat != unknown for cat in include):
|
|
651
|
+
raise ValueError(
|
|
652
|
+
f"Invalid categories {include!r}. Options are: "
|
|
653
|
+
+ ", ".join(map(repr, source))
|
|
654
|
+
+ "."
|
|
655
|
+
)
|
|
656
|
+
for cat in tuple(table):
|
|
657
|
+
table[cat][:] = [cmap for cmap in table[cat] if cmap is not None]
|
|
658
|
+
if not table[cat] or cat.lower() not in include and cat != unknown:
|
|
659
|
+
del table[cat]
|
|
660
|
+
|
|
661
|
+
# Draw figure
|
|
662
|
+
# Allocate two colorbar widths for each title of sections
|
|
663
|
+
naxs = 2 * len(table) + sum(map(len, table.values()))
|
|
664
|
+
fig, axs = ui.subplots(
|
|
665
|
+
refwidth=length,
|
|
666
|
+
refheight=width,
|
|
667
|
+
nrows=naxs,
|
|
668
|
+
share=False,
|
|
669
|
+
hspace="2pt",
|
|
670
|
+
top="-1em",
|
|
671
|
+
)
|
|
672
|
+
i = -1
|
|
673
|
+
nheads = nbars = 0 # for deciding which axes to plot in
|
|
674
|
+
for cat, cmaps in table.items():
|
|
675
|
+
nheads += 1
|
|
676
|
+
for j, cmap in enumerate(cmaps):
|
|
677
|
+
i += 1
|
|
678
|
+
if j + nheads + nbars > naxs:
|
|
679
|
+
break
|
|
680
|
+
if j == 0: # allocate this axes for title
|
|
681
|
+
i += 2
|
|
682
|
+
for ax in axs[i - 2 : i]:
|
|
683
|
+
ax.set_visible(False)
|
|
684
|
+
ax = axs[i]
|
|
685
|
+
if N is not None:
|
|
686
|
+
cmap = cmap.copy(N=N)
|
|
687
|
+
label = cmap.name
|
|
688
|
+
label = re.sub(r"\A_*", "", label)
|
|
689
|
+
label = re.sub(r"(_copy)*\Z", "", label)
|
|
690
|
+
ax.colorbar(
|
|
691
|
+
cmap,
|
|
692
|
+
loc="fill",
|
|
693
|
+
orientation="horizontal",
|
|
694
|
+
locator="null",
|
|
695
|
+
linewidth=0,
|
|
696
|
+
rasterized=rasterized,
|
|
697
|
+
)
|
|
698
|
+
ax.text(
|
|
699
|
+
0 - (rc["axes.labelpad"] / 72) / length,
|
|
700
|
+
0.45,
|
|
701
|
+
label,
|
|
702
|
+
ha="right",
|
|
703
|
+
va="center",
|
|
704
|
+
transform="axes",
|
|
705
|
+
)
|
|
706
|
+
if j == 0:
|
|
707
|
+
ax.set_title(cat, weight="bold")
|
|
708
|
+
nbars += len(cmaps)
|
|
709
|
+
|
|
710
|
+
return fig, axs
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
@docstring._snippet_manager
|
|
714
|
+
def show_cmaps(*args, **kwargs):
|
|
715
|
+
"""
|
|
716
|
+
Generate a table of the registered colormaps or the input colormaps
|
|
717
|
+
categorized by source. Adapted from `this example \
|
|
718
|
+
<http://matplotlib.org/stable/gallery/color/colormap_reference.html>`__.
|
|
719
|
+
|
|
720
|
+
Parameters
|
|
721
|
+
----------
|
|
722
|
+
*args : colormap-spec, optional
|
|
723
|
+
Colormap names or objects.
|
|
724
|
+
N : int, default: :rc:`image.lut`
|
|
725
|
+
The number of levels in each colorbar.
|
|
726
|
+
unknown : str, default: 'User'
|
|
727
|
+
Category name for colormaps that are unknown to ultraplot.
|
|
728
|
+
Set this to ``False`` to hide unknown colormaps.
|
|
729
|
+
include : str or sequence of str, default: None
|
|
730
|
+
Category names to be shown in the table. Use this to limit
|
|
731
|
+
the table to a subset of categories. Valid categories are
|
|
732
|
+
%(demos.cmaps)s.
|
|
733
|
+
ignore : str or sequence of str, default: 'MATLAB', 'GNUplot', 'GIST', 'Other'
|
|
734
|
+
Used only if `include` was not passed. Category names to be removed from the
|
|
735
|
+
table. Use of the default ignored colormaps is discouraged because they contain
|
|
736
|
+
non-uniform color transitions (see the :ref:`user guide <ug_perceptual>`).
|
|
737
|
+
%(demos.colorbar)s
|
|
738
|
+
|
|
739
|
+
Returns
|
|
740
|
+
-------
|
|
741
|
+
ultraplot.figure.Figure
|
|
742
|
+
The figure.
|
|
743
|
+
ultraplot.gridspec.SubplotGrid
|
|
744
|
+
The subplot grid.
|
|
745
|
+
|
|
746
|
+
See also
|
|
747
|
+
--------
|
|
748
|
+
show_colorspaces
|
|
749
|
+
show_channels
|
|
750
|
+
show_cycles
|
|
751
|
+
show_colors
|
|
752
|
+
show_fonts
|
|
753
|
+
"""
|
|
754
|
+
# Get the list of colormaps
|
|
755
|
+
if args:
|
|
756
|
+
cmaps = list(map(constructor.Colormap, args))
|
|
757
|
+
cmaps = [
|
|
758
|
+
(
|
|
759
|
+
cmap
|
|
760
|
+
if isinstance(cmap, mcolors.LinearSegmentedColormap)
|
|
761
|
+
else pcolors._get_cmap_subtype(cmap, "continuous")
|
|
762
|
+
)
|
|
763
|
+
for cmap in args
|
|
764
|
+
]
|
|
765
|
+
ignore = ()
|
|
766
|
+
else:
|
|
767
|
+
cmaps = [
|
|
768
|
+
cmap
|
|
769
|
+
for cmap in pcolors._cmap_database.values()
|
|
770
|
+
if isinstance(cmap, pcolors.ContinuousColormap)
|
|
771
|
+
and not (cmap.name or "_")[:1] == "_"
|
|
772
|
+
]
|
|
773
|
+
ignore = None
|
|
774
|
+
|
|
775
|
+
# Return figure of colorbars
|
|
776
|
+
kwargs.setdefault("source", CMAP_TABLE)
|
|
777
|
+
kwargs.setdefault("ignore", ignore)
|
|
778
|
+
return _draw_bars(cmaps, **kwargs)
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
@docstring._snippet_manager
|
|
782
|
+
def show_cycles(*args, **kwargs):
|
|
783
|
+
"""
|
|
784
|
+
Generate a table of registered color cycles or the input color cycles
|
|
785
|
+
categorized by source. Adapted from `this example \
|
|
786
|
+
<http://matplotlib.org/stable/gallery/color/colormap_reference.html>`__.
|
|
787
|
+
|
|
788
|
+
Parameters
|
|
789
|
+
----------
|
|
790
|
+
*args : colormap-spec, optional
|
|
791
|
+
Cycle names or objects.
|
|
792
|
+
unknown : str, default: 'User'
|
|
793
|
+
Category name for cycles that are unknown to ultraplot.
|
|
794
|
+
Set this to ``False`` to hide unknown colormaps.
|
|
795
|
+
include : str or sequence of str, default: None
|
|
796
|
+
Category names to be shown in the table. Use this to limit
|
|
797
|
+
the table to a subset of categories. Valid categories are
|
|
798
|
+
%(demos.cycles)s.
|
|
799
|
+
ignore : str or sequence of str, default: None
|
|
800
|
+
Used only if `include` was not passed. Category names to be removed
|
|
801
|
+
from the table.
|
|
802
|
+
%(demos.colorbar)s
|
|
803
|
+
|
|
804
|
+
Returns
|
|
805
|
+
-------
|
|
806
|
+
ultraplot.figure.Figure
|
|
807
|
+
The figure.
|
|
808
|
+
ultraplot.gridspec.SubplotGrid
|
|
809
|
+
The subplot grid.
|
|
810
|
+
|
|
811
|
+
See also
|
|
812
|
+
--------
|
|
813
|
+
show_cmaps
|
|
814
|
+
show_colors
|
|
815
|
+
show_fonts
|
|
816
|
+
"""
|
|
817
|
+
# Get the list of cycles
|
|
818
|
+
if args:
|
|
819
|
+
cycles = [
|
|
820
|
+
(
|
|
821
|
+
pcolors.DiscreteColormap(
|
|
822
|
+
cmap.by_key().get("color", ["k"]), name=getattr(cmap, "name", None)
|
|
823
|
+
)
|
|
824
|
+
if isinstance(cmap, cycler.Cycler)
|
|
825
|
+
else (
|
|
826
|
+
cmap
|
|
827
|
+
if isinstance(cmap, mcolors.ListedColormap)
|
|
828
|
+
else pcolors._get_cmap_subtype(cmap, "discrete")
|
|
829
|
+
)
|
|
830
|
+
)
|
|
831
|
+
for cmap in args
|
|
832
|
+
]
|
|
833
|
+
ignore = ()
|
|
834
|
+
else:
|
|
835
|
+
cycles = [
|
|
836
|
+
cmap
|
|
837
|
+
for cmap in pcolors._cmap_database.values()
|
|
838
|
+
if isinstance(cmap, pcolors.DiscreteColormap)
|
|
839
|
+
and not (cmap.name or "_")[:1] == "_"
|
|
840
|
+
]
|
|
841
|
+
ignore = None
|
|
842
|
+
|
|
843
|
+
# Return figure of colorbars
|
|
844
|
+
kwargs.setdefault("source", CYCLE_TABLE)
|
|
845
|
+
kwargs.setdefault("ignore", ignore)
|
|
846
|
+
return _draw_bars(cycles, **kwargs)
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
def _filter_colors(hcl, ihue, nhues, minsat):
|
|
850
|
+
"""
|
|
851
|
+
Filter colors into categories.
|
|
852
|
+
|
|
853
|
+
Parameters
|
|
854
|
+
----------
|
|
855
|
+
hcl : tuple
|
|
856
|
+
The data.
|
|
857
|
+
ihue : int
|
|
858
|
+
The hue column.
|
|
859
|
+
nhues : int
|
|
860
|
+
The total number of hues.
|
|
861
|
+
minsat : float
|
|
862
|
+
The minimum saturation used for the "grays" column.
|
|
863
|
+
"""
|
|
864
|
+
breakpoints = np.linspace(0, 360, nhues)
|
|
865
|
+
gray = hcl[1] <= minsat
|
|
866
|
+
if ihue == 0:
|
|
867
|
+
return gray
|
|
868
|
+
color = breakpoints[ihue - 1] <= hcl[0] < breakpoints[ihue]
|
|
869
|
+
if ihue == nhues - 1:
|
|
870
|
+
color = color or color == breakpoints[ihue] # endpoint inclusive
|
|
871
|
+
return not gray and color
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
@docstring._snippet_manager
|
|
875
|
+
def show_colors(*, nhues=17, minsat=10, unknown="User", include=None, ignore=None):
|
|
876
|
+
"""
|
|
877
|
+
Generate tables of the registered color names. Adapted from
|
|
878
|
+
`this example <https://matplotlib.org/examples/color/named_colors.html>`__.
|
|
879
|
+
|
|
880
|
+
Parameters
|
|
881
|
+
----------
|
|
882
|
+
nhues : int, optional
|
|
883
|
+
The number of breaks between hues for grouping "like colors" in the
|
|
884
|
+
color table.
|
|
885
|
+
minsat : float, optional
|
|
886
|
+
The threshold saturation, between ``0`` and ``100``, for designating
|
|
887
|
+
"gray colors" in the color table.
|
|
888
|
+
unknown : str, default: 'User'
|
|
889
|
+
Category name for color names that are unknown to ultraplot.
|
|
890
|
+
Set this to ``False`` to hide unknown color names.
|
|
891
|
+
include : str or sequence of str, default: None
|
|
892
|
+
Category names to be shown in the table. Use this to limit
|
|
893
|
+
the table to a subset of categories. Valid categories are
|
|
894
|
+
%(demos.colors)s.
|
|
895
|
+
ignore : str or sequence of str, default: 'CSS4'
|
|
896
|
+
Used only if `include` was not passed. Category names to be removed
|
|
897
|
+
from the colormap table.
|
|
898
|
+
|
|
899
|
+
Returns
|
|
900
|
+
-------
|
|
901
|
+
ultraplot.figure.Figure
|
|
902
|
+
The figure.
|
|
903
|
+
ultraplot.gridspec.SubplotGrid
|
|
904
|
+
The subplot grid.
|
|
905
|
+
"""
|
|
906
|
+
# Tables of known colors to be plotted
|
|
907
|
+
colordict = {}
|
|
908
|
+
if ignore is None:
|
|
909
|
+
ignore = "css4"
|
|
910
|
+
if isinstance(include, str):
|
|
911
|
+
include = (include.lower(),)
|
|
912
|
+
if isinstance(ignore, str):
|
|
913
|
+
ignore = (ignore.lower(),)
|
|
914
|
+
if include is None:
|
|
915
|
+
include = COLOR_TABLE.keys()
|
|
916
|
+
include -= set(map(str.lower, ignore))
|
|
917
|
+
for cat in sorted(include):
|
|
918
|
+
if cat not in COLOR_TABLE:
|
|
919
|
+
raise ValueError(
|
|
920
|
+
f"Invalid categories {include!r}. Options are: "
|
|
921
|
+
+ ", ".join(map(repr, COLOR_TABLE))
|
|
922
|
+
+ "."
|
|
923
|
+
)
|
|
924
|
+
colordict[cat] = list(COLOR_TABLE[cat]) # copy the names
|
|
925
|
+
|
|
926
|
+
# Add "unknown" colors
|
|
927
|
+
if unknown:
|
|
928
|
+
unknown_colors = [
|
|
929
|
+
color
|
|
930
|
+
for color in map(repr, pcolors._color_database)
|
|
931
|
+
if "xkcd:" not in color
|
|
932
|
+
and "tableau:" not in color
|
|
933
|
+
and not any(color in list_ for list_ in COLOR_TABLE)
|
|
934
|
+
]
|
|
935
|
+
if unknown_colors:
|
|
936
|
+
colordict[unknown] = unknown_colors
|
|
937
|
+
|
|
938
|
+
# Divide colors into columns and rows
|
|
939
|
+
# For base and open colors, tables are already organized into like
|
|
940
|
+
# colors, so just reshape them into grids. For other colors, we group
|
|
941
|
+
# them by hue in descending order of luminance.
|
|
942
|
+
namess = {}
|
|
943
|
+
for cat in sorted(include):
|
|
944
|
+
if cat == "base":
|
|
945
|
+
names = np.asarray(colordict[cat])
|
|
946
|
+
ncols, nrows = len(names), 1
|
|
947
|
+
elif cat == "opencolor":
|
|
948
|
+
names = np.asarray(colordict[cat])
|
|
949
|
+
ncols, nrows = 7, 20
|
|
950
|
+
else:
|
|
951
|
+
hclpairs = [(name, to_xyz(name, "hcl")) for name in colordict[cat]]
|
|
952
|
+
hclpairs = [
|
|
953
|
+
sorted(
|
|
954
|
+
[
|
|
955
|
+
pair
|
|
956
|
+
for pair in hclpairs
|
|
957
|
+
if _filter_colors(pair[1], ihue, nhues, minsat)
|
|
958
|
+
],
|
|
959
|
+
key=lambda x: x[1][2], # sort by luminance
|
|
960
|
+
)
|
|
961
|
+
for ihue in range(nhues)
|
|
962
|
+
]
|
|
963
|
+
names = np.array([name for ipairs in hclpairs for name, _ in ipairs])
|
|
964
|
+
ncols, nrows = 4, len(names) // 4 + 1
|
|
965
|
+
|
|
966
|
+
names.resize((ncols, nrows)) # fill empty slots with empty string
|
|
967
|
+
namess[cat] = names
|
|
968
|
+
|
|
969
|
+
# Draw figures for different groups of colors
|
|
970
|
+
# NOTE: Aspect ratios should be number of columns divided by number
|
|
971
|
+
# of rows, times the aspect ratio of the slot for each swatch-name
|
|
972
|
+
# pair, which we set to 5.
|
|
973
|
+
shape = tuple(namess.values())[0].shape # sample *first* group
|
|
974
|
+
figwidth = 6.5
|
|
975
|
+
refaspect = (figwidth * 72) / (10 * shape[1]) # points
|
|
976
|
+
maxcols = max(names.shape[0] for names in namess.values())
|
|
977
|
+
hratios = tuple(names.shape[1] for names in namess.values())
|
|
978
|
+
fig, axs = ui.subplots(
|
|
979
|
+
figwidth=figwidth,
|
|
980
|
+
refaspect=refaspect,
|
|
981
|
+
nrows=len(include),
|
|
982
|
+
hratios=hratios,
|
|
983
|
+
)
|
|
984
|
+
title_dict = {
|
|
985
|
+
"css4": "CSS4 colors",
|
|
986
|
+
"base": "Base colors",
|
|
987
|
+
"opencolor": "Open color",
|
|
988
|
+
"xkcd": "XKCD colors",
|
|
989
|
+
}
|
|
990
|
+
for ax, (cat, names) in zip(axs, namess.items()):
|
|
991
|
+
# Format axes
|
|
992
|
+
ax.format(
|
|
993
|
+
title=title_dict.get(cat, cat),
|
|
994
|
+
titleweight="bold",
|
|
995
|
+
xlim=(0, maxcols - 1),
|
|
996
|
+
ylim=(0, names.shape[1]),
|
|
997
|
+
grid=False,
|
|
998
|
+
yloc="neither",
|
|
999
|
+
xloc="neither",
|
|
1000
|
+
alpha=0,
|
|
1001
|
+
)
|
|
1002
|
+
|
|
1003
|
+
# Draw swatches as lines
|
|
1004
|
+
lw = 8 # best to just use trial and error
|
|
1005
|
+
swatch = 0.45 # percent of column reserved for swatch
|
|
1006
|
+
ncols, nrows = names.shape
|
|
1007
|
+
for col, inames in enumerate(names):
|
|
1008
|
+
for row, name in enumerate(inames):
|
|
1009
|
+
if not name:
|
|
1010
|
+
continue
|
|
1011
|
+
y = nrows - row - 1 # start at top
|
|
1012
|
+
x1 = col * (maxcols - 1) / ncols # e.g. idx 3 --> idx 7
|
|
1013
|
+
x2 = x1 + swatch # portion of column
|
|
1014
|
+
xtext = x1 + 1.1 * swatch
|
|
1015
|
+
ax.text(
|
|
1016
|
+
xtext,
|
|
1017
|
+
y,
|
|
1018
|
+
name,
|
|
1019
|
+
ha="left",
|
|
1020
|
+
va="center",
|
|
1021
|
+
transform="data",
|
|
1022
|
+
clip_on=False,
|
|
1023
|
+
)
|
|
1024
|
+
ax.plot(
|
|
1025
|
+
[x1, x2],
|
|
1026
|
+
[y, y],
|
|
1027
|
+
color=name,
|
|
1028
|
+
lw=lw,
|
|
1029
|
+
solid_capstyle="butt", # do not stick out
|
|
1030
|
+
clip_on=False,
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
return fig, axs
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
def show_fonts(
|
|
1037
|
+
*args, family=None, user=None, text=None, math=False, fallback=False, **kwargs
|
|
1038
|
+
):
|
|
1039
|
+
"""
|
|
1040
|
+
Generate a table of fonts. If a glyph for a particular font is unavailable,
|
|
1041
|
+
it is replaced with the "¤" dummy character.
|
|
1042
|
+
|
|
1043
|
+
Parameters
|
|
1044
|
+
----------
|
|
1045
|
+
*args : str or `~matplotlib.font_manager.FontProperties`
|
|
1046
|
+
The font specs, font names, or `~matplotlib.font_manager.FontProperties`\\ s
|
|
1047
|
+
to show. If no positional arguments are passed and the `family` argument is
|
|
1048
|
+
not passed, then the fonts found in `~ultraplot.config.Configurator.user_folder`
|
|
1049
|
+
and `~ultraplot.config.Configurator.local_folders` and the *available*
|
|
1050
|
+
:rcraw:`font.sans-serif` fonts are shown.
|
|
1051
|
+
family \
|
|
1052
|
+
: {'tex-gyre', 'sans-serif', 'serif', 'monospace', 'cursive', 'fantasy'}, optional
|
|
1053
|
+
The family from which *available* fonts are shown. Default is ``'sans-serif'``
|
|
1054
|
+
if no arguments were provided. Otherwise the default is to not show family
|
|
1055
|
+
fonts. The fonts belonging to each family are listed under :rcraw:`font.serif`,
|
|
1056
|
+
:rcraw:`font.sans-serif`, :rcraw:`font.monospace`, :rcraw:`font.cursive`, and
|
|
1057
|
+
:rcraw:`font.fantasy`. The special family ``'tex-gyre'`` includes the
|
|
1058
|
+
`TeX Gyre <http://www.gust.org.pl/projects/e-foundry/tex-gyre>`__ fonts.
|
|
1059
|
+
user : bool, optional
|
|
1060
|
+
Whether to include fonts in `~ultraplot.config.Configurator.user_folder` and
|
|
1061
|
+
`~ultraplot.config.Configurator.local_folders` at the top of the table. Default
|
|
1062
|
+
is ``True`` if called without any arguments and ``False`` otherwise.
|
|
1063
|
+
text : str, optional
|
|
1064
|
+
The sample text shown for each font. If not passed then default math or
|
|
1065
|
+
non-math sample text is used.
|
|
1066
|
+
math : bool, default: False
|
|
1067
|
+
Whether the default sample text should show non-math Latin characters or
|
|
1068
|
+
or math equations and Greek letters.
|
|
1069
|
+
fallback : bool, default: False
|
|
1070
|
+
Whether to use the fallback font :rcraw:`mathtext.fallback` for unavailable
|
|
1071
|
+
characters. If ``False`` the dummy glyph "¤" is shown for missing characters.
|
|
1072
|
+
**kwargs
|
|
1073
|
+
Additional font properties passed to `~matplotlib.font_manager.FontProperties`.
|
|
1074
|
+
Default size is ``12`` and default weight, style, and strength are ``'normal'``.
|
|
1075
|
+
|
|
1076
|
+
Other parameters
|
|
1077
|
+
----------------
|
|
1078
|
+
size : float, default: 12
|
|
1079
|
+
The font size.
|
|
1080
|
+
weight : str, default: 'normal'
|
|
1081
|
+
The font weight.
|
|
1082
|
+
style : str, default: 'normal'
|
|
1083
|
+
The font style.
|
|
1084
|
+
stretch : str, default: 'normal'
|
|
1085
|
+
The font stretch.
|
|
1086
|
+
|
|
1087
|
+
Returns
|
|
1088
|
+
-------
|
|
1089
|
+
ultraplot.figure.Figure
|
|
1090
|
+
The figure.
|
|
1091
|
+
ultraplot.gridspec.SubplotGrid
|
|
1092
|
+
The subplot grid.
|
|
1093
|
+
|
|
1094
|
+
See also
|
|
1095
|
+
--------
|
|
1096
|
+
show_cmaps
|
|
1097
|
+
show_cycles
|
|
1098
|
+
show_colors
|
|
1099
|
+
"""
|
|
1100
|
+
# Parse user input fonts and translate into FontProperties.
|
|
1101
|
+
s = set()
|
|
1102
|
+
props = [] # should be string names
|
|
1103
|
+
all_fonts = sorted(mfonts.fontManager.ttflist, key=lambda font: font.name)
|
|
1104
|
+
all_fonts = [
|
|
1105
|
+
font for font in all_fonts if font.name not in s and not s.add(font.name)
|
|
1106
|
+
] # noqa: E501
|
|
1107
|
+
all_names = [font.name for font in all_fonts]
|
|
1108
|
+
for arg in args:
|
|
1109
|
+
if isinstance(arg, str):
|
|
1110
|
+
arg = mfonts.FontProperties(arg, **kwargs) # possibly a fontspec
|
|
1111
|
+
elif not isinstance(arg, mfonts.FontProperties):
|
|
1112
|
+
raise TypeError(f"Expected string or FontProperties but got {type(arg)}.")
|
|
1113
|
+
opts = arg.get_family() # usually a singleton list
|
|
1114
|
+
if opts and opts[0] in all_names:
|
|
1115
|
+
props.append(arg)
|
|
1116
|
+
else:
|
|
1117
|
+
warnings._warn_ultraplot(f"Input font name {opts[:1]!r} not found. Skipping.")
|
|
1118
|
+
|
|
1119
|
+
# Add user and family FontProperties.
|
|
1120
|
+
user = _not_none(user, not args and family is None)
|
|
1121
|
+
family = _not_none(family, None if args else "sans-serif")
|
|
1122
|
+
if user:
|
|
1123
|
+
paths = _get_data_folders("fonts", default=False)
|
|
1124
|
+
for font in all_fonts: # fonts sorted by unique name
|
|
1125
|
+
if os.path.dirname(font.fname) in paths:
|
|
1126
|
+
props.append(mfonts.FontProperties(font.name, **kwargs))
|
|
1127
|
+
if family is not None:
|
|
1128
|
+
options = ("serif", "sans-serif", "monospace", "cursive", "fantasy", "tex-gyre")
|
|
1129
|
+
if family not in options:
|
|
1130
|
+
raise ValueError(
|
|
1131
|
+
f"Invalid font family {family!r}. Options are: "
|
|
1132
|
+
+ ", ".join(map(repr, options))
|
|
1133
|
+
+ "."
|
|
1134
|
+
)
|
|
1135
|
+
names = FAMILY_TEXGYRE if family == "tex-gyre" else rc["font." + family]
|
|
1136
|
+
for name in names:
|
|
1137
|
+
if name in all_names: # valid font name
|
|
1138
|
+
props.append(mfonts.FontProperties(name, **kwargs))
|
|
1139
|
+
|
|
1140
|
+
# The default sample text
|
|
1141
|
+
linespacing = 0.8 if text is None and math else 1.2
|
|
1142
|
+
if text is None:
|
|
1143
|
+
if not math:
|
|
1144
|
+
text = (
|
|
1145
|
+
"the quick brown fox jumps over a lazy dog 01234 ; . , + - * ^ () ||"
|
|
1146
|
+
"\n"
|
|
1147
|
+
"THE QUICK BROWN FOX JUMPS OVER A LAZY DOG 56789 : ! ? & # % $ [] {}"
|
|
1148
|
+
)
|
|
1149
|
+
else:
|
|
1150
|
+
text = (
|
|
1151
|
+
"\n"
|
|
1152
|
+
r"$\alpha\beta$ $\Gamma\gamma$ $\Delta\delta$ "
|
|
1153
|
+
r"$\epsilon\zeta\eta$ $\Theta\theta$ $\kappa\mu\nu$ "
|
|
1154
|
+
r"$\Lambda\lambda$ $\Pi\pi$ $\xi\rho\tau\chi$ $\Sigma\sigma$ "
|
|
1155
|
+
r"$\Phi\phi$ $\Psi\psi$ $\Omega\omega$ "
|
|
1156
|
+
r"$\{ \; \}^i$ $[ \; ]_j$ $( \; )^k$ $\left< \right>_n$"
|
|
1157
|
+
"\n"
|
|
1158
|
+
r"$0^a + 1_b - 2^c \times 3_d = "
|
|
1159
|
+
r"4.0^e \equiv 5.0_f \approx 6.0^g \sim 7_h \leq 8^i \geq 9_j"
|
|
1160
|
+
r"\ll \prod \, P \gg \sum \, Q \, "
|
|
1161
|
+
r"\int \, Y \mathrm{d}y \propto \oint \;\, Z \mathrm{d}z$"
|
|
1162
|
+
)
|
|
1163
|
+
|
|
1164
|
+
# Settings for rendering math text
|
|
1165
|
+
ctx = {"mathtext.fontset": "custom"}
|
|
1166
|
+
if not fallback:
|
|
1167
|
+
if _version_mpl < "3.4":
|
|
1168
|
+
ctx["mathtext.fallback_to_cm"] = False
|
|
1169
|
+
else:
|
|
1170
|
+
ctx["mathtext.fallback"] = None
|
|
1171
|
+
if "size" not in kwargs:
|
|
1172
|
+
for prop in props:
|
|
1173
|
+
if prop.get_size() == rc["font.size"]:
|
|
1174
|
+
prop.set_size(12) # only if fontspec did not change the size
|
|
1175
|
+
|
|
1176
|
+
# Create figure
|
|
1177
|
+
refsize = props[0].get_size_in_points() if props else rc["font.size"]
|
|
1178
|
+
refheight = 1.2 * (text.count("\n") + 2.5) * refsize / 72
|
|
1179
|
+
fig, axs = ui.subplots(
|
|
1180
|
+
refwidth=4.5,
|
|
1181
|
+
refheight=refheight,
|
|
1182
|
+
nrows=len(props),
|
|
1183
|
+
ncols=1,
|
|
1184
|
+
space=0,
|
|
1185
|
+
)
|
|
1186
|
+
fig._render_context.update(ctx)
|
|
1187
|
+
fig.format(
|
|
1188
|
+
xloc="neither", yloc="neither", xlocator="null", ylocator="null", alpha=0
|
|
1189
|
+
)
|
|
1190
|
+
for ax, prop in zip(axs, props):
|
|
1191
|
+
name = prop.get_family()[0]
|
|
1192
|
+
ax.text(
|
|
1193
|
+
0,
|
|
1194
|
+
0.5,
|
|
1195
|
+
f"{name}:\n{text} ",
|
|
1196
|
+
ha="left",
|
|
1197
|
+
va="center",
|
|
1198
|
+
linespacing=linespacing,
|
|
1199
|
+
fontproperties=prop,
|
|
1200
|
+
)
|
|
1201
|
+
return fig, axs
|