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.
Files changed (303) hide show
  1. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/AGENTS.md +3 -3
  2. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/CHANGELOG.rst +133 -0
  3. anyplotlib-0.10.0/Examples/PlotTypes/plot_aspect_ratio.py +77 -0
  4. anyplotlib-0.10.0/Examples/PlotTypes/plot_subplots_adjust.py +90 -0
  5. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/PKG-INFO +1 -1
  6. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/FIGURE_ESM.md +459 -99
  7. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_base_plot.py +99 -4
  8. anyplotlib-0.10.0/anyplotlib/_export.py +262 -0
  9. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_repr_utils.py +70 -33
  10. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_utils.py +14 -0
  11. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/_axes.py +8 -2
  12. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/callbacks.py +4 -0
  13. anyplotlib-0.10.0/anyplotlib/embed.py +457 -0
  14. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_figure.py +109 -0
  15. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure_esm.js +2454 -166
  16. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/markers.py +34 -0
  17. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/_plot1d.py +16 -1
  18. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_plot2d.py +240 -15
  19. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_plotmesh.py +11 -1
  20. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_tile_backend.py +45 -16
  21. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_scraper.py +13 -52
  22. anyplotlib-0.10.0/anyplotlib/tests/baselines/imshow_labels.png +0 -0
  23. anyplotlib-0.10.0/anyplotlib/tests/test_embed/_export_utils.py +71 -0
  24. anyplotlib-0.10.0/anyplotlib/tests/test_embed/conftest.py +80 -0
  25. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_3d.py +328 -0
  26. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_api.py +269 -0
  27. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_escaping.py +139 -0
  28. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_navigated.py +906 -0
  29. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_embed_set_image.py +306 -0
  30. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_export_menu.py +523 -0
  31. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_png.py +14 -80
  32. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_export_sources.py +386 -0
  33. anyplotlib-0.10.0/anyplotlib/tests/test_embed/test_savefig.py +290 -0
  34. anyplotlib-0.10.0/anyplotlib/tests/test_markers/test_text_style.py +146 -0
  35. anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_axis_ticks.py +205 -0
  36. anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_colorbar_values.py +298 -0
  37. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_imshow.py +13 -10
  38. anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_pointer_pixel_centre.py +168 -0
  39. anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_status_pixel_value.py +730 -0
  40. anyplotlib-0.10.0/anyplotlib/tests/test_plot2d/test_tile_backend.py +199 -0
  41. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_root/index.html +3 -3
  42. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_root/switcher.json +10 -0
  43. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/conf.py +1 -1
  44. anyplotlib-0.10.0/docs/embedding.rst +445 -0
  45. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/events.rst +92 -0
  46. anyplotlib-0.10.0/docs/exporting.rst +218 -0
  47. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/index.rst +12 -0
  48. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/pyproject.toml +1 -1
  49. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/uv.lock +1 -1
  50. anyplotlib-0.8.0/anyplotlib/embed.py +0 -194
  51. anyplotlib-0.8.0/anyplotlib/tests/baselines/imshow_labels.png +0 -0
  52. anyplotlib-0.8.0/anyplotlib/tests/test_embed/test_embed_api.py +0 -133
  53. anyplotlib-0.8.0/anyplotlib/tests/test_plot2d/test_tile_backend.py +0 -99
  54. anyplotlib-0.8.0/docs/embedding.rst +0 -181
  55. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/ci.yml +0 -0
  56. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/docs.yml +0 -0
  57. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/prepare_release.yml +0 -0
  58. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/release.yml +0 -0
  59. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.github/workflows/tests.yml +0 -0
  60. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/.gitignore +0 -0
  61. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Benchmarks/README.rst +0 -0
  62. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Benchmarks/plot_benchmark_comparison.py +0 -0
  63. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/README.rst +0 -0
  64. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_3d_spectral_viewer.py +0 -0
  65. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_eels_explorer.py +0 -0
  66. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_figure_annotations.py +0 -0
  67. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_interactive_fft.py +0 -0
  68. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_interactive_fitting.py +0 -0
  69. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_ipf_density_map.py +0 -0
  70. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_ipf_explorer.py +0 -0
  71. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_key_bindings.py +0 -0
  72. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_particle_picker.py +0 -0
  73. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_point_widget.py +0 -0
  74. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_segment_by_contrast.py +0 -0
  75. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_segment_by_contrast_advanced.py +0 -0
  76. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_spectra_roi_inspector.py +0 -0
  77. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_star_globe_explorer.py +0 -0
  78. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_threshold_explorer.py +0 -0
  79. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Interactive/plot_voxel_grain_explorer.py +0 -0
  80. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/README.rst +0 -0
  81. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_arrows.py +0 -0
  82. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_circles.py +0 -0
  83. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_ellipses.py +0 -0
  84. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_horizontal_lines.py +0 -0
  85. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_line_segments.py +0 -0
  86. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_points.py +0 -0
  87. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_polygons.py +0 -0
  88. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_rectangles.py +0 -0
  89. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_squares.py +0 -0
  90. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_texts.py +0 -0
  91. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_transform_markers.py +0 -0
  92. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Markers/plot_vertical_lines.py +0 -0
  93. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/README.rst +0 -0
  94. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_3d.py +0 -0
  95. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_3d_texture.py +0 -0
  96. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_bar.py +0 -0
  97. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_gpu_voxels.py +0 -0
  98. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_gridspec_custom.py +0 -0
  99. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_image2d.py +0 -0
  100. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_inset.py +0 -0
  101. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_key_overlays.py +0 -0
  102. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_label_formatting.py +0 -0
  103. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_line_styles.py +0 -0
  104. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_pcolormesh.py +0 -0
  105. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_spectra1d.py +0 -0
  106. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_step_and_log.py +0 -0
  107. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_tile_backend.py +0 -0
  108. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/PlotTypes/plot_twinx.py +0 -0
  109. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/README.rst +0 -0
  110. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/README.rst +0 -0
  111. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_hline.py +0 -0
  112. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_point.py +0 -0
  113. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_range.py +0 -0
  114. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget1d_vline.py +0 -0
  115. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_annular.py +0 -0
  116. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_arrow.py +0 -0
  117. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_circle.py +0 -0
  118. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_crosshair.py +0 -0
  119. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_label.py +0 -0
  120. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_polygon.py +0 -0
  121. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget2d_rectangle.py +0 -0
  122. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Examples/Widgets/plot_widget3d_plane.py +0 -0
  123. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/LICENSE +0 -0
  124. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/Makefile +0 -0
  125. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/README.md +0 -0
  126. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/__init__.py +0 -0
  127. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_binary_frame.py +0 -0
  128. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/_electron.py +0 -0
  129. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/__init__.py +0 -0
  130. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/axes/_inset_axes.py +0 -0
  131. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/conftest.py +0 -0
  132. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/__init__.py +0 -0
  133. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_gridspec.py +0 -0
  134. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/figure/_subplots.py +0 -0
  135. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/keys.py +0 -0
  136. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/__init__.py +0 -0
  137. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot1d/_plotbar.py +0 -0
  138. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/__init__.py +0 -0
  139. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot2d/_layer.py +0 -0
  140. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot3d/__init__.py +0 -0
  141. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plot3d/_plot3d.py +0 -0
  142. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plotxy/__init__.py +0 -0
  143. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/plotxy/_plotxy.py +0 -0
  144. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/__init__.py +0 -0
  145. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_directive.py +0 -0
  146. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_repr_utils.py +0 -0
  147. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/_wheel_builder.py +0 -0
  148. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/static/anywidget_bridge.js +0 -0
  149. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/static/anywidget_overlay.css +0 -0
  150. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/__init__.py +0 -0
  151. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/conftest.py +0 -0
  152. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_directive.py +0 -0
  153. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_init.py +0 -0
  154. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_repr_utils.py +0 -0
  155. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_scraper.py +0 -0
  156. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/sphinx_anywidget/tests/test_wheel_builder.py +0 -0
  157. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/__init__.py +0 -0
  158. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/_gpu_clim_check.cjs +0 -0
  159. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/_png_utils.py +0 -0
  160. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/bar_basic.png +0 -0
  161. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_3col_equal_spectra.png +0 -0
  162. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_asymmetric_width_ratios.png +0 -0
  163. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_height_ratio_image_histogram.png +0 -0
  164. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_image_two_spectra.png +0 -0
  165. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_side_by_side_1d.png +0 -0
  166. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/gridspec_spanning_top_two_bottom.png +0 -0
  167. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_axis_off.png +0 -0
  168. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_checkerboard.png +0 -0
  169. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_gradient.png +0 -0
  170. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/imshow_viridis.png +0 -0
  171. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_1d.png +0 -0
  172. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_maximized.png +0 -0
  173. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_minimized.png +0 -0
  174. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_normal_2d.png +0 -0
  175. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_stacked.png +0 -0
  176. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/inset_stacked_one_minimized.png +0 -0
  177. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/pcolormesh_uniform.png +0 -0
  178. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_all_linestyles.png +0 -0
  179. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_alpha.png +0 -0
  180. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_axis_off.png +0 -0
  181. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_dashed.png +0 -0
  182. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_marker_symbols.png +0 -0
  183. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_markers.png +0 -0
  184. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_multi.png +0 -0
  185. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_sine.png +0 -0
  186. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_title.png +0 -0
  187. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot1d_twinx.png +0 -0
  188. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/plot3d_surface.png +0 -0
  189. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/baselines/subplots_2x1.png +0 -0
  190. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/conftest.py +0 -0
  191. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/__init__.py +0 -0
  192. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/baselines.json +0 -0
  193. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/benchmarks/baselines.json +0 -0
  194. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/test_benchmarks.py +0 -0
  195. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_benchmarks/test_benchmarks_py.py +0 -0
  196. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/__init__.py +0 -0
  197. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_bridge.py +0 -0
  198. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_push_hook.py +0 -0
  199. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_documentation/test_scraper.py +0 -0
  200. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_electron/__init__.py +0 -0
  201. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_electron/test_binary_frame.py +0 -0
  202. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/__init__.py +0 -0
  203. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_embed_mount.py +0 -0
  204. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_pixel_tokens.py +0 -0
  205. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_embed/test_export_widget_sync.py +0 -0
  206. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_examples/__init__.py +0 -0
  207. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_examples/test_interactive_examples.py +0 -0
  208. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/__init__.py +0 -0
  209. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/_event_test_utils.py +0 -0
  210. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_blit_audit.py +0 -0
  211. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_callbacks_playwright.py +0 -0
  212. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_callbacks_unit.py +0 -0
  213. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_circle_lock_center.py +0 -0
  214. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_edit_chrome.py +0 -0
  215. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_edit_chrome_playwright.py +0 -0
  216. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_pause_hold.py +0 -0
  217. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_plots.py +0 -0
  218. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_event_settled.py +0 -0
  219. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_events_regression.py +0 -0
  220. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_orbit_direction.py +0 -0
  221. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_pointer_down_1d.py +0 -0
  222. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_range_orientation_snap.py +0 -0
  223. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_star_globe_linking.py +0 -0
  224. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_tile_parity_playwright.py +0 -0
  225. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_title.py +0 -0
  226. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_touch.py +0 -0
  227. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_brush.py +0 -0
  228. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_max_extent.py +0 -0
  229. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widget_set_notify.py +0 -0
  230. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widgets.py +0 -0
  231. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_interactive/test_widgets_line_2d.py +0 -0
  232. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_keys/test_keys.py +0 -0
  233. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/__init__.py +0 -0
  234. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_label_api.py +0 -0
  235. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_label_rendering.py +0 -0
  236. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_no_clipping.py +0 -0
  237. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_labels/test_ylabel_clearance.py +0 -0
  238. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/__init__.py +0 -0
  239. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_batch.py +0 -0
  240. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_coord_conversion.py +0 -0
  241. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_geom_channel.py +0 -0
  242. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_gridspec.py +0 -0
  243. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_inset.py +0 -0
  244. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_inset_callout.py +0 -0
  245. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_interaction.py +0 -0
  246. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_layouts/test_visual.py +0 -0
  247. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/__init__.py +0 -0
  248. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_marker_transforms.py +0 -0
  249. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_markers.py +0 -0
  250. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_per_marker_colors.py +0 -0
  251. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_markers/test_size_units.py +0 -0
  252. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/__init__.py +0 -0
  253. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_line_none_rendering.py +0 -0
  254. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_plot1d.py +0 -0
  255. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot1d/test_plotbar.py +0 -0
  256. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/__init__.py +0 -0
  257. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_colorbar_gap_scalebar.py +0 -0
  258. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_detail_tile.py +0 -0
  259. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_display_window.py +0 -0
  260. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_first_paint_race.py +0 -0
  261. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_gpu_image.py +0 -0
  262. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_gpu_parity_playwright.py +0 -0
  263. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_imshow_rgb.py +0 -0
  264. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_layers.py +0 -0
  265. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_layers_playwright.py +0 -0
  266. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_pcolormesh.py +0 -0
  267. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_plot2d_api.py +0 -0
  268. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_rapid_frame_update.py +0 -0
  269. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_tile_diagnostics.py +0 -0
  270. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_tiled_imshow.py +0 -0
  271. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot2d/test_zoom_view_write.py +0 -0
  272. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/__init__.py +0 -0
  273. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_colors_highlight.py +0 -0
  274. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_depth.py +0 -0
  275. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_fallback.py +0 -0
  276. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_gpu_hidden_reveal.py +0 -0
  277. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_plot3d.py +0 -0
  278. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_texture.py +0 -0
  279. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plot3d/test_voxels_planes.py +0 -0
  280. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/tests/test_plotxy/test_plotxy.py +0 -0
  281. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/__init__.py +0 -0
  282. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_base.py +0 -0
  283. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets1d.py +0 -0
  284. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets2d.py +0 -0
  285. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/anyplotlib/widgets/_widgets3d.py +0 -0
  286. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_sg_html_scraper.py +0 -0
  287. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/anyplotlib.svg +0 -0
  288. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/custom.css +0 -0
  289. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_static/pyodide_bridge.js +0 -0
  290. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/_templates/autosummary/class.rst +0 -0
  291. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/callbacks.rst +0 -0
  292. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/figure.rst +0 -0
  293. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/figure_plots.rst +0 -0
  294. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/index.rst +0 -0
  295. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/keys.rst +0 -0
  296. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/markers.rst +0 -0
  297. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/api/widgets.rst +0 -0
  298. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/benchmarking.rst +0 -0
  299. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/dev/index.rst +0 -0
  300. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/docs/getting_started.rst +0 -0
  301. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/make.bat +0 -0
  302. {anyplotlib-0.8.0 → anyplotlib-0.10.0}/upcoming_changes/.gitkeep +0 -0
  303. {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 (~9,300 lines); all rendering logic lives here. **Read `anyplotlib/FIGURE_ESM.md` first** — it is the section map.
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 10,119 lines.
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 (~9,300 lines) |
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.8.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