anyplotlib 0.8.0__tar.gz → 0.10.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.
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/AGENTS.md +3 -3
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/CHANGELOG.rst +133 -0
- anyplotlib-0.10.0/Examples/PlotTypes/plot_aspect_ratio.py +77 -0
- anyplotlib-0.10.0/Examples/PlotTypes/plot_subplots_adjust.py +90 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/PKG-INFO +1 -1
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/FIGURE_ESM.md +459 -99
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_base_plot.py +99 -4
- anyplotlib-0.10.0/anyplotlib/_export.py +262 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_repr_utils.py +70 -33
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_utils.py +14 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/_axes.py +8 -2
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/callbacks.py +4 -0
- anyplotlib-0.10.0/anyplotlib/embed.py +457 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_figure.py +109 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure_esm.js +2454 -166
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/markers.py +34 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/_plot1d.py +16 -1
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_plot2d.py +240 -15
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_plotmesh.py +11 -1
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_tile_backend.py +45 -16
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_scraper.py +13 -52
- anyplotlib-0.10.0/anyplotlib/tests/baselines/imshow_labels.png +0 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/_export_utils.py +71 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/conftest.py +80 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_3d.py +328 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_api.py +269 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_escaping.py +139 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_navigated.py +906 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_set_image.py +306 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_export_menu.py +523 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_png.py +14 -80
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_export_sources.py +386 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_savefig.py +290 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_markers/test_text_style.py +146 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_axis_ticks.py +205 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_colorbar_values.py +298 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_imshow.py +13 -10
- anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_pointer_pixel_centre.py +168 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_status_pixel_value.py +730 -0
- anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_tile_backend.py +199 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_root/index.html +3 -3
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_root/switcher.json +10 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/conf.py +1 -1
- anyplotlib-0.10.0/docs/embedding.rst +445 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/events.rst +92 -0
- anyplotlib-0.10.0/docs/exporting.rst +218 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/index.rst +12 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/pyproject.toml +1 -1
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/uv.lock +1 -1
- anyplotlib-0.8.0/anyplotlib/embed.py +0 -194
- anyplotlib-0.8.0/anyplotlib/tests/baselines/imshow_labels.png +0 -0
- anyplotlib-0.8.0/anyplotlib/tests/test_embed/test_embed_api.py +0 -133
- anyplotlib-0.8.0/anyplotlib/tests/test_plot2d/test_tile_backend.py +0 -99
- anyplotlib-0.8.0/docs/embedding.rst +0 -181
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/ci.yml +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/docs.yml +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/prepare_release.yml +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/release.yml +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/tests.yml +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.gitignore +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Benchmarks/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Benchmarks/plot_benchmark_comparison.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_3d_spectral_viewer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_eels_explorer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_figure_annotations.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_interactive_fft.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_interactive_fitting.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_ipf_density_map.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_ipf_explorer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_key_bindings.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_particle_picker.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_point_widget.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_segment_by_contrast.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_segment_by_contrast_advanced.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_spectra_roi_inspector.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_star_globe_explorer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_threshold_explorer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_voxel_grain_explorer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_arrows.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_circles.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_ellipses.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_horizontal_lines.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_line_segments.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_points.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_polygons.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_rectangles.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_squares.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_texts.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_transform_markers.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_vertical_lines.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_3d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_3d_texture.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_bar.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_gpu_voxels.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_gridspec_custom.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_image2d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_inset.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_key_overlays.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_label_formatting.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_line_styles.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_pcolormesh.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_spectra1d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_step_and_log.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_tile_backend.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_twinx.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/README.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_hline.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_point.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_range.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_vline.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_annular.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_arrow.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_circle.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_crosshair.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_label.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_polygon.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_rectangle.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget3d_plane.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/LICENSE +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Makefile +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/README.md +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_binary_frame.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_electron.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/_inset_axes.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/conftest.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_gridspec.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_subplots.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/keys.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/_plotbar.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_layer.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot3d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot3d/_plot3d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plotxy/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plotxy/_plotxy.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_directive.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_repr_utils.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_wheel_builder.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/static/anywidget_bridge.js +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/static/anywidget_overlay.css +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/conftest.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_directive.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_init.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_repr_utils.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_scraper.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_wheel_builder.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/_gpu_clim_check.cjs +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/_png_utils.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/bar_basic.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_3col_equal_spectra.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_asymmetric_width_ratios.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_height_ratio_image_histogram.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_image_two_spectra.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_side_by_side_1d.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_spanning_top_two_bottom.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_axis_off.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_checkerboard.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_gradient.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_viridis.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_1d.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_maximized.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_minimized.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_normal_2d.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_stacked.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_stacked_one_minimized.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/pcolormesh_uniform.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_all_linestyles.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_alpha.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_axis_off.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_dashed.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_marker_symbols.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_markers.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_multi.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_sine.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_title.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_twinx.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot3d_surface.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/subplots_2x1.png +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/conftest.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/baselines.json +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/benchmarks/baselines.json +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/test_benchmarks.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/test_benchmarks_py.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_bridge.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_push_hook.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_scraper.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_electron/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_electron/test_binary_frame.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_embed_mount.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_pixel_tokens.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_widget_sync.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_examples/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_examples/test_interactive_examples.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/_event_test_utils.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_blit_audit.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_callbacks_playwright.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_callbacks_unit.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_circle_lock_center.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_edit_chrome.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_edit_chrome_playwright.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_pause_hold.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_plots.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_settled.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_events_regression.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_orbit_direction.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_pointer_down_1d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_range_orientation_snap.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_star_globe_linking.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_tile_parity_playwright.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_title.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_touch.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_brush.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_max_extent.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_set_notify.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widgets.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widgets_line_2d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_keys/test_keys.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_label_api.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_label_rendering.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_no_clipping.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_ylabel_clearance.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_batch.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_coord_conversion.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_geom_channel.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_gridspec.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_inset.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_inset_callout.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_interaction.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_visual.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_marker_transforms.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_markers.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_per_marker_colors.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_size_units.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_line_none_rendering.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_plot1d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_plotbar.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_colorbar_gap_scalebar.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_detail_tile.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_display_window.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_first_paint_race.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_gpu_image.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_gpu_parity_playwright.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_imshow_rgb.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_layers.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_layers_playwright.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_pcolormesh.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_plot2d_api.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_rapid_frame_update.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_tile_diagnostics.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_tiled_imshow.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_zoom_view_write.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_colors_highlight.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_depth.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_fallback.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_hidden_reveal.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_plot3d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_texture.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_voxels_planes.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plotxy/test_plotxy.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/__init__.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_base.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets1d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets2d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets3d.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_sg_html_scraper.py +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/anyplotlib.svg +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/custom.css +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/pyodide_bridge.js +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_templates/autosummary/class.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/callbacks.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/figure.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/figure_plots.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/index.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/keys.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/markers.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/widgets.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/benchmarking.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/dev/index.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/getting_started.rst +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/make.bat +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/upcoming_changes/.gitkeep +0 -0
- {anyplotlib-0.8.0 → anyplotlib-0.10.0}/upcoming_changes/README.rst +0 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- **`Figure`** (`anyplotlib/figure/_figure.py`) — the only `anywidget.AnyWidget` subclass. Owns all traitlets and is the Python↔JS bridge.
|
|
8
8
|
- **Plot objects** (`plot1d/`, `plot2d/`, `plot3d/`) — `Plot1D`, `PlotBar`, `Plot2D`, `PlotMesh`, `Plot3D` are **plain Python classes**, not widgets. They hold state in `_state` dicts and push to the Figure. Shared behaviour lives in `_base_plot.py` (`_BasePlot`, `_PanelMixin`, `_MarkerMixin`).
|
|
9
9
|
- **`Axes`** (`axes/_axes.py`) — grid-cell container; factory methods (`imshow`, `plot`, `bar`, `pcolormesh`, `plot_surface`, …) create plot objects and attach them.
|
|
10
|
-
- **`figure_esm.js`** — pure-JS canvas renderer (~
|
|
10
|
+
- **`figure_esm.js`** — pure-JS canvas renderer (~12,210 lines); all rendering logic lives here. **Read `anyplotlib/FIGURE_ESM.md` first** — it is the section map.
|
|
11
11
|
- **`markers.py`** — static visual overlays (circles, arrows, lines, etc.) with a two-level dict registry: `plot.markers[type][name]`.
|
|
12
12
|
- **`widgets/`** — interactive draggable overlays (`RectangleWidget`, `CrosshairWidget`, etc.) that receive JS position updates.
|
|
13
13
|
- **`callbacks.py`** — event system: `Event` dataclass, `CallbackRegistry` (priority ordering, wildcard, pause/hold), `_EventMixin` (`add_event_handler`).
|
|
@@ -115,7 +115,7 @@ grep -nE '^\s*(function|const|let) [A-Za-z_]' anyplotlib/figure_esm.js
|
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
and reconcile against the two numbered tables (the section map near the top and
|
|
118
|
-
the 2-D function table). Both were last verified at
|
|
118
|
+
the 2-D function table). Both were last verified at 12,407 lines.
|
|
119
119
|
|
|
120
120
|
Changelog entries: add a fragment file to `upcoming_changes/` (e.g.
|
|
121
121
|
`123.new_feature.rst`) — towncrier assembles `CHANGELOG.rst` at release time.
|
|
@@ -129,7 +129,7 @@ Use `api_change` when existing behaviour changes, even if the change is a fix.
|
|
|
129
129
|
| `anyplotlib/figure/_gridspec.py` | `GridSpec`, `SubplotSpec` |
|
|
130
130
|
| `anyplotlib/figure/_subplots.py` | `subplots()` factory |
|
|
131
131
|
| `anyplotlib/axes/_axes.py` | `Axes` — plot factory methods |
|
|
132
|
-
| `anyplotlib/figure_esm.js` | All JS canvas rendering (~
|
|
132
|
+
| `anyplotlib/figure_esm.js` | All JS canvas rendering (~12,210 lines) |
|
|
133
133
|
| `anyplotlib/FIGURE_ESM.md` | Section map for `figure_esm.js` — read this before editing the JS |
|
|
134
134
|
| `anyplotlib/markers.py` | Static marker collections; `to_wire()` translation |
|
|
135
135
|
| `anyplotlib/widgets/` | Interactive overlay widgets |
|
|
@@ -10,6 +10,139 @@ Fragment files in ``upcoming_changes/`` are assembled into this file by
|
|
|
10
10
|
|
|
11
11
|
.. towncrier release notes start
|
|
12
12
|
|
|
13
|
+
0.10.0 (2026-09-14)
|
|
14
|
+
===================
|
|
15
|
+
|
|
16
|
+
API and Behaviour Changes
|
|
17
|
+
-------------------------
|
|
18
|
+
|
|
19
|
+
- 2-D pointer events (``pointer_down``, ``double_click``, ``pointer_settled``, ``key_down``) and the hover readout now report ``img_x``/``img_y`` in the pixel-centre convention that markers, widgets and :meth:`~anyplotlib.Plot2D.display_to_data` already used — they read half a pixel right and down before — so ``round(event.img_x)`` names the clicked pixel (``int()`` no longer does), brush strokes land under the cursor, and an ``imshow`` event's ``xdata``/``ydata`` is exactly the axis value of the pixel centre it hits (``pcolormesh`` values are unchanged). (`#73 <https://github.com/CSSFrancis/anyplotlib/pull/73>`_)
|
|
20
|
+
- 2-D tick labels now sit on the pixels they name: ``imshow`` axis values are placed at pixel centres (the image extends half a pixel past the first and last value, as matplotlib's ``imshow`` extent does) through the same transform markers and pointer events use, so ticks also follow a letterboxed image instead of spanning the whole gutter, and an ``origin='lower'`` image gets y ticks at all; :meth:`~anyplotlib.Plot2D.set_view` / ``set_xlim`` / ``set_ylim`` read the axis the same way — ``set_xlim(-0.5, n - 0.5)`` is the whole image, ``set_xlim(0, n - 1)`` now crops the outer half pixels — and accept a descending ``origin='lower'`` y axis. (`#74 <https://github.com/CSSFrancis/anyplotlib/pull/74>`_)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
New Features
|
|
24
|
+
------------
|
|
25
|
+
|
|
26
|
+
- The 2-D colorbar now writes its display minimum and maximum beside the strip — both ends in one format, and the strip itself coloured through the display window (saturated beyond it, the way the image is) and spanning the image rather than the whole panel — so a labelled scale says how much and not only which way; the image gives up a value gutter budgeted for the numbers (fixed for ordinary values so a contrast drag never moves the image, wider for the rare long ones, dropped in a cell too narrow to keep 40 px of image, and mirrored in :meth:`plot_box`) so they never clip. (`#71 <https://github.com/CSSFrancis/anyplotlib/pull/71>`_)
|
|
27
|
+
- Text markers (:meth:`~anyplotlib.Plot2D.add_texts`, :meth:`~anyplotlib.Plot1D.add_texts` and ``add_text``) gained ``fontweight`` for bold labels and ``outline_color`` / ``outline_width`` for a halo stroked under the text, which keeps a label legible over both light and dark parts of an image. (`#73 <https://github.com/CSSFrancis/anyplotlib/pull/73>`_)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
0.9.0 (2026-09-11)
|
|
31
|
+
==================
|
|
32
|
+
|
|
33
|
+
New Features
|
|
34
|
+
------------
|
|
35
|
+
|
|
36
|
+
- A self-contained HTML page can now navigate its own data.
|
|
37
|
+
``anyplotlib.embed.navigated_html`` writes a figure, the dataset it navigates
|
|
38
|
+
and a list of bindings into one file: drag the navigator's crosshair and the
|
|
39
|
+
signal panel shows that position's frame, its overlays follow, and a detector
|
|
40
|
+
drawn on the signal panel re-maps the navigator. Data travels as *blocks*:
|
|
41
|
+
dense arrays, or ``Ragged`` row-pointer blocks for a variable number of rows
|
|
42
|
+
per position, packed by ``pack_blocks`` into one byte string the page decodes
|
|
43
|
+
once.
|
|
44
|
+
|
|
45
|
+
The JS mount handle gained the pieces that make that fast: ``setImage`` pushes
|
|
46
|
+
raw pixel bytes straight to the renderer's draw path (a fraction of a
|
|
47
|
+
millisecond at 2048², against 129-136 ms through the panel state),
|
|
48
|
+
``patchPanel`` merges a partial state, and ``panelIds`` lists the panels. The
|
|
49
|
+
runtime and its readers (``mountNavigated``, ``dense``, ``ragged``,
|
|
50
|
+
``maskFromWidget``, ``rasterDisks``, ``robustLevels``, ``toU8``) are exported
|
|
51
|
+
from ``figure_esm.js`` for hosts that already own their data. (`#69 <https://github.com/CSSFrancis/anyplotlib/pull/69>`_)
|
|
52
|
+
- Figures can now be **saved and copied as PNG images**. Right-click any plot for a
|
|
53
|
+
menu offering *Copy image*, *Save PNG…*, *Save full view…* and *Save at native
|
|
54
|
+
resolution…* for the panel you clicked, the same for the whole figure, and a
|
|
55
|
+
sticky **Theme** choice (*Current* / *Light* / *Dark*) so a dark-themed notebook
|
|
56
|
+
can still produce a light figure for a paper. ``Ctrl+C`` (``Cmd+C`` on macOS)
|
|
57
|
+
copies the plot under the cursor to the clipboard, with a brief
|
|
58
|
+
*"Image copied to clipboard"* confirmation; with no plot hovered it copies the
|
|
59
|
+
whole figure. Inside JupyterLab, PyCharm and VS Code the badge is the reliable
|
|
60
|
+
route: those hosts install their own ``contextmenu`` and keyboard handlers and
|
|
61
|
+
may swallow a right-click or ``Cmd+C`` before the figure ever sees it. *Save PNG…* downloads without any permission prompt; a separate *Save as…*
|
|
62
|
+
entry opens a real system file dialog where the browser supports one
|
|
63
|
+
(Chromium), at the cost of Chrome's file-editing permission prompt. Hosts that
|
|
64
|
+
block script-started downloads get an in-figure preview instead.
|
|
65
|
+
The three sources are *current view* (zoom, pan and contrast
|
|
66
|
+
exactly as displayed), *full view* (the whole data extent at the panel's
|
|
67
|
+
on-screen resolution) and *native resolution* (one output pixel per data pixel,
|
|
68
|
+
with the axes, colorbar, title, markers and widgets all redrawn at that size).
|
|
69
|
+
|
|
70
|
+
The same thing is available from Python as :meth:`~anyplotlib.Figure.savefig`::
|
|
71
|
+
|
|
72
|
+
fig.savefig("figure.png") # as displayed
|
|
73
|
+
fig.savefig("paper.png", theme="light", scale=2) # light, 2x
|
|
74
|
+
fig.savefig("data.png", source="native", panel=plot) # 1:1 with the data
|
|
75
|
+
|
|
76
|
+
``savefig`` renders through the real JavaScript renderer in a headless browser,
|
|
77
|
+
so the output is exactly what the figure looks like on screen — it needs
|
|
78
|
+
Playwright (``pip install "anyplotlib[docs]"`` then
|
|
79
|
+
``playwright install chromium``). ``source="native"`` works even for a **tiled**
|
|
80
|
+
plot, whose full-resolution array normally never leaves Python: the backend is
|
|
81
|
+
re-sampled at full resolution for the export only, leaving the live figure
|
|
82
|
+
untouched. In the browser that case is offered but disabled, with a tooltip
|
|
83
|
+
pointing at ``savefig``, because the page only ever holds a downsampled
|
|
84
|
+
overview.
|
|
85
|
+
|
|
86
|
+
Downstream applications can add their own entries to the menu through the
|
|
87
|
+
embedding handle, so a host can save formats anyplotlib knows nothing about::
|
|
88
|
+
|
|
89
|
+
handle.registerExportAction({
|
|
90
|
+
id: 'save-tiff', label: 'Save as TIFF…', scope: 'panel',
|
|
91
|
+
handler: (ctx) => host.writeTiff(ctx.panelId, ctx.exportCanvas().canvas),
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
The handler receives the clicked panel, its state, the chosen theme, and bound
|
|
95
|
+
``exportPNG`` / ``exportCanvas`` / ``downloadPNG`` / ``copyPNG`` / ``toast``
|
|
96
|
+
helpers. See :doc:`exporting` for the full reference.
|
|
97
|
+
- The 2-D hover readout now also names the **value** of the pixel under the
|
|
98
|
+
cursor — ``v:<value>`` for a colourmapped image, ``rgb:r,g,b`` for a true-colour
|
|
99
|
+
one — alongside the existing physical and pixel coordinates. It is exact:
|
|
100
|
+
integer data whose range fits the 256 transferred codes is inverted locally,
|
|
101
|
+
and for anything wider the renderer asks Python for the true value once the
|
|
102
|
+
cursor dwells on a pixel (``imshow(..., probe_exact=True)`` by default, tunable
|
|
103
|
+
via :meth:`~anyplotlib.Plot2D.set_value_probe`), falling back to the quantised
|
|
104
|
+
estimate when no kernel can answer. Zoomed into a detail tile the value comes
|
|
105
|
+
from the tile's native pixels rather than the coarser overview.
|
|
106
|
+
The **v** key toggles the on-image pill, and
|
|
107
|
+
:meth:`~anyplotlib.Plot2D.set_readout_visible` turns it off from Python while
|
|
108
|
+
keeping the readout live: embedding hosts receive every update through
|
|
109
|
+
``mount()``'s ``opts.onReadout`` callback and an ``apl:readout`` DOM event — so
|
|
110
|
+
an Electron app can render position and value in its own status bar instead,
|
|
111
|
+
where it covers no data. 2-D pointer events also carry ``img_x``/``img_y`` now,
|
|
112
|
+
the cursor's position in image pixels.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
Bug Fixes
|
|
116
|
+
---------
|
|
117
|
+
|
|
118
|
+
- Fixed a tiled :meth:`~anyplotlib.Axes.imshow` of a **signed** integer frame
|
|
119
|
+
displaying wrapped values: a ``uint32`` accumulator in the overview box-mean read
|
|
120
|
+
an ``int16`` ``-100`` as ``+1073741696``, raised
|
|
121
|
+
``_UFuncOutputCastingError`` on a non-divisible grid, and overflowed on any dtype
|
|
122
|
+
wider than 16 bits; the accumulator is now sized to the data, which also makes the
|
|
123
|
+
overview up to 4x faster on large float frames. (`#65 <https://github.com/CSSFrancis/anyplotlib/pull/65>`_)
|
|
124
|
+
- :meth:`~anyplotlib.Figure.save_html`, :func:`~anyplotlib.embed.to_html` and
|
|
125
|
+
:func:`~anyplotlib.embed.figure_state` now capture the view the reader is
|
|
126
|
+
actually looking at. Zoom, pan, orbit and the colorbar / scale-mode shortcuts
|
|
127
|
+
are applied in the browser and written back to the panel traits, but nothing on
|
|
128
|
+
the Python side read them back, so every snapshot silently reset the figure to
|
|
129
|
+
the view it was created with. Those keys are now reconciled into the plot state
|
|
130
|
+
before a snapshot is taken.
|
|
131
|
+
- Fixed PNG export producing a mostly-blank image when the figure is wider than
|
|
132
|
+
the notebook cell. In that case the renderer shrinks the figure with a CSS
|
|
133
|
+
``transform: scale()``, which makes element rectangles report *visual* pixels
|
|
134
|
+
while the export sized its canvas in *native* pixels — so the panels were
|
|
135
|
+
composited into the top-left corner and the remainder was filled with the
|
|
136
|
+
background colour. Export coordinates are now un-scaled by the live transform.
|
|
137
|
+
- Modified key presses no longer trigger a plot's single-letter shortcuts. The
|
|
138
|
+
panel key handlers matched on the bare letter without checking modifiers, so
|
|
139
|
+
``Ctrl+C`` toggled the colorbar instead of copying, and ``Cmd+S`` — JupyterLab's
|
|
140
|
+
*save notebook* — silently flipped a 2-D plot's colour scale to symlog. Keys
|
|
141
|
+
pressed with ``Ctrl``, ``Cmd`` or ``Alt`` are now left to the host. They are
|
|
142
|
+
still reported to Python ``key_down`` callbacks exactly as before, so nothing
|
|
143
|
+
that observes the full keystroke changes.
|
|
144
|
+
|
|
145
|
+
|
|
13
146
|
0.8.0 (2026-08-25)
|
|
14
147
|
==================
|
|
15
148
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Aspect Ratio Control
|
|
3
|
+
====================
|
|
4
|
+
|
|
5
|
+
:meth:`~anyplotlib.Plot2D.set_aspect` constrains the displayed image canvas so
|
|
6
|
+
that one unit on the x-axis occupies the same number of pixels as one unit on
|
|
7
|
+
the y-axis.
|
|
8
|
+
|
|
9
|
+
Three modes are shown:
|
|
10
|
+
|
|
11
|
+
1. **Default** — the image fills the panel exactly (no constraint).
|
|
12
|
+
2. ``set_aspect("equal")`` — forces a 1 : 1 pixel-per-unit ratio. A square
|
|
13
|
+
array is displayed as a square image regardless of panel dimensions.
|
|
14
|
+
3. ``set_aspect(2.0)`` — makes the canvas twice as wide as it is tall.
|
|
15
|
+
|
|
16
|
+
The scale bar, axis ticks, and colorbar all update automatically when the
|
|
17
|
+
canvas is resized by ``set_aspect``.
|
|
18
|
+
"""
|
|
19
|
+
import numpy as np
|
|
20
|
+
import anyplotlib as apl
|
|
21
|
+
|
|
22
|
+
rng = np.random.default_rng(0)
|
|
23
|
+
|
|
24
|
+
# ── Synthetic calibrated image ────────────────────────────────────────────────
|
|
25
|
+
N = 64
|
|
26
|
+
x = np.linspace(0, 10, N) # nm
|
|
27
|
+
y = np.linspace(0, 10, N)
|
|
28
|
+
XX, YY = np.meshgrid(x, y)
|
|
29
|
+
data = (np.sin(XX) * np.cos(YY) + 0.2 * rng.standard_normal((N, N))).astype(np.float32)
|
|
30
|
+
|
|
31
|
+
# ── 1. Default (no aspect constraint) ────────────────────────────────────────
|
|
32
|
+
# %%
|
|
33
|
+
# Default — no aspect constraint
|
|
34
|
+
# --------------------------------
|
|
35
|
+
# The image stretches to fill the full panel area.
|
|
36
|
+
|
|
37
|
+
fig1, ax1 = apl.subplots(1, 1, figsize=(420, 340))
|
|
38
|
+
plot1 = ax1.imshow(data, axes=[x, y], units="nm", cmap="viridis")
|
|
39
|
+
plot1.set_title("Default (no constraint)")
|
|
40
|
+
plot1.set_xlabel("x (nm)")
|
|
41
|
+
plot1.set_ylabel("y (nm)")
|
|
42
|
+
|
|
43
|
+
fig1 # Interactive
|
|
44
|
+
|
|
45
|
+
# ── 2. Equal aspect ratio ─────────────────────────────────────────────────────
|
|
46
|
+
# %%
|
|
47
|
+
# Equal aspect ratio
|
|
48
|
+
# ------------------
|
|
49
|
+
# ``set_aspect("equal")`` (or equivalently ``set_aspect(1.0)``) ensures that
|
|
50
|
+
# one nm on the x-axis occupies the same number of canvas pixels as one nm on
|
|
51
|
+
# the y-axis. The canvas height adjusts to be equal to the canvas width.
|
|
52
|
+
|
|
53
|
+
fig2, ax2 = apl.subplots(1, 1, figsize=(420, 340))
|
|
54
|
+
plot2 = ax2.imshow(data, axes=[x, y], units="nm", cmap="viridis")
|
|
55
|
+
plot2.set_aspect("equal")
|
|
56
|
+
plot2.set_title("set_aspect('equal')")
|
|
57
|
+
plot2.set_xlabel("x (nm)")
|
|
58
|
+
plot2.set_ylabel("y (nm)")
|
|
59
|
+
|
|
60
|
+
fig2 # Interactive
|
|
61
|
+
|
|
62
|
+
# ── 3. Explicit ratio ─────────────────────────────────────────────────────────
|
|
63
|
+
# %%
|
|
64
|
+
# Explicit ratio (2 : 1)
|
|
65
|
+
# -----------------------
|
|
66
|
+
# ``set_aspect(2.0)`` makes the canvas twice as wide as it is tall. Useful
|
|
67
|
+
# when the physical x and y scales differ (e.g. a time-series scan where one
|
|
68
|
+
# axis is faster than the other).
|
|
69
|
+
|
|
70
|
+
fig3, ax3 = apl.subplots(1, 1, figsize=(420, 340))
|
|
71
|
+
plot3 = ax3.imshow(data, axes=[x, y], units="nm", cmap="inferno")
|
|
72
|
+
plot3.set_aspect(2.0)
|
|
73
|
+
plot3.set_title("set_aspect(2.0)")
|
|
74
|
+
plot3.set_xlabel("x (nm)")
|
|
75
|
+
plot3.set_ylabel("y (nm)")
|
|
76
|
+
|
|
77
|
+
fig3 # Interactive
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Subplot Spacing with subplots_adjust
|
|
3
|
+
=====================================
|
|
4
|
+
|
|
5
|
+
:meth:`~anyplotlib.Figure.subplots_adjust` controls the gap between panels in
|
|
6
|
+
a multi-panel figure.
|
|
7
|
+
|
|
8
|
+
* **hspace** — vertical gap as a fraction of the mean row height.
|
|
9
|
+
``hspace=0.15`` adds 15 % of the average row height as space between rows.
|
|
10
|
+
* **wspace** — horizontal gap as a fraction of the mean column width.
|
|
11
|
+
``wspace=0.10`` adds 10 % of the average column width as space between
|
|
12
|
+
columns.
|
|
13
|
+
|
|
14
|
+
Both values default to ``0.0`` (panels are flush with no gap).
|
|
15
|
+
|
|
16
|
+
The examples below compare default flush spacing against adjusted spacing on
|
|
17
|
+
the same 2 × 2 grid.
|
|
18
|
+
"""
|
|
19
|
+
import numpy as np
|
|
20
|
+
import anyplotlib as apl
|
|
21
|
+
|
|
22
|
+
rng = np.random.default_rng(42)
|
|
23
|
+
t = np.linspace(0, 2 * np.pi, 512)
|
|
24
|
+
|
|
25
|
+
COLORS = ["#4fc3f7", "#ff7043", "#aed581", "#ffd54f"]
|
|
26
|
+
LABELS = ["α", "β", "γ", "δ"]
|
|
27
|
+
SIGNALS = [
|
|
28
|
+
np.sin(t * (i + 1)) + rng.normal(scale=0.08, size=len(t))
|
|
29
|
+
for i in range(4)
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _fill_grid(fig):
|
|
34
|
+
"""Add four 1-D spectra to a 2×2 Figure."""
|
|
35
|
+
import anyplotlib as _apl
|
|
36
|
+
gs = _apl.GridSpec(2, 2)
|
|
37
|
+
positions = [(0, 0), (0, 1), (1, 0), (1, 1)]
|
|
38
|
+
for idx, (r, c) in enumerate(positions):
|
|
39
|
+
ax = fig.add_subplot(gs[r, c])
|
|
40
|
+
ax.plot(SIGNALS[idx], color=COLORS[idx], label=LABELS[idx])
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ── 1. Default spacing (flush) ────────────────────────────────────────────────
|
|
44
|
+
# %%
|
|
45
|
+
# Default spacing — panels flush
|
|
46
|
+
# --------------------------------
|
|
47
|
+
# Without calling ``subplots_adjust`` the panels abut each other with no gap.
|
|
48
|
+
|
|
49
|
+
fig1 = apl.Figure(2, 2, figsize=(680, 480))
|
|
50
|
+
_fill_grid(fig1)
|
|
51
|
+
|
|
52
|
+
fig1 # Interactive
|
|
53
|
+
|
|
54
|
+
# ── 2. Vertical gap only (hspace) ────────────────────────────────────────────
|
|
55
|
+
# %%
|
|
56
|
+
# Vertical gap only — hspace=0.15
|
|
57
|
+
# ---------------------------------
|
|
58
|
+
# ``subplots_adjust(hspace=0.15)`` inserts a vertical gap equal to 15 % of
|
|
59
|
+
# the mean row height between the two rows.
|
|
60
|
+
|
|
61
|
+
fig2 = apl.Figure(2, 2, figsize=(680, 480))
|
|
62
|
+
_fill_grid(fig2)
|
|
63
|
+
fig2.subplots_adjust(hspace=0.15)
|
|
64
|
+
|
|
65
|
+
fig2 # Interactive
|
|
66
|
+
|
|
67
|
+
# ── 3. Horizontal gap only (wspace) ──────────────────────────────────────────
|
|
68
|
+
# %%
|
|
69
|
+
# Horizontal gap only — wspace=0.10
|
|
70
|
+
# -----------------------------------
|
|
71
|
+
# ``subplots_adjust(wspace=0.10)`` inserts a horizontal gap equal to 10 % of
|
|
72
|
+
# the mean column width between the two columns.
|
|
73
|
+
|
|
74
|
+
fig3 = apl.Figure(2, 2, figsize=(680, 480))
|
|
75
|
+
_fill_grid(fig3)
|
|
76
|
+
fig3.subplots_adjust(wspace=0.10)
|
|
77
|
+
|
|
78
|
+
fig3 # Interactive
|
|
79
|
+
|
|
80
|
+
# ── 4. Both gaps ─────────────────────────────────────────────────────────────
|
|
81
|
+
# %%
|
|
82
|
+
# Both hspace and wspace
|
|
83
|
+
# -----------------------
|
|
84
|
+
# Combine both arguments to add space in both directions.
|
|
85
|
+
|
|
86
|
+
fig4 = apl.Figure(2, 2, figsize=(680, 480))
|
|
87
|
+
_fill_grid(fig4)
|
|
88
|
+
fig4.subplots_adjust(hspace=0.15, wspace=0.10)
|
|
89
|
+
|
|
90
|
+
fig4 # Interactive
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: anyplotlib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
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
|