anyplotlib 0.7.0__tar.gz → 0.7.1__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.
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/CHANGELOG.rst +22 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/PKG-INFO +1 -1
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/figure/_figure.py +27 -3
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/keys.py +5 -8
- anyplotlib-0.7.1/anyplotlib/tests/test_embed/test_export_pixel_tokens.py +174 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_root/index.html +3 -3
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_root/switcher.json +5 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/conf.py +1 -1
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/pyproject.toml +1 -1
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.github/workflows/ci.yml +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.github/workflows/docs.yml +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.github/workflows/prepare_release.yml +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.github/workflows/release.yml +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.github/workflows/tests.yml +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/.gitignore +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/AGENTS.md +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Benchmarks/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Benchmarks/plot_benchmark_comparison.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_3d_spectral_viewer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_eels_explorer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_figure_annotations.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_interactive_fft.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_interactive_fitting.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_ipf_density_map.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_ipf_explorer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_key_bindings.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_particle_picker.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_point_widget.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_segment_by_contrast.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_segment_by_contrast_advanced.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_spectra_roi_inspector.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_star_globe_explorer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_threshold_explorer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_voxel_grain_explorer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_arrows.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_circles.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_ellipses.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_horizontal_lines.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_line_segments.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_points.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_polygons.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_rectangles.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_squares.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_texts.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_transform_markers.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Markers/plot_vertical_lines.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_3d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_3d_texture.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_bar.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_gpu_voxels.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_gridspec_custom.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_image2d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_inset.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_key_overlays.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_label_formatting.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_line_styles.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_pcolormesh.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_spectra1d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_step_and_log.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_tile_backend.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/PlotTypes/plot_twinx.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget1d_hline.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget1d_point.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget1d_range.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget1d_vline.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_annular.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_arrow.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_circle.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_crosshair.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_label.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_polygon.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget2d_rectangle.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Widgets/plot_widget3d_plane.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/LICENSE +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/Makefile +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/README.md +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/FIGURE_ESM.md +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/_base_plot.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/_binary_frame.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/_electron.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/_repr_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/axes/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/axes/_axes.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/axes/_inset_axes.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/callbacks.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/conftest.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/embed.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/figure/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/figure/_gridspec.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/figure/_subplots.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/figure_esm.js +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/markers.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot1d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot1d/_plot1d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot1d/_plotbar.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot2d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot2d/_layer.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot2d/_plot2d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot2d/_plotmesh.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot2d/_tile_backend.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot3d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plot3d/_plot3d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plotxy/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/plotxy/_plotxy.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/_directive.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/_repr_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/_scraper.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/_wheel_builder.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/static/anywidget_bridge.js +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/static/anywidget_overlay.css +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/conftest.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/test_directive.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/test_init.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/test_repr_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/test_scraper.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/sphinx_anywidget/tests/test_wheel_builder.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/_gpu_clim_check.cjs +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/_png_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/bar_basic.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_3col_equal_spectra.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_asymmetric_width_ratios.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_height_ratio_image_histogram.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_image_two_spectra.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_side_by_side_1d.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/gridspec_spanning_top_two_bottom.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/imshow_axis_off.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/imshow_checkerboard.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/imshow_gradient.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/imshow_labels.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/imshow_viridis.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_1d.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_maximized.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_minimized.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_normal_2d.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_stacked.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/inset_stacked_one_minimized.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/pcolormesh_uniform.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_all_linestyles.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_alpha.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_axis_off.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_dashed.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_marker_symbols.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_markers.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_multi.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_sine.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_title.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot1d_twinx.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/plot3d_surface.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/baselines/subplots_2x1.png +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/conftest.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_benchmarks/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_benchmarks/baselines.json +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_benchmarks/benchmarks/baselines.json +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_benchmarks/test_benchmarks.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_benchmarks/test_benchmarks_py.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_documentation/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_documentation/test_bridge.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_documentation/test_push_hook.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_documentation/test_scraper.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_electron/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_electron/test_binary_frame.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_embed/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_embed/test_embed_api.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_embed/test_embed_mount.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_embed/test_export_png.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_embed/test_export_widget_sync.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_examples/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_examples/test_interactive_examples.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/_event_test_utils.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_blit_audit.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_callbacks_playwright.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_callbacks_unit.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_edit_chrome.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_edit_chrome_playwright.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_event_pause_hold.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_event_plots.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_event_settled.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_events_regression.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_orbit_direction.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_pointer_down_1d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_range_orientation_snap.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_star_globe_linking.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_tile_parity_playwright.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_title.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_touch.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_widget_brush.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_widget_max_extent.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_widget_set_notify.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_widgets.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_interactive/test_widgets_line_2d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_keys/test_keys.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_labels/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_labels/test_label_api.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_labels/test_label_rendering.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_labels/test_no_clipping.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_labels/test_ylabel_clearance.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_batch.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_coord_conversion.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_geom_channel.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_gridspec.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_inset.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_inset_callout.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_interaction.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_layouts/test_visual.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_markers/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_markers/test_marker_transforms.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_markers/test_markers.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_markers/test_per_marker_colors.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_markers/test_size_units.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot1d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot1d/test_line_none_rendering.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot1d/test_plot1d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot1d/test_plotbar.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_colorbar_gap_scalebar.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_detail_tile.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_first_paint_race.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_gpu_image.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_gpu_parity_playwright.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_imshow.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_imshow_rgb.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_layers.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_layers_playwright.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_pcolormesh.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_plot2d_api.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_rapid_frame_update.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_tile_backend.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_tile_diagnostics.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_tiled_imshow.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot2d/test_zoom_view_write.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_colors_highlight.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_gpu_depth.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_gpu_fallback.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_gpu_hidden_reveal.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_plot3d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_texture.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plot3d/test_voxels_planes.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/tests/test_plotxy/test_plotxy.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/widgets/__init__.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/widgets/_base.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/widgets/_widgets1d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/widgets/_widgets2d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/anyplotlib/widgets/_widgets3d.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_sg_html_scraper.py +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_static/anyplotlib.svg +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_static/custom.css +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_static/pyodide_bridge.js +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/_templates/autosummary/class.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/callbacks.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/figure.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/figure_plots.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/index.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/keys.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/markers.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/api/widgets.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/benchmarking.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/dev/index.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/embedding.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/events.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/getting_started.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/docs/index.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/make.bat +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/upcoming_changes/.gitkeep +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/upcoming_changes/README.rst +0 -0
- {anyplotlib-0.7.0 → anyplotlib-0.7.1}/uv.lock +0 -0
|
@@ -10,6 +10,28 @@ Fragment files in ``upcoming_changes/`` are assembled into this file by
|
|
|
10
10
|
|
|
11
11
|
.. towncrier release notes start
|
|
12
12
|
|
|
13
|
+
0.7.1 (2026-08-02)
|
|
14
|
+
==================
|
|
15
|
+
|
|
16
|
+
Bug Fixes
|
|
17
|
+
---------
|
|
18
|
+
|
|
19
|
+
- Fixed ``save_html`` / ``to_html`` / ``figure_state`` dropping image pixels
|
|
20
|
+
under the Electron binary transport: the snapshot kept the ``"\x00bin:"``
|
|
21
|
+
change-tokens whose bytes only ever ride the live PLOTBIN channel, so an
|
|
22
|
+
overlay added with :meth:`~anyplotlib.Plot2D.add_layer` did not render in the
|
|
23
|
+
exported document. (`#52 <https://github.com/CSSFrancis/anyplotlib/pull/52>`_)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Documentation
|
|
27
|
+
-------------
|
|
28
|
+
|
|
29
|
+
- Fixed the documentation build failing on
|
|
30
|
+
:class:`~anyplotlib.keys.KeyOverlay`, whose ``id`` and ``name`` were described
|
|
31
|
+
both in the class docstring and by the properties themselves — a duplicate
|
|
32
|
+
object description, which the build treats as an error. (`#53 <https://github.com/CSSFrancis/anyplotlib/pull/53>`_)
|
|
33
|
+
|
|
34
|
+
|
|
13
35
|
0.7.0 (2026-07-31)
|
|
14
36
|
==================
|
|
15
37
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anyplotlib
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: A plotting library using python, javascript and anywidget for performant in browser plotting.
|
|
5
5
|
Project-URL: Homepage, https://cssfrancis.github.io/anyplotlib/
|
|
6
6
|
Project-URL: Repository, https://github.com/CSSFrancis/anyplotlib
|
|
@@ -300,7 +300,7 @@ class Figure(anywidget.AnyWidget, _EventMixin):
|
|
|
300
300
|
self._push(pid)
|
|
301
301
|
self._push_layout()
|
|
302
302
|
|
|
303
|
-
def _push(self, panel_id: str) -> None:
|
|
303
|
+
def _push(self, panel_id: str, *, resolve_pixels: bool = False) -> None:
|
|
304
304
|
"""Serialise one panel and write to its trait.
|
|
305
305
|
|
|
306
306
|
Inside a :meth:`batch` block, pushes are coalesced: each panel is
|
|
@@ -309,6 +309,14 @@ class Figure(anywidget.AnyWidget, _EventMixin):
|
|
|
309
309
|
many per-frame pushes of a linked-view update (set_data + set_title +
|
|
310
310
|
widget moves on the same panel) into one serialise/transfer per panel
|
|
311
311
|
— the dominant cost over a Pyodide comm boundary.
|
|
312
|
+
|
|
313
|
+
Parameters
|
|
314
|
+
----------
|
|
315
|
+
resolve_pixels : bool, optional
|
|
316
|
+
Force pixel change-tokens to be materialised to inline base64 even
|
|
317
|
+
when the binary transport is live. Set by :meth:`_sync_for_export`
|
|
318
|
+
because a snapshot has no PLOTBIN channel to carry the bytes; see
|
|
319
|
+
the token discussion below.
|
|
312
320
|
"""
|
|
313
321
|
plot = self._plots_map.get(panel_id)
|
|
314
322
|
if plot is None:
|
|
@@ -329,7 +337,15 @@ class Figure(anywidget.AnyWidget, _EventMixin):
|
|
|
329
337
|
# save_html / Jupyter figure with no binary channel — materialise the
|
|
330
338
|
# real base64 inline so the pixels actually travel. ``_binary_wire``
|
|
331
339
|
# matches the producer's gate (``Plot2D._encode_pixels``).
|
|
332
|
-
|
|
340
|
+
#
|
|
341
|
+
# ``resolve_pixels`` overrides that gate for an EXPORT. A snapshot is by
|
|
342
|
+
# definition off-wire: whatever PLOTBIN would have delivered never
|
|
343
|
+
# arrives, so a token left in the state is a dangling reference and the
|
|
344
|
+
# pixels are simply lost. The gate reads a process-global env var, which
|
|
345
|
+
# is on in a host app even while THIS push is serialising a snapshot —
|
|
346
|
+
# so the export has to say so explicitly.
|
|
347
|
+
if (geom_keys and (resolve_pixels or not _binary_wire())
|
|
348
|
+
and hasattr(plot, "resolve_pixel_tokens")):
|
|
333
349
|
plot.resolve_pixel_tokens(state)
|
|
334
350
|
if geom_keys and self.has_trait(gname):
|
|
335
351
|
# Split heavy geometry into its own channel. Detect change by
|
|
@@ -814,9 +830,17 @@ class Figure(anywidget.AnyWidget, _EventMixin):
|
|
|
814
830
|
Called from ``_repr_utils._widget_state``, the one chokepoint every
|
|
815
831
|
export path goes through. The live Jupyter path deliberately keeps
|
|
816
832
|
using targeted pushes and does not pay this cost.
|
|
833
|
+
|
|
834
|
+
The re-push passes ``resolve_pixels=True``: this rewrites the panel
|
|
835
|
+
traits, and under a live binary transport an ordinary push leaves pixel
|
|
836
|
+
change-tokens in place for PLOTBIN to fill in. A snapshot has no
|
|
837
|
+
PLOTBIN, so those tokens would be dangling — and because the re-push
|
|
838
|
+
rewrites ``panel_<id>_json`` unconditionally it would also undo any
|
|
839
|
+
materialisation the caller did beforehand. An export always ships real
|
|
840
|
+
pixels.
|
|
817
841
|
"""
|
|
818
842
|
for panel_id in list(self._plots_map):
|
|
819
|
-
self._push(panel_id)
|
|
843
|
+
self._push(panel_id, resolve_pixels=True)
|
|
820
844
|
|
|
821
845
|
def _push_panel_fields(self, panel_id: str, fields: dict) -> None:
|
|
822
846
|
"""Apply a small set of changed *fields* to a panel, then push once.
|
|
@@ -37,14 +37,6 @@ class KeyOverlay:
|
|
|
37
37
|
key = plot.add_key(ipf_triangle, corner="bottom-right")
|
|
38
38
|
key.set(size=0.3, bgcolor="none")
|
|
39
39
|
key.visible = False # plain attribute assignment also pushes
|
|
40
|
-
|
|
41
|
-
Attributes
|
|
42
|
-
----------
|
|
43
|
-
id : str
|
|
44
|
-
Short unique identifier.
|
|
45
|
-
name : str
|
|
46
|
-
Caller-supplied name, or the id when none was given. Use it with
|
|
47
|
-
:meth:`~anyplotlib.Plot2D.get_key`.
|
|
48
40
|
"""
|
|
49
41
|
|
|
50
42
|
#: Fields that live on the light view channel. The image itself does NOT
|
|
@@ -68,10 +60,15 @@ class KeyOverlay:
|
|
|
68
60
|
|
|
69
61
|
@property
|
|
70
62
|
def id(self) -> str:
|
|
63
|
+
"""Short unique identifier."""
|
|
71
64
|
return self._id
|
|
72
65
|
|
|
73
66
|
@property
|
|
74
67
|
def name(self) -> str:
|
|
68
|
+
"""Caller-supplied name, or the id when none was given.
|
|
69
|
+
|
|
70
|
+
Use it with :meth:`~anyplotlib.Plot2D.get_key`.
|
|
71
|
+
"""
|
|
75
72
|
return self._name
|
|
76
73
|
|
|
77
74
|
# ── attribute access ──────────────────────────────────────────────
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Snapshots must carry real pixels, never a dangling binary change-token.
|
|
3
|
+
|
|
4
|
+
Under the Electron binary transport (``APL_BINARY_TRANSPORT=1``) a panel's
|
|
5
|
+
image bytes do not travel in the state at all: ``Plot2D._encode_pixels`` writes
|
|
6
|
+
a ``"\\x00bin:<adler>"`` change-token and the real bytes ride a PLOTBIN frame
|
|
7
|
+
emitted by ``_electron._route_change``. That split is right for a live wire and
|
|
8
|
+
wrong for a snapshot — ``save_html`` / ``to_html`` / ``figure_state`` produce a
|
|
9
|
+
document with no PLOTBIN behind it, so a token left in the state resolves to
|
|
10
|
+
nothing and the pixels are simply lost.
|
|
11
|
+
|
|
12
|
+
``Figure._sync_for_export`` therefore re-pushes with ``resolve_pixels=True``.
|
|
13
|
+
It has to say so explicitly because the transport gate is a process-global env
|
|
14
|
+
var, which is on in a host app even while that push is serialising a snapshot.
|
|
15
|
+
|
|
16
|
+
Regression: the re-push (added for widget-position capture) rewrote
|
|
17
|
+
``panel_<id>_json`` unconditionally with unresolved tokens, which both lost the
|
|
18
|
+
pixels and undid any materialisation a caller had done beforehand. An overlay
|
|
19
|
+
LAYER was the visible casualty — ``_layerBytes`` in figure_esm.js bails on a
|
|
20
|
+
token (``b64.charCodeAt(0) === 0``), so the layer silently did not draw while
|
|
21
|
+
the base image, which is plain base64, still did.
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
|
|
27
|
+
import numpy as np
|
|
28
|
+
import pytest
|
|
29
|
+
|
|
30
|
+
import anyplotlib as apl
|
|
31
|
+
from anyplotlib.embed import figure_state
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
TOKEN = "\x00bin:"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.fixture
|
|
38
|
+
def binary_wire(monkeypatch):
|
|
39
|
+
"""Turn on the same env gate the Electron host sets."""
|
|
40
|
+
monkeypatch.setenv("APL_BINARY_TRANSPORT", "1")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _fig_with_layer():
|
|
44
|
+
"""A base image + one overlay layer, both on the token path.
|
|
45
|
+
|
|
46
|
+
``imshow`` encodes the base BEFORE the plot is attached to its Figure, so
|
|
47
|
+
``_encode_pixels`` finds no ``_raw_pixels`` side-table and falls back to
|
|
48
|
+
base64 for it; ``add_layer`` runs after the attach and does produce a token.
|
|
49
|
+
One ``set_data`` puts the base on the token path too — the state a live host
|
|
50
|
+
is actually in once anything has redrawn. (That asymmetry is why the
|
|
51
|
+
regression looked so odd in the wild: the base image still rendered and only
|
|
52
|
+
the overlay vanished.)
|
|
53
|
+
"""
|
|
54
|
+
img = np.linspace(0, 1, 32 * 32, dtype=np.float32).reshape(32, 32)
|
|
55
|
+
fig, ax = apl.subplots(1, 1, figsize=(300, 300))
|
|
56
|
+
plot = ax.imshow(img, cmap="gray")
|
|
57
|
+
plot.add_layer(img, cmap="magma", alpha=0.5)
|
|
58
|
+
plot.set_data(img)
|
|
59
|
+
return fig, plot
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _panel(state, plot):
|
|
63
|
+
return json.loads(state[f"panel_{plot._id}_json"])
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _geom(state, plot):
|
|
67
|
+
return json.loads(state[f"panel_{plot._id}_geom"])
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _is_b64(value):
|
|
71
|
+
return isinstance(value, str) and value != "" and not value.startswith(TOKEN)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class TestSnapshotResolvesPixelTokens:
|
|
75
|
+
def test_producer_really_emits_tokens(self, binary_wire):
|
|
76
|
+
"""Guard the premise: without this, the tests below prove nothing."""
|
|
77
|
+
fig, plot = _fig_with_layer()
|
|
78
|
+
state = plot.to_state_dict()
|
|
79
|
+
assert state["image_b64"].startswith(TOKEN)
|
|
80
|
+
assert state["layers"][0]["image_b64"].startswith(TOKEN)
|
|
81
|
+
|
|
82
|
+
def test_base_image_is_inline_base64(self, binary_wire):
|
|
83
|
+
fig, plot = _fig_with_layer()
|
|
84
|
+
assert _is_b64(_geom(figure_state(fig), plot)["image_b64"])
|
|
85
|
+
|
|
86
|
+
def test_layer_pixels_are_inline_base64(self, binary_wire):
|
|
87
|
+
"""The nested copy is the one figure_esm.js `_layerBytes` reads."""
|
|
88
|
+
fig, plot = _fig_with_layer()
|
|
89
|
+
layer = _panel(figure_state(fig), plot)["layers"][0]
|
|
90
|
+
assert _is_b64(layer["image_b64"])
|
|
91
|
+
|
|
92
|
+
def test_layer_geom_key_is_inline_base64(self, binary_wire):
|
|
93
|
+
fig, plot = _fig_with_layer()
|
|
94
|
+
geom = _geom(figure_state(fig), plot)
|
|
95
|
+
assert _is_b64(geom[f"layer_{plot._state['layers'][0]['id']}_b64"])
|
|
96
|
+
|
|
97
|
+
def test_no_token_survives_anywhere_in_the_snapshot(self, binary_wire):
|
|
98
|
+
fig, plot = _fig_with_layer()
|
|
99
|
+
blob = json.dumps(figure_state(fig))
|
|
100
|
+
# json.dumps escapes NUL as \\u0000.
|
|
101
|
+
assert "\\u0000bin:" not in blob
|
|
102
|
+
|
|
103
|
+
def test_caller_materialisation_is_not_undone(self, binary_wire):
|
|
104
|
+
"""A host that resolves the traits itself before exporting keeps them.
|
|
105
|
+
|
|
106
|
+
``_sync_for_export`` rewrites ``panel_<id>_json`` unconditionally, so an
|
|
107
|
+
unresolved re-push would clobber the caller's work — the exact shape of
|
|
108
|
+
the reported regression.
|
|
109
|
+
"""
|
|
110
|
+
fig, plot = _fig_with_layer()
|
|
111
|
+
state = plot.to_state_dict()
|
|
112
|
+
plot.resolve_pixel_tokens(state)
|
|
113
|
+
resolved = state["layers"][0]["image_b64"]
|
|
114
|
+
setattr(fig, f"panel_{plot._id}_json", json.dumps(state))
|
|
115
|
+
|
|
116
|
+
after = _panel(figure_state(fig), plot)["layers"][0]["image_b64"]
|
|
117
|
+
assert after == resolved
|
|
118
|
+
|
|
119
|
+
def test_multi_layer_all_resolved(self, binary_wire):
|
|
120
|
+
img = np.linspace(0, 1, 16 * 16, dtype=np.float32).reshape(16, 16)
|
|
121
|
+
fig, ax = apl.subplots(1, 1, figsize=(300, 300))
|
|
122
|
+
plot = ax.imshow(img, cmap="gray")
|
|
123
|
+
for cmap in ("magma", "cividis", "plasma"):
|
|
124
|
+
plot.add_layer(img, cmap=cmap, alpha=0.4)
|
|
125
|
+
layers = _panel(figure_state(fig), plot)["layers"]
|
|
126
|
+
assert len(layers) == 3
|
|
127
|
+
assert all(_is_b64(ly["image_b64"]) for ly in layers)
|
|
128
|
+
|
|
129
|
+
def test_widget_positions_still_reconciled(self, binary_wire):
|
|
130
|
+
"""The pixel fix must not cost the reason _sync_for_export exists."""
|
|
131
|
+
fig, plot = _fig_with_layer()
|
|
132
|
+
widget = plot.add_widget("rectangle", x=2, y=2, w=4, h=4)
|
|
133
|
+
widget.set(x=21, y=23)
|
|
134
|
+
got = _panel(figure_state(fig), plot)["overlay_widgets"][0]
|
|
135
|
+
assert got["x"] == 21 and got["y"] == 23
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TestLiveWireStillUsesTokens:
|
|
139
|
+
"""The live path must keep its token/PLOTBIN split — that is the whole
|
|
140
|
+
point of the binary transport, and resolving there would push megabytes of
|
|
141
|
+
base64 through the comm on every scrub frame."""
|
|
142
|
+
|
|
143
|
+
def test_ordinary_push_keeps_the_token(self, binary_wire):
|
|
144
|
+
fig, plot = _fig_with_layer()
|
|
145
|
+
fig._push(plot._id)
|
|
146
|
+
geom = json.loads(getattr(fig, f"panel_{plot._id}_geom"))
|
|
147
|
+
assert geom["image_b64"].startswith(TOKEN)
|
|
148
|
+
layer_key = f"layer_{plot._state['layers'][0]['id']}_b64"
|
|
149
|
+
assert geom[layer_key].startswith(TOKEN)
|
|
150
|
+
|
|
151
|
+
def test_set_data_keeps_the_token(self, binary_wire):
|
|
152
|
+
fig, plot = _fig_with_layer()
|
|
153
|
+
plot.set_data(np.zeros((32, 32), dtype=np.float32))
|
|
154
|
+
geom = json.loads(getattr(fig, f"panel_{plot._id}_geom"))
|
|
155
|
+
assert geom["image_b64"].startswith(TOKEN)
|
|
156
|
+
|
|
157
|
+
def test_push_after_export_returns_to_tokens(self, binary_wire):
|
|
158
|
+
"""An export must not leave the live wire on the base64 path."""
|
|
159
|
+
fig, plot = _fig_with_layer()
|
|
160
|
+
figure_state(fig)
|
|
161
|
+
plot.set_data(np.ones((32, 32), dtype=np.float32))
|
|
162
|
+
geom = json.loads(getattr(fig, f"panel_{plot._id}_geom"))
|
|
163
|
+
assert geom["image_b64"].startswith(TOKEN)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class TestNoBinaryTransport:
|
|
167
|
+
"""With no binary wire the state was always inline base64; keep it so."""
|
|
168
|
+
|
|
169
|
+
def test_snapshot_is_inline_base64(self, monkeypatch):
|
|
170
|
+
monkeypatch.delenv("APL_BINARY_TRANSPORT", raising=False)
|
|
171
|
+
fig, plot = _fig_with_layer()
|
|
172
|
+
layer = _panel(figure_state(fig), plot)["layers"][0]
|
|
173
|
+
assert _is_b64(layer["image_b64"])
|
|
174
|
+
assert _is_b64(_geom(figure_state(fig), plot)["image_b64"])
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<title>anyplotlib – redirecting…</title>
|
|
6
6
|
<!-- Redirect to the latest dev docs. -->
|
|
7
|
-
<meta http-equiv="refresh" content="0; url=v0.7.
|
|
8
|
-
<link rel="canonical" href="v0.7.
|
|
7
|
+
<meta http-equiv="refresh" content="0; url=v0.7.1/" />
|
|
8
|
+
<link rel="canonical" href="v0.7.1/" />
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<p>
|
|
12
|
-
Redirecting to <a href="v0.7.
|
|
12
|
+
Redirecting to <a href="v0.7.1/">v0.7.1 documentation</a>…
|
|
13
13
|
</p>
|
|
14
14
|
</body>
|
|
15
15
|
</html>
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
"version": "dev",
|
|
5
5
|
"url": "https://cssfrancis.github.io/anyplotlib/dev/"
|
|
6
6
|
},
|
|
7
|
+
{
|
|
8
|
+
"name": "v0.7.1 (stable)",
|
|
9
|
+
"version": "v0.7.1",
|
|
10
|
+
"url": "https://cssfrancis.github.io/anyplotlib/v0.7.1/"
|
|
11
|
+
},
|
|
7
12
|
{
|
|
8
13
|
"name": "v0.7.0 (stable)",
|
|
9
14
|
"version": "v0.7.0",
|
|
@@ -17,7 +17,7 @@ from _sg_html_scraper import ViewerScraper # noqa: E402
|
|
|
17
17
|
project = "anyplotlib"
|
|
18
18
|
copyright = "2026, anyplotlib contributors"
|
|
19
19
|
author = "anyplotlib contributors"
|
|
20
|
-
release = "0.7.
|
|
20
|
+
release = "0.7.1"
|
|
21
21
|
|
|
22
22
|
# When built in CI the workflow sets DOCS_VERSION to the tag name (e.g.
|
|
23
23
|
# "v0.1.0") or "dev". Fall back to "dev" for local builds.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anyplotlib-0.7.0 → anyplotlib-0.7.1}/Examples/Interactive/plot_segment_by_contrast_advanced.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|