fluxplot 0.1.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fluxplot-0.1.0 → fluxplot-0.4.0}/.gitignore +1 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/PKG-INFO +112 -62
- {fluxplot-0.1.0 → fluxplot-0.4.0}/README.md +111 -61
- {fluxplot-0.1.0 → fluxplot-0.4.0}/examples/fluxbox_example.py +1 -1
- fluxplot-0.4.0/examples/meanmark_example.py +74 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/pyproject.toml +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/__init__.py +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/api.py +41 -5
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/brackets.py +7 -4
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/data.py +9 -4
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/descriptors.py +5 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/fields.py +5 -3
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/integrity.py +13 -0
- fluxplot-0.4.0/src/fluxplot/layout.py +418 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/manifest.py +12 -4
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/raster.py +2 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/render.py +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/roles.py +6 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/schemas/manifest.schema.json +1773 -6
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/schemas/recipe.schema.json +1 -1
- fluxplot-0.4.0/src/fluxplot/signature_fluxplots/__init__.py +7 -0
- fluxplot-0.4.0/src/fluxplot/signature_fluxplots/_categorical.py +379 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/signature_fluxplots/_colour.py +3 -3
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/signature_fluxplots/fluxbox.py +123 -21
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/signature_fluxplots/hexmatrix.py +1 -1
- fluxplot-0.4.0/src/fluxplot/signature_fluxplots/meanmark.py +349 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/tagger.py +22 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/version.py +3 -2
- fluxplot-0.4.0/tests/fixtures/scene3d-library/SHA256SUMS.json +35 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/box-axes.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/box-axes.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/box-axes.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/categorical-missing.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/categorical-missing.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/categorical-missing.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/continuous.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/continuous.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/continuous.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-a.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-a.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-a.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-b.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-b.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-b.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-incompatible.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-incompatible.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/morph-incompatible.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/named-parts.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/named-parts.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/named-parts.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/plain.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/plain.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/plain.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/scalebar.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/scalebar.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/scalebar.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/sequence.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/sequence.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/sequence.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/states.fluxplot.json +2 -2
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/states.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d-library/states.recipe.json +1 -1
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_brackets.py +3 -3
- fluxplot-0.1.0/tests/test_glowbar.py → fluxplot-0.4.0/tests/test_categorical.py +21 -124
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_dark_ground.py +14 -15
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_fluxbox.py +89 -11
- fluxplot-0.4.0/tests/test_layout_capture.py +112 -0
- fluxplot-0.4.0/tests/test_layout_escapees.py +20 -0
- fluxplot-0.4.0/tests/test_meanmark.py +318 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_schema_complete.py +4 -4
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_series_colors.py +5 -5
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_tick_group_completeness.py +2 -1
- fluxplot-0.1.0/examples/glowbar_example.py +0 -54
- fluxplot-0.1.0/src/fluxplot/signature_fluxplots/__init__.py +0 -18
- fluxplot-0.1.0/src/fluxplot/signature_fluxplots/glowbar.py +0 -769
- fluxplot-0.1.0/tests/fixtures/scene3d-library/SHA256SUMS.json +0 -35
- {fluxplot-0.1.0 → fluxplot-0.4.0}/LICENSE +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/THIRD_PARTY_NOTICES.md +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/examples/growth_plot.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/examples/hexmatrix_example.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/examples/image_example.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/examples/scene3d_demo.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_fieldmap.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_mesh_reduce.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_scene3d_size.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_viewer/THIRD-PARTY.txt +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_viewer/flux-model3d-viewer.min.js +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/_viewer/stamp.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/autotag.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/base.mplstyle +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/canonical_json.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/capture.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/colorcheck.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/colors.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/colorscale.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/definitions/colormaps.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/definitions/flexoki.tokens.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/definitions/palettes.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/fits.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/glb.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/ids.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/images.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/mesh3d.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/panels.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/postprocess.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/presets.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/provenance.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/recipe.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/scene3d.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/scene3d_manifest.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/scene3d_viewer.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/schemas/.gitkeep +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/schemas/scene3d.schema.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/seaborn_adapters.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/stats/__init__.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/stats/_common.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/stats/multi_group.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/stats/paired.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/stats/two_group.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/style.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/surface.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/src/fluxplot/surface3d.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/_helpers.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/conftest.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/colorscale_vectors.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/fields.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/fields.png +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/fields.recipe.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/fields.svg +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-a.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-a.recipe.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-a.svg +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-b.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-b.recipe.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/panels-b.svg +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/presets.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/presets.recipe.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/polish/presets.svg +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/SHA256SUMS.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/box-axes.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/box-axes.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/categorical-missing.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/categorical-missing.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/continuous.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/continuous.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-a.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-a.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-b.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-b.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-incompatible.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/morph-incompatible.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/named-parts.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/named-parts.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/plain.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/plain.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/scalebar.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/scalebar.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/sequence.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/sequence.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/states.fluxplot.json +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/fixtures/scene3d/states.glb +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/generate_colorscale_vectors.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/generate_polish_fixtures.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/generate_scene3d_fixtures.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/generate_scene3d_library_fixtures.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_alpha_by.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_autotag_promotion.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_band.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_capture.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_color_definitions.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_colorcheck.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_colors.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_colorscale.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_core_fixes.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_data_kind.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_determinism.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_errorbar_legend.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_examples_fresh.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_extra_sweep.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_fits.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_hexmatrix.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_id_stability.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_ids.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_images.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_m1_correctness.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_marker_dom.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_parts_contract.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_polish.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_provenance.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_rasterize.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_recipe_rerun.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_scaffold.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_scene3d.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_scene3d_api.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_scene3d_contract.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_scene3d_static.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_schema.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_seaborn_coverage.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_semantic_integrity.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_staged_write.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_stats.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_stats_multi.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_step_stem_axes.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_style.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_surface.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_tag_seaborn.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_theme.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_tick_deref.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_twins_figure.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_view_geometry.py +0 -0
- {fluxplot-0.1.0 → fluxplot-0.4.0}/tests/test_wrappers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fluxplot
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: matplotlib, but every meaningful thing has a name — semantic SVG plots for the Flux ecosystem
|
|
5
5
|
Project-URL: Homepage, https://github.com/fluxsci/fluxplot
|
|
6
6
|
Project-URL: Repository, https://github.com/fluxsci/fluxplot
|
|
@@ -297,6 +297,24 @@ anchors + a scale type is the complete, portable contract. (FluxPlot computes th
|
|
|
297
297
|
dpi-invariant fraction method that round-trips *exactly* against the positions matplotlib actually
|
|
298
298
|
emits — verified in `NOTES_matplotlib_svg.md`.)
|
|
299
299
|
|
|
300
|
+
### Layout capture — resizing without rerunning Python
|
|
301
|
+
|
|
302
|
+
Schema 0.4 adds a `layout` block, captured after the final SVG-renderer draw while the layout
|
|
303
|
+
is frozen. It records the original engine and GridSpec inputs, axes domains and aspect rules,
|
|
304
|
+
text anchors/extents, font advances, numeric locator/formatter parameters, legends, colorbars
|
|
305
|
+
and coordinate frames. Initial layout inputs are preserved across repeated saves, so the same
|
|
306
|
+
figure remains deterministic even when a draw adjusts its limits or subplot parameters.
|
|
307
|
+
|
|
308
|
+
Flux uses these facts to reflow a placed plot at a new physical size without measuring browser
|
|
309
|
+
text or executing Python. Data follows axes affines; glyphs, typography and stroke widths keep
|
|
310
|
+
their point sizes. Tick values identify existing labels across reticks. The matplotlib oracle in
|
|
311
|
+
`tools/relayout_oracle.py` generates layout, tick and solver truth for the Flux verification gates.
|
|
312
|
+
Date/category/custom (including locale-specific) ticks reposition without reticking. Point-sized glyphs anchored to data keep their point geometry: fluxbox boxes (`box` frames) and meanmark circles, arms and caps (`mark` frames, rebuilt exactly as `_MeanPart.get_path` draws them). Secondary
|
|
313
|
+
axes with affine conversions reflow; non-affine conversions record a named transform refusal. A dynamic major locator that emits no
|
|
314
|
+
native ticks records `ticks:no-template`, since there is no faithful SVG tick template to clone.
|
|
315
|
+
Polar, 3D, subfigures, compressed
|
|
316
|
+
layout, usetex and unsupported transforms record named refusals; their SVG still saves normally.
|
|
317
|
+
|
|
300
318
|
---
|
|
301
319
|
|
|
302
320
|
## Semantic IDs: the universal join key
|
|
@@ -475,58 +493,89 @@ label rather than being dropped.
|
|
|
475
493
|
|
|
476
494
|
**Signature fluxplots** — complete, opinionated plot types that are unique to Flux. They take a
|
|
477
495
|
DataFrame (pandas, polars or a dict of columns) plus column names, seaborn-style, and name every
|
|
478
|
-
part for you.
|
|
496
|
+
part for you. **Meanmark** draws an arithmetic mean as an outlined circle with a tinted
|
|
497
|
+
interior and two uncertainty arms, matching the compact mean-and-error marks used in scientific
|
|
498
|
+
figures:
|
|
479
499
|
|
|
480
500
|
```python
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
501
|
+
mm = fp.meanmark(df, x="condition", y="signal", units="subject", ax=ax)
|
|
502
|
+
# Summary alone, solid dots, 95% Student-t confidence intervals and endpoint caps:
|
|
503
|
+
mm = fp.meanmark(df, x="condition", y="signal", ax=ax,
|
|
504
|
+
show_individual_points=False, interval="ci", confidence=.95,
|
|
505
|
+
mark_fill_color="stroke", show_caps=True)
|
|
484
506
|
```
|
|
485
507
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
508
|
+
The default is a **95% Student-t confidence interval** around the mean (`interval="ci"`,
|
|
509
|
+
`confidence=.95`), using sample SD (`ddof=1`). `"sem"` gives mean ± SEM, `"sd"` gives mean ± SD,
|
|
510
|
+
`"range"` spans the observations, and a
|
|
511
|
+
callable `values -> (low, high)` supplies absolute bounds (finite and containing the mean).
|
|
512
|
+
Statistics count finite observations, without collapsing repeated rows per unit. A singleton has
|
|
513
|
+
an observable mean but no estimable SD/SEM/CI: its circle is drawn with null uncertainty bounds.
|
|
514
|
+
Empty categories retain a tick and have no summary. `orientation="horizontal"` rotates the layout;
|
|
515
|
+
`x` still supplies categories and `y` values. `value_scale="log"` changes the value axis while
|
|
516
|
+
preserving the arithmetic mean in original units; nonpositive data or bounds raise an error.
|
|
517
|
+
|
|
518
|
+
The circle diameter (`mark_size=4.5`) and outline (`mark_edge_width=1.5`) are in points. Its stroke
|
|
519
|
+
uses the group colour unless `mark_color` overrides it. `mark_fill_color="auto"` mixes 25% of the
|
|
520
|
+
stroke with the axes ground into an opaque tint (`mark_fill_mix=.25`). Use `"stroke"` for a solid
|
|
521
|
+
dot, `"none"` for a hollow circle, or any explicit colour. `mark_fill_alpha` affects only the fill.
|
|
522
|
+
The arms stop at the circle rim, so a transparent interior never reveals a line through its centre;
|
|
523
|
+
intervals shorter than the radius fit inside the circle and have no visible arm beyond it.
|
|
524
|
+
`error_width=1.7` / `error_color` control the arms; `show_error=False` hides them.
|
|
525
|
+
Caps are on by default (`cap_size=3.5`, `cap_width=1.2`); `cap_color` overrides their colour.
|
|
526
|
+
Use `show_caps=False` to remove them. Each endpoint remains individually editable.
|
|
527
|
+
`show_notch=True` cuts two V-shaped notches into the circle's actual outline, at the exact mean.
|
|
528
|
+
`notch_depth` and `notch_height` are in points; the cutouts are transparent on any background.
|
|
529
|
+
|
|
530
|
+
With `units=` every unit keeps a lane and colour derived from the table, never the measured values,
|
|
531
|
+
so different measures from the same table agree even with missing values. Points default to the
|
|
532
|
+
category colour (`point_colors="group"`), with area 13 pt², .06 jitter, .2 pt rims and .45 fill alpha.
|
|
533
|
+
Use `point_colors="shades"` for equal perceptual steps through the palette, interleaved across lanes.
|
|
534
|
+
Paired connectors default on when `units` is supplied (`connect_identical_points_across_x_values="auto"`);
|
|
535
|
+
use `False` to disable them or `True` to require units. They break at missing categories and default to
|
|
536
|
+
.5 pt width, `#5f5f5f`, and .2 alpha. Set `connect_color=None` for the theme's neutral colour.
|
|
537
|
+
These controls are shared with `fluxbox`, whose defaults differ:
|
|
538
|
+
|
|
539
|
+
- `show_individual_points`, `point_size` (points²), `jitter`, `point_edge`, `point_edge_width`,
|
|
540
|
+
`point_fill_alpha` (the rim stays opaque).
|
|
541
|
+
- `palette`, `group_color`, `group_color_position`, `point_colors`, `shade_range`, `interleave_shades`.
|
|
542
|
+
Palettes accept FluxPlot and matplotlib colormaps, discrete palettes, or individual colours;
|
|
543
|
+
mappings choose a palette per category. Defaults cycle through `YlGnBu`, `YlOrRd`, `RdPu`,
|
|
544
|
+
`BuGn`, `Purples`, and `YlOrBr`.
|
|
545
|
+
- `connect_identical_points_across_x_values`, `connect_line_width`, `connect_color`, `connect_alpha`.
|
|
546
|
+
- `order`, `unit_order`, `series`, `unit_series`, `label_axes`, `zorder`.
|
|
547
|
+
|
|
548
|
+
`mark_offset=None` resolves to .25 category units when points or connectors are shown, otherwise zero.
|
|
549
|
+
`mark_side="right"` puts summaries to the right; `"left"` places them to the left,
|
|
550
|
+
and `"outer"` puts the first left and the others right. For horizontal plots those sides are below/above.
|
|
551
|
+
Set `mark_offset=0` to centre all summaries on their category ticks.
|
|
552
|
+
|
|
553
|
+
| part | default SVG id | role / editing kind |
|
|
502
554
|
|---|---|---|
|
|
503
|
-
|
|
|
504
|
-
|
|
|
505
|
-
|
|
|
506
|
-
|
|
|
507
|
-
|
|
|
508
|
-
| points without
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
`
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
`
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
The **fluxbox** is the glowbar with a box plot for its summary — the same call, the same lanes,
|
|
529
|
-
colours, connectors and names, so the two can be swapped for one another dot for dot:
|
|
555
|
+
| mean circle, including its cutout outline | `<category>.mean` | `mean` / shape |
|
|
556
|
+
| lower uncertainty arm | `<category>.error-low` | `errorbar` / line |
|
|
557
|
+
| upper uncertainty arm | `<category>.error-high` | `errorbar` / line |
|
|
558
|
+
| optional lower / upper caps | `<category>.cap-low`, `<category>.cap-high` | `cap` / line |
|
|
559
|
+
| unit points / connector | `<unit>.points`, `<unit>.point.<k>` / `<unit>.line` | `point` / `line` |
|
|
560
|
+
| points without units | `<category>.points`, `<category>.point.<k>` | `point` |
|
|
561
|
+
|
|
562
|
+
`fp.save` writes the SVG, manifest and regeneration recipe together. The manifest lists the circle,
|
|
563
|
+
each arm and each cap as separate components, with `meanmark` statistics (`n`, `mean`, `meanKind`,
|
|
564
|
+
`sd`, `sem`, `interval`, `confidence`, `low`, `high`, `x`, `y`, `categoryPosition`, `orientation`,
|
|
565
|
+
`scale`, `groupColor`, `palette`) and unit identity. IDs persist when caps, points or notches are
|
|
566
|
+
toggled; lower/upper always refer to data values, including on inverted axes. The recipe records
|
|
567
|
+
the producing script; use `fp.params` and `recipe={"params": ...}` to expose adjustable controls
|
|
568
|
+
for Flux regeneration (see `examples/meanmark_example.py`). Geometry lives in the SVG, statistics
|
|
569
|
+
in the manifest, and regeneration settings in the recipe.
|
|
570
|
+
|
|
571
|
+
The return value is `MeanmarkResult` with `.ax`, `.categories`, `.stats`, `.group_colors`,
|
|
572
|
+
`.point_colors`, `.series`, `.unit_series`, `.orientation`, and `.artists`. Artists are grouped under
|
|
573
|
+
`mean`, `error_low`, `error_high`, `cap_low`, `cap_high`, `points`, and `lines`; each summary part
|
|
574
|
+
is an independent matplotlib artist. Vertical plots also support `.positions` and `.brackets(...)`.
|
|
575
|
+
|
|
576
|
+
The **fluxbox** uses a box plot for its summary — the same call, the same lanes,
|
|
577
|
+
colours, connectors and names. Set their shared controls explicitly to preserve the same
|
|
578
|
+
point styling when swapping between them:
|
|
530
579
|
|
|
531
580
|
```python
|
|
532
581
|
fb = fp.fluxbox(df, x="condition", y="APP/GAPDH", units="subject", ax=ax)
|
|
@@ -537,7 +586,7 @@ Beside each group sits a slim box (Q1–Q3), a half-strength wash of the group c
|
|
|
537
586
|
a dark background lifted, only as far as it takes to differ from the box by `median_contrast=30`
|
|
538
587
|
units of perceived lightness, so it reads for any palette and theme; the whiskers (and fliers) share
|
|
539
588
|
that colour, so the box is the only wash. The **mean** is a V-notch cut
|
|
540
|
-
into both edges of the box
|
|
589
|
+
into both edges of the box; a mean outside the box (a strongly skewed
|
|
541
590
|
group) keeps its mark as the same two V's drawn solid, pointing in at the whisker. The capless
|
|
542
591
|
whiskers reach the most extreme observations within `whis` × IQR of the box (`1.5` — Tukey's rule,
|
|
543
592
|
exactly `plt.boxplot`'s whiskers), `"range"`, or a `(low, high)` pair of percentiles. Observations
|
|
@@ -552,7 +601,7 @@ points are hidden (`show_fliers="auto"`).
|
|
|
552
601
|
| median line | `<category>.median` | `median` |
|
|
553
602
|
| mean notch | `<category>.mean` | `mean` |
|
|
554
603
|
| fliers (points hidden) | `<category>.fliers` | `flier` |
|
|
555
|
-
| points / connectors | as for the
|
|
604
|
+
| points / connectors | as for the meanmark | `point` / `line` |
|
|
556
605
|
|
|
557
606
|
Each category series carries a `fluxbox` manifest payload with the exact statistics drawn (`n`,
|
|
558
607
|
`mean`, `median`, `sd`, `sem`, `q1`, `q3`, `iqr`, `whis`, `whiskerLow`, `whiskerHigh`, `outliers`,
|
|
@@ -561,8 +610,8 @@ Each category series carries a `fluxbox` manifest payload with the exact statist
|
|
|
561
610
|
median outright), `median_contrast`, `mean_notch_depth`, `mean_notch_height`, `whisker_width`, `whisker_color`,
|
|
562
611
|
`cap_size`, `cap_width`, `cap_color`, `flier_size`, `cut_color` and
|
|
563
612
|
`show_mean`/`show_median`/`show_whiskers`/`show_caps`/`show_fliers`; every point, colour, connector
|
|
564
|
-
and naming keyword is the
|
|
565
|
-
`
|
|
613
|
+
and naming keyword is the meanmark's. It returns a `FluxboxResult` with the same core fields as a
|
|
614
|
+
`MeanmarkResult` (without `orientation`). `examples/fluxbox_example.py` draws both designs.
|
|
566
615
|
|
|
567
616
|
The **hexmatrix** tiles the plane with regular hexagons, each one a named part. One call covers a
|
|
568
617
|
point cloud's density, a 2D gradient of a third variable, and a matrix drawn on a hex lattice:
|
|
@@ -674,12 +723,12 @@ test above over the pairs of a `{name: sample}` family and corrects across them:
|
|
|
674
723
|
*From rows to brackets* — `fp.brackets(ax, rows, positions=…)` draws one significance bracket per
|
|
675
724
|
post-hoc row and stacks them automatically: shortest span first, each bracket one `step` above the
|
|
676
725
|
data it spans and above every bracket it overlaps in x (multiplicative steps on a log axis), so
|
|
677
|
-
nothing crosses. `positions` maps group name → x; a
|
|
726
|
+
nothing crosses. `positions` maps group name → x; a meanmark / fluxbox result provides it, and
|
|
678
727
|
`gb.brackets(rows)` is the one-liner:
|
|
679
728
|
|
|
680
729
|
```python
|
|
681
730
|
rows = fp.stats.pairwise(fp.stats.welch_hedges, {"ctl": ctl, "drug": drug, "sham": sham})
|
|
682
|
-
gb = fp.
|
|
731
|
+
gb = fp.meanmark(data=df, x="group", y="value", ax=ax)
|
|
683
732
|
gb.brackets(rows) # *** / ** / * / ns from p_corrected_holm
|
|
684
733
|
gb.brackets(rows, label="p", ns=False, p_column="p_corrected_bh") # "p = 0.003", drop ns pairs
|
|
685
734
|
```
|
|
@@ -837,12 +886,12 @@ fluxplot/
|
|
|
837
886
|
brackets.py # fp.brackets: stats rows → stacked significance brackets
|
|
838
887
|
fits.py # fp.regression, fp.kde
|
|
839
888
|
seaborn_adapters.py # exact identity for seaborn's categorical plots and hue splits
|
|
840
|
-
signature_fluxplots/ # preset plot types unique to Flux (fp.
|
|
889
|
+
signature_fluxplots/ # preset plot types unique to Flux (fp.meanmark, fp.fluxbox, fp.hexmatrix)
|
|
841
890
|
stats/ # tests behind the plots, returning reporting rows (two-group, paired, k-group, post hoc)
|
|
842
891
|
schemas/ # JSON Schemas for the manifest and recipe (validated on every save)
|
|
843
892
|
definitions/ # the shipped colormap / palette / token tables
|
|
844
893
|
examples/growth_plot.py # the worked example above
|
|
845
|
-
examples/
|
|
894
|
+
examples/meanmark_example.py # the meanmark signature plot, paired + summary variants
|
|
846
895
|
examples/fluxbox_example.py # the fluxbox signature plot, unpaired + paired
|
|
847
896
|
examples/hexmatrix_example.py # the hexmatrix: joint, log-log, spatial, gradient, lattice map
|
|
848
897
|
examples/image_example.py # a two-channel micrograph with a scale bar and per-channel keys
|
|
@@ -1054,12 +1103,12 @@ Every series records its primary paint in the manifest — `series[].color = {"h
|
|
|
1054
1103
|
"alpha": 1.0, "token": "flexoki.green-400", "palette": {"name": "flexoki.light", "index": 2}}`:
|
|
1055
1104
|
the exact palette token that names it when one does, its slot in the active cycle when it came
|
|
1056
1105
|
from there (`"varies"` for a colour-mapped collection, whose `scale` names the colour scale).
|
|
1057
|
-
The
|
|
1106
|
+
The meanmark and fluxbox payloads record the `palette` spec each category's shades came from.
|
|
1058
1107
|
|
|
1059
1108
|
`fp.colors.categories` keeps categories consistent across figures: `get("SD")` returns the colour
|
|
1060
1109
|
pinned to a category, else assigns the next unused slot of the palette (default: the theme's
|
|
1061
1110
|
cycle) in first-request order and remembers it, so `"b"` is the same colour whether or not `"a"`
|
|
1062
|
-
is on the plot — `categorical_colors` (surface maps),
|
|
1111
|
+
is on the plot — `categorical_colors` (surface maps), meanmark and fluxbox group colours and
|
|
1063
1112
|
`tag_seaborn`'s hue levels all consult it. `assign({...})` pins colours, `save()` / `load()`
|
|
1064
1113
|
write and read a project file, `fluxplot.colors.json`
|
|
1065
1114
|
(`{"spec": "fluxplot/colors", "version": 1, "categories": {"SD": "#bc5215"}, "palette": "flexoki"}`),
|
|
@@ -1067,16 +1116,17 @@ which the first use auto-loads from `$FLUXPLOT_COLORS` or the nearest one betwee
|
|
|
1067
1116
|
directory and the Git root; nothing is ever written implicitly. `categories.auto_series = True`
|
|
1068
1117
|
colours `fp.line` / `fp.scatter` series by their name when the call gives no colour (off by
|
|
1069
1118
|
default). Two more recipe controls follow: `__fluxplot__.palette = "tol.bright"` makes every
|
|
1070
|
-
`fx.use_*` install that palette as the prop cycle (and
|
|
1119
|
+
`fx.use_*` install that palette as the prop cycle (and meanmark categories draw from it), and
|
|
1071
1120
|
`__fluxplot__.series = {"<series id>": {"color": "#…"}}` recolours a series on a rerun — the
|
|
1072
1121
|
helpers and the signature plots check it before drawing.
|
|
1073
1122
|
|
|
1074
1123
|
### Signature plots on dark grounds
|
|
1075
1124
|
|
|
1076
|
-
The
|
|
1125
|
+
The meanmark, fluxbox and hexmatrix judge every ink against the ground they are drawn on. On a
|
|
1077
1126
|
dark theme the point rims lighten instead of darkening, the shades stay at least 20 lightness
|
|
1078
|
-
units above the ground,
|
|
1079
|
-
(`_colour.median_ink
|
|
1127
|
+
units above the ground, and fluxbox's median ink lifts off its box instead of deepening
|
|
1128
|
+
(`_colour.median_ink`). Meanmark derives its circle tint from its stroke and the ground.
|
|
1129
|
+
Connectors take the theme's grid neutral, a
|
|
1080
1130
|
qualitative palette's group ink is the light neutral, and a hexmatrix's single-colour ramp turns
|
|
1081
1131
|
(deep near the ground → pale at the top, named `hexmatrix.mono-dark:#…` so a rerun rebuilds it).
|
|
1082
1132
|
`tests/test_dark_ground.py` pins WCAG contrast ≥ 1.5 for every mark and ≥ 3 for bracket and
|
|
@@ -267,6 +267,24 @@ anchors + a scale type is the complete, portable contract. (FluxPlot computes th
|
|
|
267
267
|
dpi-invariant fraction method that round-trips *exactly* against the positions matplotlib actually
|
|
268
268
|
emits — verified in `NOTES_matplotlib_svg.md`.)
|
|
269
269
|
|
|
270
|
+
### Layout capture — resizing without rerunning Python
|
|
271
|
+
|
|
272
|
+
Schema 0.4 adds a `layout` block, captured after the final SVG-renderer draw while the layout
|
|
273
|
+
is frozen. It records the original engine and GridSpec inputs, axes domains and aspect rules,
|
|
274
|
+
text anchors/extents, font advances, numeric locator/formatter parameters, legends, colorbars
|
|
275
|
+
and coordinate frames. Initial layout inputs are preserved across repeated saves, so the same
|
|
276
|
+
figure remains deterministic even when a draw adjusts its limits or subplot parameters.
|
|
277
|
+
|
|
278
|
+
Flux uses these facts to reflow a placed plot at a new physical size without measuring browser
|
|
279
|
+
text or executing Python. Data follows axes affines; glyphs, typography and stroke widths keep
|
|
280
|
+
their point sizes. Tick values identify existing labels across reticks. The matplotlib oracle in
|
|
281
|
+
`tools/relayout_oracle.py` generates layout, tick and solver truth for the Flux verification gates.
|
|
282
|
+
Date/category/custom (including locale-specific) ticks reposition without reticking. Point-sized glyphs anchored to data keep their point geometry: fluxbox boxes (`box` frames) and meanmark circles, arms and caps (`mark` frames, rebuilt exactly as `_MeanPart.get_path` draws them). Secondary
|
|
283
|
+
axes with affine conversions reflow; non-affine conversions record a named transform refusal. A dynamic major locator that emits no
|
|
284
|
+
native ticks records `ticks:no-template`, since there is no faithful SVG tick template to clone.
|
|
285
|
+
Polar, 3D, subfigures, compressed
|
|
286
|
+
layout, usetex and unsupported transforms record named refusals; their SVG still saves normally.
|
|
287
|
+
|
|
270
288
|
---
|
|
271
289
|
|
|
272
290
|
## Semantic IDs: the universal join key
|
|
@@ -445,58 +463,89 @@ label rather than being dropped.
|
|
|
445
463
|
|
|
446
464
|
**Signature fluxplots** — complete, opinionated plot types that are unique to Flux. They take a
|
|
447
465
|
DataFrame (pandas, polars or a dict of columns) plus column names, seaborn-style, and name every
|
|
448
|
-
part for you.
|
|
466
|
+
part for you. **Meanmark** draws an arithmetic mean as an outlined circle with a tinted
|
|
467
|
+
interior and two uncertainty arms, matching the compact mean-and-error marks used in scientific
|
|
468
|
+
figures:
|
|
449
469
|
|
|
450
470
|
```python
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
471
|
+
mm = fp.meanmark(df, x="condition", y="signal", units="subject", ax=ax)
|
|
472
|
+
# Summary alone, solid dots, 95% Student-t confidence intervals and endpoint caps:
|
|
473
|
+
mm = fp.meanmark(df, x="condition", y="signal", ax=ax,
|
|
474
|
+
show_individual_points=False, interval="ci", confidence=.95,
|
|
475
|
+
mark_fill_color="stroke", show_caps=True)
|
|
454
476
|
```
|
|
455
477
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
478
|
+
The default is a **95% Student-t confidence interval** around the mean (`interval="ci"`,
|
|
479
|
+
`confidence=.95`), using sample SD (`ddof=1`). `"sem"` gives mean ± SEM, `"sd"` gives mean ± SD,
|
|
480
|
+
`"range"` spans the observations, and a
|
|
481
|
+
callable `values -> (low, high)` supplies absolute bounds (finite and containing the mean).
|
|
482
|
+
Statistics count finite observations, without collapsing repeated rows per unit. A singleton has
|
|
483
|
+
an observable mean but no estimable SD/SEM/CI: its circle is drawn with null uncertainty bounds.
|
|
484
|
+
Empty categories retain a tick and have no summary. `orientation="horizontal"` rotates the layout;
|
|
485
|
+
`x` still supplies categories and `y` values. `value_scale="log"` changes the value axis while
|
|
486
|
+
preserving the arithmetic mean in original units; nonpositive data or bounds raise an error.
|
|
487
|
+
|
|
488
|
+
The circle diameter (`mark_size=4.5`) and outline (`mark_edge_width=1.5`) are in points. Its stroke
|
|
489
|
+
uses the group colour unless `mark_color` overrides it. `mark_fill_color="auto"` mixes 25% of the
|
|
490
|
+
stroke with the axes ground into an opaque tint (`mark_fill_mix=.25`). Use `"stroke"` for a solid
|
|
491
|
+
dot, `"none"` for a hollow circle, or any explicit colour. `mark_fill_alpha` affects only the fill.
|
|
492
|
+
The arms stop at the circle rim, so a transparent interior never reveals a line through its centre;
|
|
493
|
+
intervals shorter than the radius fit inside the circle and have no visible arm beyond it.
|
|
494
|
+
`error_width=1.7` / `error_color` control the arms; `show_error=False` hides them.
|
|
495
|
+
Caps are on by default (`cap_size=3.5`, `cap_width=1.2`); `cap_color` overrides their colour.
|
|
496
|
+
Use `show_caps=False` to remove them. Each endpoint remains individually editable.
|
|
497
|
+
`show_notch=True` cuts two V-shaped notches into the circle's actual outline, at the exact mean.
|
|
498
|
+
`notch_depth` and `notch_height` are in points; the cutouts are transparent on any background.
|
|
499
|
+
|
|
500
|
+
With `units=` every unit keeps a lane and colour derived from the table, never the measured values,
|
|
501
|
+
so different measures from the same table agree even with missing values. Points default to the
|
|
502
|
+
category colour (`point_colors="group"`), with area 13 pt², .06 jitter, .2 pt rims and .45 fill alpha.
|
|
503
|
+
Use `point_colors="shades"` for equal perceptual steps through the palette, interleaved across lanes.
|
|
504
|
+
Paired connectors default on when `units` is supplied (`connect_identical_points_across_x_values="auto"`);
|
|
505
|
+
use `False` to disable them or `True` to require units. They break at missing categories and default to
|
|
506
|
+
.5 pt width, `#5f5f5f`, and .2 alpha. Set `connect_color=None` for the theme's neutral colour.
|
|
507
|
+
These controls are shared with `fluxbox`, whose defaults differ:
|
|
508
|
+
|
|
509
|
+
- `show_individual_points`, `point_size` (points²), `jitter`, `point_edge`, `point_edge_width`,
|
|
510
|
+
`point_fill_alpha` (the rim stays opaque).
|
|
511
|
+
- `palette`, `group_color`, `group_color_position`, `point_colors`, `shade_range`, `interleave_shades`.
|
|
512
|
+
Palettes accept FluxPlot and matplotlib colormaps, discrete palettes, or individual colours;
|
|
513
|
+
mappings choose a palette per category. Defaults cycle through `YlGnBu`, `YlOrRd`, `RdPu`,
|
|
514
|
+
`BuGn`, `Purples`, and `YlOrBr`.
|
|
515
|
+
- `connect_identical_points_across_x_values`, `connect_line_width`, `connect_color`, `connect_alpha`.
|
|
516
|
+
- `order`, `unit_order`, `series`, `unit_series`, `label_axes`, `zorder`.
|
|
517
|
+
|
|
518
|
+
`mark_offset=None` resolves to .25 category units when points or connectors are shown, otherwise zero.
|
|
519
|
+
`mark_side="right"` puts summaries to the right; `"left"` places them to the left,
|
|
520
|
+
and `"outer"` puts the first left and the others right. For horizontal plots those sides are below/above.
|
|
521
|
+
Set `mark_offset=0` to centre all summaries on their category ticks.
|
|
522
|
+
|
|
523
|
+
| part | default SVG id | role / editing kind |
|
|
472
524
|
|---|---|---|
|
|
473
|
-
|
|
|
474
|
-
|
|
|
475
|
-
|
|
|
476
|
-
|
|
|
477
|
-
|
|
|
478
|
-
| points without
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
`
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
`
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
The **fluxbox** is the glowbar with a box plot for its summary — the same call, the same lanes,
|
|
499
|
-
colours, connectors and names, so the two can be swapped for one another dot for dot:
|
|
525
|
+
| mean circle, including its cutout outline | `<category>.mean` | `mean` / shape |
|
|
526
|
+
| lower uncertainty arm | `<category>.error-low` | `errorbar` / line |
|
|
527
|
+
| upper uncertainty arm | `<category>.error-high` | `errorbar` / line |
|
|
528
|
+
| optional lower / upper caps | `<category>.cap-low`, `<category>.cap-high` | `cap` / line |
|
|
529
|
+
| unit points / connector | `<unit>.points`, `<unit>.point.<k>` / `<unit>.line` | `point` / `line` |
|
|
530
|
+
| points without units | `<category>.points`, `<category>.point.<k>` | `point` |
|
|
531
|
+
|
|
532
|
+
`fp.save` writes the SVG, manifest and regeneration recipe together. The manifest lists the circle,
|
|
533
|
+
each arm and each cap as separate components, with `meanmark` statistics (`n`, `mean`, `meanKind`,
|
|
534
|
+
`sd`, `sem`, `interval`, `confidence`, `low`, `high`, `x`, `y`, `categoryPosition`, `orientation`,
|
|
535
|
+
`scale`, `groupColor`, `palette`) and unit identity. IDs persist when caps, points or notches are
|
|
536
|
+
toggled; lower/upper always refer to data values, including on inverted axes. The recipe records
|
|
537
|
+
the producing script; use `fp.params` and `recipe={"params": ...}` to expose adjustable controls
|
|
538
|
+
for Flux regeneration (see `examples/meanmark_example.py`). Geometry lives in the SVG, statistics
|
|
539
|
+
in the manifest, and regeneration settings in the recipe.
|
|
540
|
+
|
|
541
|
+
The return value is `MeanmarkResult` with `.ax`, `.categories`, `.stats`, `.group_colors`,
|
|
542
|
+
`.point_colors`, `.series`, `.unit_series`, `.orientation`, and `.artists`. Artists are grouped under
|
|
543
|
+
`mean`, `error_low`, `error_high`, `cap_low`, `cap_high`, `points`, and `lines`; each summary part
|
|
544
|
+
is an independent matplotlib artist. Vertical plots also support `.positions` and `.brackets(...)`.
|
|
545
|
+
|
|
546
|
+
The **fluxbox** uses a box plot for its summary — the same call, the same lanes,
|
|
547
|
+
colours, connectors and names. Set their shared controls explicitly to preserve the same
|
|
548
|
+
point styling when swapping between them:
|
|
500
549
|
|
|
501
550
|
```python
|
|
502
551
|
fb = fp.fluxbox(df, x="condition", y="APP/GAPDH", units="subject", ax=ax)
|
|
@@ -507,7 +556,7 @@ Beside each group sits a slim box (Q1–Q3), a half-strength wash of the group c
|
|
|
507
556
|
a dark background lifted, only as far as it takes to differ from the box by `median_contrast=30`
|
|
508
557
|
units of perceived lightness, so it reads for any palette and theme; the whiskers (and fliers) share
|
|
509
558
|
that colour, so the box is the only wash. The **mean** is a V-notch cut
|
|
510
|
-
into both edges of the box
|
|
559
|
+
into both edges of the box; a mean outside the box (a strongly skewed
|
|
511
560
|
group) keeps its mark as the same two V's drawn solid, pointing in at the whisker. The capless
|
|
512
561
|
whiskers reach the most extreme observations within `whis` × IQR of the box (`1.5` — Tukey's rule,
|
|
513
562
|
exactly `plt.boxplot`'s whiskers), `"range"`, or a `(low, high)` pair of percentiles. Observations
|
|
@@ -522,7 +571,7 @@ points are hidden (`show_fliers="auto"`).
|
|
|
522
571
|
| median line | `<category>.median` | `median` |
|
|
523
572
|
| mean notch | `<category>.mean` | `mean` |
|
|
524
573
|
| fliers (points hidden) | `<category>.fliers` | `flier` |
|
|
525
|
-
| points / connectors | as for the
|
|
574
|
+
| points / connectors | as for the meanmark | `point` / `line` |
|
|
526
575
|
|
|
527
576
|
Each category series carries a `fluxbox` manifest payload with the exact statistics drawn (`n`,
|
|
528
577
|
`mean`, `median`, `sd`, `sem`, `q1`, `q3`, `iqr`, `whis`, `whiskerLow`, `whiskerHigh`, `outliers`,
|
|
@@ -531,8 +580,8 @@ Each category series carries a `fluxbox` manifest payload with the exact statist
|
|
|
531
580
|
median outright), `median_contrast`, `mean_notch_depth`, `mean_notch_height`, `whisker_width`, `whisker_color`,
|
|
532
581
|
`cap_size`, `cap_width`, `cap_color`, `flier_size`, `cut_color` and
|
|
533
582
|
`show_mean`/`show_median`/`show_whiskers`/`show_caps`/`show_fliers`; every point, colour, connector
|
|
534
|
-
and naming keyword is the
|
|
535
|
-
`
|
|
583
|
+
and naming keyword is the meanmark's. It returns a `FluxboxResult` with the same core fields as a
|
|
584
|
+
`MeanmarkResult` (without `orientation`). `examples/fluxbox_example.py` draws both designs.
|
|
536
585
|
|
|
537
586
|
The **hexmatrix** tiles the plane with regular hexagons, each one a named part. One call covers a
|
|
538
587
|
point cloud's density, a 2D gradient of a third variable, and a matrix drawn on a hex lattice:
|
|
@@ -644,12 +693,12 @@ test above over the pairs of a `{name: sample}` family and corrects across them:
|
|
|
644
693
|
*From rows to brackets* — `fp.brackets(ax, rows, positions=…)` draws one significance bracket per
|
|
645
694
|
post-hoc row and stacks them automatically: shortest span first, each bracket one `step` above the
|
|
646
695
|
data it spans and above every bracket it overlaps in x (multiplicative steps on a log axis), so
|
|
647
|
-
nothing crosses. `positions` maps group name → x; a
|
|
696
|
+
nothing crosses. `positions` maps group name → x; a meanmark / fluxbox result provides it, and
|
|
648
697
|
`gb.brackets(rows)` is the one-liner:
|
|
649
698
|
|
|
650
699
|
```python
|
|
651
700
|
rows = fp.stats.pairwise(fp.stats.welch_hedges, {"ctl": ctl, "drug": drug, "sham": sham})
|
|
652
|
-
gb = fp.
|
|
701
|
+
gb = fp.meanmark(data=df, x="group", y="value", ax=ax)
|
|
653
702
|
gb.brackets(rows) # *** / ** / * / ns from p_corrected_holm
|
|
654
703
|
gb.brackets(rows, label="p", ns=False, p_column="p_corrected_bh") # "p = 0.003", drop ns pairs
|
|
655
704
|
```
|
|
@@ -807,12 +856,12 @@ fluxplot/
|
|
|
807
856
|
brackets.py # fp.brackets: stats rows → stacked significance brackets
|
|
808
857
|
fits.py # fp.regression, fp.kde
|
|
809
858
|
seaborn_adapters.py # exact identity for seaborn's categorical plots and hue splits
|
|
810
|
-
signature_fluxplots/ # preset plot types unique to Flux (fp.
|
|
859
|
+
signature_fluxplots/ # preset plot types unique to Flux (fp.meanmark, fp.fluxbox, fp.hexmatrix)
|
|
811
860
|
stats/ # tests behind the plots, returning reporting rows (two-group, paired, k-group, post hoc)
|
|
812
861
|
schemas/ # JSON Schemas for the manifest and recipe (validated on every save)
|
|
813
862
|
definitions/ # the shipped colormap / palette / token tables
|
|
814
863
|
examples/growth_plot.py # the worked example above
|
|
815
|
-
examples/
|
|
864
|
+
examples/meanmark_example.py # the meanmark signature plot, paired + summary variants
|
|
816
865
|
examples/fluxbox_example.py # the fluxbox signature plot, unpaired + paired
|
|
817
866
|
examples/hexmatrix_example.py # the hexmatrix: joint, log-log, spatial, gradient, lattice map
|
|
818
867
|
examples/image_example.py # a two-channel micrograph with a scale bar and per-channel keys
|
|
@@ -1024,12 +1073,12 @@ Every series records its primary paint in the manifest — `series[].color = {"h
|
|
|
1024
1073
|
"alpha": 1.0, "token": "flexoki.green-400", "palette": {"name": "flexoki.light", "index": 2}}`:
|
|
1025
1074
|
the exact palette token that names it when one does, its slot in the active cycle when it came
|
|
1026
1075
|
from there (`"varies"` for a colour-mapped collection, whose `scale` names the colour scale).
|
|
1027
|
-
The
|
|
1076
|
+
The meanmark and fluxbox payloads record the `palette` spec each category's shades came from.
|
|
1028
1077
|
|
|
1029
1078
|
`fp.colors.categories` keeps categories consistent across figures: `get("SD")` returns the colour
|
|
1030
1079
|
pinned to a category, else assigns the next unused slot of the palette (default: the theme's
|
|
1031
1080
|
cycle) in first-request order and remembers it, so `"b"` is the same colour whether or not `"a"`
|
|
1032
|
-
is on the plot — `categorical_colors` (surface maps),
|
|
1081
|
+
is on the plot — `categorical_colors` (surface maps), meanmark and fluxbox group colours and
|
|
1033
1082
|
`tag_seaborn`'s hue levels all consult it. `assign({...})` pins colours, `save()` / `load()`
|
|
1034
1083
|
write and read a project file, `fluxplot.colors.json`
|
|
1035
1084
|
(`{"spec": "fluxplot/colors", "version": 1, "categories": {"SD": "#bc5215"}, "palette": "flexoki"}`),
|
|
@@ -1037,16 +1086,17 @@ which the first use auto-loads from `$FLUXPLOT_COLORS` or the nearest one betwee
|
|
|
1037
1086
|
directory and the Git root; nothing is ever written implicitly. `categories.auto_series = True`
|
|
1038
1087
|
colours `fp.line` / `fp.scatter` series by their name when the call gives no colour (off by
|
|
1039
1088
|
default). Two more recipe controls follow: `__fluxplot__.palette = "tol.bright"` makes every
|
|
1040
|
-
`fx.use_*` install that palette as the prop cycle (and
|
|
1089
|
+
`fx.use_*` install that palette as the prop cycle (and meanmark categories draw from it), and
|
|
1041
1090
|
`__fluxplot__.series = {"<series id>": {"color": "#…"}}` recolours a series on a rerun — the
|
|
1042
1091
|
helpers and the signature plots check it before drawing.
|
|
1043
1092
|
|
|
1044
1093
|
### Signature plots on dark grounds
|
|
1045
1094
|
|
|
1046
|
-
The
|
|
1095
|
+
The meanmark, fluxbox and hexmatrix judge every ink against the ground they are drawn on. On a
|
|
1047
1096
|
dark theme the point rims lighten instead of darkening, the shades stay at least 20 lightness
|
|
1048
|
-
units above the ground,
|
|
1049
|
-
(`_colour.median_ink
|
|
1097
|
+
units above the ground, and fluxbox's median ink lifts off its box instead of deepening
|
|
1098
|
+
(`_colour.median_ink`). Meanmark derives its circle tint from its stroke and the ground.
|
|
1099
|
+
Connectors take the theme's grid neutral, a
|
|
1050
1100
|
qualitative palette's group ink is the light neutral, and a hexmatrix's single-colour ramp turns
|
|
1051
1101
|
(deep near the ground → pale at the top, named `hexmatrix.mono-dark:#…` so a rerun rebuilds it).
|
|
1052
1102
|
`tests/test_dark_ground.py` pins WCAG contrast ≥ 1.5 for every mark and ≥ 3 for bracket and
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""The fluxbox —
|
|
1
|
+
"""The fluxbox — a box plot with individual observations, in two designs.
|
|
2
2
|
|
|
3
3
|
* ``out/fluxbox.svg`` two independent groups, one dot per animal (fixed lane + colour per animal)
|
|
4
4
|
* ``out/fluxbox_paired.svg`` the same animals measured twice, joined across conditions
|