figrecipe 0.9.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.
Potentially problematic release.
This version of figrecipe might be problematic. Click here for more details.
- figrecipe-0.9.0/.github/ISSUE_TEMPLATE/bug_report.md +52 -0
- figrecipe-0.9.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- figrecipe-0.9.0/.github/ISSUE_TEMPLATE/feature_request.md +33 -0
- figrecipe-0.9.0/.github/PULL_REQUEST_TEMPLATE.md +34 -0
- figrecipe-0.9.0/.github/workflows/test.yml +60 -0
- figrecipe-0.9.0/.gitignore +121 -0
- figrecipe-0.9.0/.old/README_v02.md +288 -0
- figrecipe-0.9.0/.pre-commit-config.yaml +25 -0
- figrecipe-0.9.0/CHANGELOG.md +294 -0
- figrecipe-0.9.0/CONTRIBUTING.md +190 -0
- figrecipe-0.9.0/KNOWN_ISSUES.md +15 -0
- figrecipe-0.9.0/LICENSE +661 -0
- figrecipe-0.9.0/Makefile +86 -0
- figrecipe-0.9.0/PKG-INFO +427 -0
- figrecipe-0.9.0/README.md +364 -0
- figrecipe-0.9.0/docs/bgm/README.md +13 -0
- figrecipe-0.9.0/docs/bgm/smile.mp3 +0 -0
- figrecipe-0.9.0/docs/figrecipe_logo.png +0 -0
- figrecipe-0.9.0/docs/images/editor_axis_panel.png +0 -0
- figrecipe-0.9.0/docs/images/editor_dark_mode.png +0 -0
- figrecipe-0.9.0/docs/images/editor_demo.png +0 -0
- figrecipe-0.9.0/docs/images/editor_download_options.png +0 -0
- figrecipe-0.9.0/docs/images/editor_overview.png +0 -0
- figrecipe-0.9.0/docs/images/gui_editor_demo.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/all_plot_types.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_2d_image_matrix.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_bar_categorical.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_contour_surface.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_distribution.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_line_curve.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_scatter_points.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_special.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_spectral_signal.png +0 -0
- figrecipe-0.9.0/docs/images/plot_types/category_vector_flow.png +0 -0
- figrecipe-0.9.0/docs/layout_and_cropping.md +277 -0
- figrecipe-0.9.0/docs/to_claude/examples/pip-project-template/.pre-commit-config.yaml +65 -0
- figrecipe-0.9.0/docs/to_claude/examples/pip-project-template/pyproject.toml +160 -0
- figrecipe-0.9.0/examples/demo_editor.py +142 -0
- figrecipe-0.9.0/examples/demo_editor_brackets.py +119 -0
- figrecipe-0.9.0/examples/demo_editor_full.py +89 -0
- figrecipe-0.9.0/examples/demo_editor_smart_alignment.py +113 -0
- figrecipe-0.9.0/examples/demo_get_signature.py +99 -0
- figrecipe-0.9.0/examples/demo_movie/01_enable_dark_mode.py +84 -0
- figrecipe-0.9.0/examples/demo_movie/02_change_color.py +119 -0
- figrecipe-0.9.0/examples/demo_movie/03_datatable_import.py +83 -0
- figrecipe-0.9.0/examples/demo_movie/04_image_drop.py +68 -0
- figrecipe-0.9.0/examples/demo_movie/05_panel_drag.py +96 -0
- figrecipe-0.9.0/examples/demo_movie/06_file_browser.py +68 -0
- figrecipe-0.9.0/examples/demo_movie/__init__.py +9 -0
- figrecipe-0.9.0/examples/demo_movie/add_narration.py +119 -0
- figrecipe-0.9.0/examples/demo_movie/process_all_demos.py +270 -0
- figrecipe-0.9.0/examples/demo_movie/run_all.py +194 -0
- figrecipe-0.9.0/examples/demo_plot_all.py +146 -0
- figrecipe-0.9.0/examples/figrecipe_demo.ipynb +849 -0
- figrecipe-0.9.0/examples/figrecipe_demo.pdf +0 -0
- figrecipe-0.9.0/outputs/notebook/before_crop.jpg +0 -0
- figrecipe-0.9.0/outputs/notebook/before_crop.yaml +51 -0
- figrecipe-0.9.0/outputs/notebook/before_crop_cropped.jpg +0 -0
- figrecipe-0.9.0/outputs/notebook/dark.png +0 -0
- figrecipe-0.9.0/outputs/notebook/dark.yaml +537 -0
- figrecipe-0.9.0/outputs/notebook/mm_layout.png +0 -0
- figrecipe-0.9.0/outputs/notebook/mm_layout.yaml +489 -0
- figrecipe-0.9.0/outputs/notebook/multi_panel.png +0 -0
- figrecipe-0.9.0/outputs/notebook/multi_panel.yaml +479 -0
- figrecipe-0.9.0/outputs/notebook/multi_plot.png +0 -0
- figrecipe-0.9.0/outputs/notebook/multi_plot.yaml +786 -0
- figrecipe-0.9.0/outputs/notebook/seaborn.png +0 -0
- figrecipe-0.9.0/outputs/notebook/seaborn.yaml +425 -0
- figrecipe-0.9.0/outputs/notebook/styled.png +0 -0
- figrecipe-0.9.0/outputs/notebook/styled.yaml +1185 -0
- figrecipe-0.9.0/pyproject.toml +111 -0
- figrecipe-0.9.0/scripts/gui_periodic.sh +42 -0
- figrecipe-0.9.0/scripts/restart_gui.sh +13 -0
- figrecipe-0.9.0/src/figrecipe/__init__.py +489 -0
- figrecipe-0.9.0/src/figrecipe/__main__.py +12 -0
- figrecipe-0.9.0/src/figrecipe/_api/__init__.py +48 -0
- figrecipe-0.9.0/src/figrecipe/_api/_extract.py +108 -0
- figrecipe-0.9.0/src/figrecipe/_api/_notebook.py +61 -0
- figrecipe-0.9.0/src/figrecipe/_api/_panel.py +113 -0
- figrecipe-0.9.0/src/figrecipe/_api/_save.py +287 -0
- figrecipe-0.9.0/src/figrecipe/_api/_seaborn_proxy.py +34 -0
- figrecipe-0.9.0/src/figrecipe/_api/_style_manager.py +153 -0
- figrecipe-0.9.0/src/figrecipe/_api/_subplots.py +333 -0
- figrecipe-0.9.0/src/figrecipe/_api/_validate.py +82 -0
- figrecipe-0.9.0/src/figrecipe/_cli/__init__.py +7 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_compose.py +87 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_convert.py +117 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_crop.py +82 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_edit.py +70 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_extract.py +128 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_fonts.py +47 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_info.py +67 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_main.py +58 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_reproduce.py +79 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_style.py +77 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_validate.py +66 -0
- figrecipe-0.9.0/src/figrecipe/_cli/_version.py +50 -0
- figrecipe-0.9.0/src/figrecipe/_composition/__init__.py +32 -0
- figrecipe-0.9.0/src/figrecipe/_composition/_alignment.py +452 -0
- figrecipe-0.9.0/src/figrecipe/_composition/_compose.py +179 -0
- figrecipe-0.9.0/src/figrecipe/_composition/_import_axes.py +127 -0
- figrecipe-0.9.0/src/figrecipe/_composition/_visibility.py +125 -0
- figrecipe-0.9.0/src/figrecipe/_dev/__init__.py +31 -0
- figrecipe-0.9.0/src/figrecipe/_dev/_plotters.py +76 -0
- figrecipe-0.9.0/src/figrecipe/_dev/_run_demos.py +56 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/__init__.py +69 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_audio.py +240 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_caption.py +356 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_click_effect.py +146 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_cursor.py +196 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_highlight.py +105 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_narration.py +237 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_recorder.py +446 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_utils.py +178 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_video_trim/__init__.py +152 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_video_trim/_detection.py +223 -0
- figrecipe-0.9.0/src/figrecipe/_dev/browser/_video_trim/_markers.py +140 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/__init__.py +64 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/_categories.py +81 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/_figure_creators.py +119 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/_helpers.py +31 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/_registry.py +50 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/bar_categorical/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/bar_categorical/plot_bar.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/bar_categorical/plot_barh.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_contour.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_contourf.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_tricontour.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_tricontourf.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_tripcolor.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/contour_surface/plot_triplot.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/plot_boxplot.py +24 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/plot_ecdf.py +24 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/plot_hist.py +24 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/plot_hist2d.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/distribution/plot_violinplot.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_hexbin.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_imshow.py +23 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_matshow.py +23 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_pcolor.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_pcolormesh.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/image_matrix/plot_spy.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_errorbar.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_fill.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_fill_between.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_fill_betweenx.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_plot.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_stackplot.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_stairs.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/line_curve/plot_step.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/scatter_points/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/scatter_points/plot_scatter.py +24 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_eventplot.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_loglog.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_pie.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_semilogx.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_semilogy.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/special/plot_stem.py +27 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_acorr.py +24 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_angle_spectrum.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_cohere.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_csd.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_magnitude_spectrum.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_phase_spectrum.py +28 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_psd.py +29 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_specgram.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/spectral_signal/plot_xcorr.py +25 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/vector_flow/__init__.py +4 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/vector_flow/plot_barbs.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/vector_flow/plot_quiver.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_dev/demo_plotters/vector_flow/plot_streamplot.py +30 -0
- figrecipe-0.9.0/src/figrecipe/_editor/__init__.py +278 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/__init__.py +43 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_collections.py +177 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_elements.py +159 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_extract.py +402 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_extract_axes.py +370 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_extract_text.py +466 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_lines.py +173 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_bbox/_transforms.py +146 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_call_overrides.py +183 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_datatable_plot_handlers.py +249 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_figure_layout.py +211 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_flask_app.py +399 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_helpers.py +251 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/__init__.py +76 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/__init__.py +21 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/_collections.py +345 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/_images.py +68 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/_lines.py +107 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/_patches.py +163 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_artists/_text.py +190 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_colors.py +181 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_detect.py +194 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap/_restore.py +154 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_hitmap_main.py +182 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_overrides.py +321 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_plot_types_registry.py +190 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_preferences.py +135 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_render_overrides.py +507 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_renderer.py +244 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_annotation.py +114 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_axis.py +482 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_captions.py +130 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_composition.py +270 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_core.py +126 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_datatable.py +364 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_element.py +335 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_files.py +443 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_image.py +200 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_snapshot.py +94 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_routes_style.py +243 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/__init__.py +190 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_html.py +496 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_html_components/__init__.py +13 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_html_components/_composition_toolbar.py +79 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_html_components/_file_browser.py +41 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_html_datatable.py +92 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/__init__.py +178 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_accordion.py +328 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_annotation_drag.py +504 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_api.py +228 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_canvas_context_menu.py +182 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_captions.py +231 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_colors.py +485 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_composition.py +283 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_core.py +493 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/__init__.py +59 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_cell_edit.py +97 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_clipboard.py +164 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_context_menu.py +221 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_core.py +150 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_editable.py +511 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_import.py +161 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_plot.py +261 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_selection.py +438 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_table.py +256 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_datatable/_tabs.py +354 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_debug_snapshot.py +186 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_element_editor.py +325 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_files.py +429 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_files_context_menu.py +240 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_hitmap.py +512 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_image_drop.py +428 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_inspector.py +315 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_labels.py +464 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_legend_drag.py +270 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_modals.py +226 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_multi_select.py +198 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_overlays.py +292 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_panel_drag.py +505 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_panel_drag_snapshot.py +33 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_panel_position.py +463 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_panel_resize.py +230 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_panel_snap.py +307 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_region_select.py +255 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_selection.py +244 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_sync.py +242 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_tabs.py +89 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_undo_redo.py +348 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_view_mode.py +107 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_scripts/_zoom.py +212 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/__init__.py +78 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_base.py +111 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_buttons.py +327 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_color_input.py +123 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_composition.py +87 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_controls.py +430 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/__init__.py +40 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/_editable.py +203 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/_panel.py +268 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/_table.py +479 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/_toolbar.py +384 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_datatable/_vars.py +123 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_dynamic_props.py +144 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_file_browser.py +466 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_forms.py +224 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_hitmap.py +191 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_inspector.py +90 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_labels.py +118 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_modals.py +127 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_overlays.py +130 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_preview.py +430 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_selection.py +73 -0
- figrecipe-0.9.0/src/figrecipe/_editor/_templates/_styles/_spinner.py +117 -0
- figrecipe-0.9.0/src/figrecipe/_editor/static/audio/click.mp3 +0 -0
- figrecipe-0.9.0/src/figrecipe/_editor/static/click.mp3 +0 -0
- figrecipe-0.9.0/src/figrecipe/_editor/static/icons/favicon.ico +0 -0
- figrecipe-0.9.0/src/figrecipe/_integrations/__init__.py +17 -0
- figrecipe-0.9.0/src/figrecipe/_integrations/_scitex_stats.py +298 -0
- figrecipe-0.9.0/src/figrecipe/_params/_DECORATION_METHODS.py +35 -0
- figrecipe-0.9.0/src/figrecipe/_params/_PLOTTING_METHODS.py +58 -0
- figrecipe-0.9.0/src/figrecipe/_params/__init__.py +9 -0
- figrecipe-0.9.0/src/figrecipe/_recorder.py +442 -0
- figrecipe-0.9.0/src/figrecipe/_recorder_utils.py +124 -0
- figrecipe-0.9.0/src/figrecipe/_reproducer/__init__.py +18 -0
- figrecipe-0.9.0/src/figrecipe/_reproducer/_core.py +509 -0
- figrecipe-0.9.0/src/figrecipe/_reproducer/_custom_plots.py +279 -0
- figrecipe-0.9.0/src/figrecipe/_reproducer/_seaborn.py +100 -0
- figrecipe-0.9.0/src/figrecipe/_reproducer/_violin.py +186 -0
- figrecipe-0.9.0/src/figrecipe/_seaborn.py +310 -0
- figrecipe-0.9.0/src/figrecipe/_serializer.py +227 -0
- figrecipe-0.9.0/src/figrecipe/_signatures/README.md +68 -0
- figrecipe-0.9.0/src/figrecipe/_signatures/__init__.py +17 -0
- figrecipe-0.9.0/src/figrecipe/_signatures/_kwargs.py +273 -0
- figrecipe-0.9.0/src/figrecipe/_signatures/_loader.py +243 -0
- figrecipe-0.9.0/src/figrecipe/_signatures/_parsing.py +147 -0
- figrecipe-0.9.0/src/figrecipe/_utils/__init__.py +37 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_bundle.py +205 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_crop.py +267 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_diff.py +98 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_image_diff.py +208 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_numpy_io.py +203 -0
- figrecipe-0.9.0/src/figrecipe/_utils/_units.py +208 -0
- figrecipe-0.9.0/src/figrecipe/_validator.py +195 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/__init__.py +8 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_axes.py +498 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_axes_helpers.py +136 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_axes_plots.py +418 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_axes_seaborn.py +157 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_caption_generator.py +218 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_figure.py +511 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_panel_labels.py +127 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_plot_helpers.py +143 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_stat_annotation.py +274 -0
- figrecipe-0.9.0/src/figrecipe/_wrappers/_violin_helpers.py +180 -0
- figrecipe-0.9.0/src/figrecipe/plt.py +11 -0
- figrecipe-0.9.0/src/figrecipe/pyplot.py +265 -0
- figrecipe-0.9.0/src/figrecipe/styles/__init__.py +51 -0
- figrecipe-0.9.0/src/figrecipe/styles/_dotdict.py +72 -0
- figrecipe-0.9.0/src/figrecipe/styles/_finalize.py +134 -0
- figrecipe-0.9.0/src/figrecipe/styles/_fonts.py +77 -0
- figrecipe-0.9.0/src/figrecipe/styles/_kwargs_converter.py +178 -0
- figrecipe-0.9.0/src/figrecipe/styles/_plot_styles.py +209 -0
- figrecipe-0.9.0/src/figrecipe/styles/_style_applier.py +278 -0
- figrecipe-0.9.0/src/figrecipe/styles/_style_loader.py +402 -0
- figrecipe-0.9.0/src/figrecipe/styles/_themes.py +151 -0
- figrecipe-0.9.0/src/figrecipe/styles/presets/MATPLOTLIB.yaml +95 -0
- figrecipe-0.9.0/src/figrecipe/styles/presets/SCITEX.yaml +188 -0
- figrecipe-0.9.0/tests/__init__.py +3 -0
- figrecipe-0.9.0/tests/editor/__init__.py +3 -0
- figrecipe-0.9.0/tests/editor/conftest.py +122 -0
- figrecipe-0.9.0/tests/editor/test_datatable_theme_aware.py +119 -0
- figrecipe-0.9.0/tests/editor/test_hit_detection.py +103 -0
- figrecipe-0.9.0/tests/editor/test_js_errors.py +106 -0
- figrecipe-0.9.0/tests/editor/test_overrides.py +107 -0
- figrecipe-0.9.0/tests/editor/test_panel_position.py +191 -0
- figrecipe-0.9.0/tests/editor/test_plot_types_registry.py +127 -0
- figrecipe-0.9.0/tests/editor/test_properties.py +101 -0
- figrecipe-0.9.0/tests/editor/test_restore_endpoint.py +90 -0
- figrecipe-0.9.0/tests/editor/test_theme.py +95 -0
- figrecipe-0.9.0/tests/editor/test_toolbar.py +107 -0
- figrecipe-0.9.0/tests/test_alignment.py +280 -0
- figrecipe-0.9.0/tests/test_bundle.py +237 -0
- figrecipe-0.9.0/tests/test_caption_generation.py +198 -0
- figrecipe-0.9.0/tests/test_cli.py +299 -0
- figrecipe-0.9.0/tests/test_composition.py +436 -0
- figrecipe-0.9.0/tests/test_editor_browser.py +75 -0
- figrecipe-0.9.0/tests/test_editor_contourf.py +252 -0
- figrecipe-0.9.0/tests/test_editor_dark_mode.py +251 -0
- figrecipe-0.9.0/tests/test_editor_datatable.py +377 -0
- figrecipe-0.9.0/tests/test_editor_edit_variants.py +284 -0
- figrecipe-0.9.0/tests/test_editor_file_browser.py +339 -0
- figrecipe-0.9.0/tests/test_editor_hitmap.py +300 -0
- figrecipe-0.9.0/tests/test_editor_image_drop.py +284 -0
- figrecipe-0.9.0/tests/test_editor_image_drop_formats.py +201 -0
- figrecipe-0.9.0/tests/test_editor_image_drop_recording.py +162 -0
- figrecipe-0.9.0/tests/test_editor_image_drop_url.py +162 -0
- figrecipe-0.9.0/tests/test_editor_layout_stability.py +312 -0
- figrecipe-0.9.0/tests/test_editor_new_figure.py +241 -0
- figrecipe-0.9.0/tests/test_editor_panel_drag.py +79 -0
- figrecipe-0.9.0/tests/test_editor_panel_drag_snapshot.py +79 -0
- figrecipe-0.9.0/tests/test_editor_panel_snap.py +174 -0
- figrecipe-0.9.0/tests/test_editor_pie_colors.py +226 -0
- figrecipe-0.9.0/tests/test_editor_preferences.py +283 -0
- figrecipe-0.9.0/tests/test_editor_selection_features.py +311 -0
- figrecipe-0.9.0/tests/test_editor_undo_redo.py +251 -0
- figrecipe-0.9.0/tests/test_hit_areas.py +668 -0
- figrecipe-0.9.0/tests/test_integration.py +438 -0
- figrecipe-0.9.0/tests/test_metadata_caption.py +291 -0
- figrecipe-0.9.0/tests/test_recorder.py +163 -0
- figrecipe-0.9.0/tests/test_reproducer_pie_colors.py +85 -0
- figrecipe-0.9.0/tests/test_roundtrip.py +271 -0
- figrecipe-0.9.0/tests/test_roundtrip_all_types.py +257 -0
- figrecipe-0.9.0/tests/test_scitex_stats_integration.py +227 -0
- figrecipe-0.9.0/tests/test_seaborn.py +194 -0
- figrecipe-0.9.0/tests/test_stat_annotation.py +192 -0
- figrecipe-0.9.0/tests/test_stats.py +255 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug to help us improve FigRecipe
|
|
4
|
+
title: "[BUG] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
A clear and concise description of the bug.
|
|
12
|
+
|
|
13
|
+
## To Reproduce
|
|
14
|
+
|
|
15
|
+
Steps to reproduce the behavior:
|
|
16
|
+
|
|
17
|
+
1. ...
|
|
18
|
+
2. ...
|
|
19
|
+
3. ...
|
|
20
|
+
|
|
21
|
+
## Minimal Code Example
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import figrecipe as fr
|
|
25
|
+
|
|
26
|
+
# Minimal code that reproduces the issue
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Expected Behavior
|
|
30
|
+
|
|
31
|
+
What you expected to happen.
|
|
32
|
+
|
|
33
|
+
## Actual Behavior
|
|
34
|
+
|
|
35
|
+
What actually happened.
|
|
36
|
+
|
|
37
|
+
## Error Traceback
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Paste full error traceback here (if applicable)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Environment
|
|
44
|
+
|
|
45
|
+
- OS: [e.g., Ubuntu 22.04, Windows 11, macOS 14]
|
|
46
|
+
- Python version: [e.g., 3.11.5]
|
|
47
|
+
- FigRecipe version: [run `pip show figrecipe`]
|
|
48
|
+
- Matplotlib version: [run `pip show matplotlib`]
|
|
49
|
+
|
|
50
|
+
## Additional Context
|
|
51
|
+
|
|
52
|
+
Add any other context, screenshots, or generated files here.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new feature for FigRecipe
|
|
4
|
+
title: "[FEATURE] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
A clear description of the problem you're trying to solve.
|
|
12
|
+
|
|
13
|
+
Example: "I'm frustrated when trying to..."
|
|
14
|
+
|
|
15
|
+
## Proposed Solution
|
|
16
|
+
|
|
17
|
+
A clear description of what you'd like to happen.
|
|
18
|
+
|
|
19
|
+
## Example Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
import figrecipe as fr
|
|
23
|
+
|
|
24
|
+
# How you envision using this feature
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Alternatives Considered
|
|
28
|
+
|
|
29
|
+
Any alternative solutions or features you've considered.
|
|
30
|
+
|
|
31
|
+
## Additional Context
|
|
32
|
+
|
|
33
|
+
Add any other context, mockups, or references here.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
Brief description of the changes.
|
|
4
|
+
|
|
5
|
+
## Type of Change
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix (non-breaking change that fixes an issue)
|
|
8
|
+
- [ ] New feature (non-breaking change that adds functionality)
|
|
9
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
|
10
|
+
- [ ] Documentation update
|
|
11
|
+
- [ ] Refactoring (no functional changes)
|
|
12
|
+
|
|
13
|
+
## Related Issues
|
|
14
|
+
|
|
15
|
+
Fixes #(issue number)
|
|
16
|
+
|
|
17
|
+
## Changes Made
|
|
18
|
+
|
|
19
|
+
-
|
|
20
|
+
-
|
|
21
|
+
-
|
|
22
|
+
|
|
23
|
+
## Testing
|
|
24
|
+
|
|
25
|
+
- [ ] Tests pass locally (`make test`)
|
|
26
|
+
- [ ] Linter passes (`make lint`)
|
|
27
|
+
- [ ] New tests added (if applicable)
|
|
28
|
+
|
|
29
|
+
## Checklist
|
|
30
|
+
|
|
31
|
+
- [ ] My code follows the project's code style
|
|
32
|
+
- [ ] I have updated the documentation (if needed)
|
|
33
|
+
- [ ] I have added tests that prove my fix/feature works
|
|
34
|
+
- [ ] All new and existing tests pass
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install system fonts (Arial, etc.)
|
|
25
|
+
run: |
|
|
26
|
+
echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections
|
|
27
|
+
sudo apt-get update
|
|
28
|
+
sudo apt-get install -y ttf-mscorefonts-installer fontconfig
|
|
29
|
+
sudo fc-cache -f -v
|
|
30
|
+
# Clear matplotlib font cache
|
|
31
|
+
rm -rf ~/.cache/matplotlib
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
pip install -e ".[all]"
|
|
37
|
+
|
|
38
|
+
- name: Install Playwright browsers
|
|
39
|
+
run: |
|
|
40
|
+
playwright install chromium
|
|
41
|
+
|
|
42
|
+
- name: Run tests
|
|
43
|
+
run: |
|
|
44
|
+
pytest tests/ -v --tb=short --ignore=tests/editor
|
|
45
|
+
|
|
46
|
+
lint:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
|
|
51
|
+
- name: Set up Python
|
|
52
|
+
uses: actions/setup-python@v5
|
|
53
|
+
with:
|
|
54
|
+
python-version: "3.11"
|
|
55
|
+
|
|
56
|
+
- name: Install ruff
|
|
57
|
+
run: pip install ruff
|
|
58
|
+
|
|
59
|
+
- name: Run ruff
|
|
60
|
+
run: ruff check src/
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Claude Code
|
|
2
|
+
CLAUDE.md
|
|
3
|
+
.claude
|
|
4
|
+
docs/to_claude
|
|
5
|
+
REFACTORING.md
|
|
6
|
+
project_management/
|
|
7
|
+
|
|
8
|
+
# Byte-compiled / optimized / DLL files
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.py[cod]
|
|
11
|
+
*$py.class
|
|
12
|
+
|
|
13
|
+
# C extensions
|
|
14
|
+
*.so
|
|
15
|
+
|
|
16
|
+
# Distribution / packaging
|
|
17
|
+
.Python
|
|
18
|
+
build/
|
|
19
|
+
develop-eggs/
|
|
20
|
+
dist/
|
|
21
|
+
downloads/
|
|
22
|
+
eggs/
|
|
23
|
+
.eggs/
|
|
24
|
+
lib/
|
|
25
|
+
lib64/
|
|
26
|
+
parts/
|
|
27
|
+
sdist/
|
|
28
|
+
var/
|
|
29
|
+
wheels/
|
|
30
|
+
*.egg-info/
|
|
31
|
+
.installed.cfg
|
|
32
|
+
*.egg
|
|
33
|
+
|
|
34
|
+
# PyInstaller
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py,cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
|
|
56
|
+
# Translations
|
|
57
|
+
*.mo
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
# Environments
|
|
61
|
+
.env
|
|
62
|
+
.venv
|
|
63
|
+
env/
|
|
64
|
+
venv/
|
|
65
|
+
ENV/
|
|
66
|
+
env.bak/
|
|
67
|
+
venv.bak/
|
|
68
|
+
|
|
69
|
+
# IDE
|
|
70
|
+
.idea/
|
|
71
|
+
.vscode/
|
|
72
|
+
*.swp
|
|
73
|
+
*.swo
|
|
74
|
+
*~
|
|
75
|
+
|
|
76
|
+
# OS
|
|
77
|
+
.DS_Store
|
|
78
|
+
Thumbs.db
|
|
79
|
+
|
|
80
|
+
# Project specific
|
|
81
|
+
outputs/
|
|
82
|
+
!outputs/notebook/
|
|
83
|
+
*.png
|
|
84
|
+
!docs/figrecipe_logo.png
|
|
85
|
+
!docs/images/*.png
|
|
86
|
+
!docs/images/**/*.png
|
|
87
|
+
!outputs/notebook/*.png
|
|
88
|
+
*.yaml
|
|
89
|
+
!.pre-commit-config.yaml
|
|
90
|
+
!pyproject.toml
|
|
91
|
+
!outputs/notebook/*.yaml
|
|
92
|
+
!src/figrecipe/styles/presets/*.yaml
|
|
93
|
+
*.npy
|
|
94
|
+
*.npz
|
|
95
|
+
*.csv
|
|
96
|
+
GITIGNORED/
|
|
97
|
+
examples/.ipynb_checkpoints/
|
|
98
|
+
examples/.old/
|
|
99
|
+
tts_cache/
|
|
100
|
+
|
|
101
|
+
# BGM files (large files excluded, except smile.mp3 for demo)
|
|
102
|
+
docs/bgm/*.mp3
|
|
103
|
+
!docs/bgm/smile.mp3
|
|
104
|
+
|
|
105
|
+
# Claude worktree symlinks
|
|
106
|
+
.worktree-*
|
|
107
|
+
|
|
108
|
+
# Claude worktree symlink
|
|
109
|
+
/feature-demo-movie
|
|
110
|
+
/.claude-worktree-symlinks
|
|
111
|
+
# Claude worktree symlink
|
|
112
|
+
/feature-cli
|
|
113
|
+
# Claude worktree symlink
|
|
114
|
+
/feature-datatable-direct-edit
|
|
115
|
+
|
|
116
|
+
# Example outputs (generated files)
|
|
117
|
+
examples/*/outputs_*/
|
|
118
|
+
# Claude worktree symlink
|
|
119
|
+
/feature-object-support
|
|
120
|
+
# Claude worktree symlink
|
|
121
|
+
/feature-editor-improvements
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
<!-- ---
|
|
2
|
+
!-- Timestamp: 2025-12-22 13:01:11
|
|
3
|
+
!-- Author: ywatanabe
|
|
4
|
+
!-- File: /home/ywatanabe/proj/figrecipe/README.md
|
|
5
|
+
!-- --- -->
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="docs/figrecipe_logo.png" alt="figrecipe logo" width="200"/>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
# FigRecipe
|
|
12
|
+
|
|
13
|
+
**Reproducible matplotlib figures with mm-precision layouts.**
|
|
14
|
+
FigRecipe is a lightweight recording & reproduction layer for matplotlib,
|
|
15
|
+
designed for scientific figures that must remain **editable, inspectable,
|
|
16
|
+
and reproducible**.
|
|
17
|
+
|
|
18
|
+
Part of **SciTeX™ – Research OS for reproducible science**
|
|
19
|
+
https://scitex.ai
|
|
20
|
+
|
|
21
|
+
[](https://badge.fury.io/py/figrecipe)
|
|
22
|
+
[](https://www.gnu.org/licenses/agpl-3.0)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Why FigRecipe?
|
|
27
|
+
|
|
28
|
+
In scientific workflows, figures are often:
|
|
29
|
+
- hard to reproduce once scripts change,
|
|
30
|
+
- resized manually in pixels or inches,
|
|
31
|
+
- impossible to partially reuse or inspect later.
|
|
32
|
+
|
|
33
|
+
**FigRecipe solves this by recording plotting calls as a structured “recipe”**,
|
|
34
|
+
allowing figures to be:
|
|
35
|
+
- faithfully reproduced,
|
|
36
|
+
- partially re-rendered,
|
|
37
|
+
- inspected for underlying data,
|
|
38
|
+
- laid out in **exact millimeters** for publication.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Key Features
|
|
43
|
+
|
|
44
|
+
- ✅ Drop-in replacement for `matplotlib.pyplot`
|
|
45
|
+
- ✅ Automatic recording of plotting calls
|
|
46
|
+
- ✅ Reproduce figures from a YAML recipe
|
|
47
|
+
- ✅ Extract plotted data programmatically
|
|
48
|
+
- ✅ Selective reproduction of specific plots
|
|
49
|
+
- ✅ Millimeter-based layout (journal-ready)
|
|
50
|
+
- ✅ Publication-quality style presets
|
|
51
|
+
- ✅ Dark theme support (data colors preserved)
|
|
52
|
+
- ✅ Seamless seaborn integration
|
|
53
|
+
- ✅ Crop figures to content with mm margins
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install figrecipe
|
|
61
|
+
|
|
62
|
+
# Optional: for PDF export from notebooks (SVG → PDF)
|
|
63
|
+
sudo apt install inkscape # Linux
|
|
64
|
+
brew install inkscape # macOS
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Basic Usage
|
|
69
|
+
|
|
70
|
+
### Recording & Saving
|
|
71
|
+
|
|
72
|
+
``` python
|
|
73
|
+
import figrecipe as fr
|
|
74
|
+
import numpy as np
|
|
75
|
+
|
|
76
|
+
x = np.linspace(0, 10, 100)
|
|
77
|
+
y = np.sin(x)
|
|
78
|
+
|
|
79
|
+
fig, ax = fr.subplots()
|
|
80
|
+
ax.plot(x, y, color='red', linewidth=2, id='sine_wave')
|
|
81
|
+
ax.set_xlabel('Time (s)')
|
|
82
|
+
ax.set_ylabel('Amplitude')
|
|
83
|
+
|
|
84
|
+
# Save image + recipe
|
|
85
|
+
img_path, yaml_path, result = fr.save(fig, 'figure.png')
|
|
86
|
+
# → creates: figure.png + figure.yaml
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Reproducing a Figure
|
|
90
|
+
|
|
91
|
+
``` python
|
|
92
|
+
import figrecipe as fr
|
|
93
|
+
|
|
94
|
+
fig, ax = fr.reproduce('figure.yaml')
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Extracting Plotted Data
|
|
98
|
+
|
|
99
|
+
``` python
|
|
100
|
+
import figrecipe as fr
|
|
101
|
+
|
|
102
|
+
data = fr.extract_data('figure.yaml')
|
|
103
|
+
# {'sine_wave': {'x': array([...]), 'y': array([...])}}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Millimeter-Based Layout (Publication-Ready)
|
|
107
|
+
|
|
108
|
+
``` python
|
|
109
|
+
fig, ax = fr.subplots(
|
|
110
|
+
axes_width_mm=60,
|
|
111
|
+
axes_height_mm=40,
|
|
112
|
+
margin_left_mm=15,
|
|
113
|
+
margin_bottom_mm=12,
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
This guarantees consistent sizing across editors, exports, and journals.
|
|
117
|
+
|
|
118
|
+
### Style Presets
|
|
119
|
+
|
|
120
|
+
``` python
|
|
121
|
+
fr.list_presets()
|
|
122
|
+
# ['MATPLOTLIB', 'SCITEX']
|
|
123
|
+
|
|
124
|
+
# Publication-quality preset (applied globally)
|
|
125
|
+
fr.load_style('SCITEX')
|
|
126
|
+
fig, ax = fr.subplots()
|
|
127
|
+
|
|
128
|
+
# Dark theme (UI-only, data colors preserved)
|
|
129
|
+
fr.load_style('SCITEX_DARK')
|
|
130
|
+
# or: fr.load_style('SCITEX', dark=True)
|
|
131
|
+
|
|
132
|
+
# Custom style
|
|
133
|
+
fr.load_style('/path/to/my_style.yaml')
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
See docs/EXAMPLE_RECIPE.yaml for a full style template.
|
|
137
|
+
|
|
138
|
+
### Recipe Format (YAML)
|
|
139
|
+
|
|
140
|
+
``` yaml
|
|
141
|
+
# Timestamp: "2025-12-22 11:53:14 (ywatanabe)"
|
|
142
|
+
# File: ./docs/EXAMPLE_RECIPE.yaml
|
|
143
|
+
# MATPLOTLIB Style Preset
|
|
144
|
+
# =======================
|
|
145
|
+
# Vanilla matplotlib defaults - minimal customization.
|
|
146
|
+
# Use this to reset to standard matplotlib behavior.
|
|
147
|
+
|
|
148
|
+
axes:
|
|
149
|
+
width_mm: null # Use matplotlib default (auto)
|
|
150
|
+
height_mm: null # Use matplotlib default (auto)
|
|
151
|
+
thickness_mm: null # Use matplotlib default
|
|
152
|
+
|
|
153
|
+
margins:
|
|
154
|
+
left_mm: null
|
|
155
|
+
right_mm: null
|
|
156
|
+
bottom_mm: null
|
|
157
|
+
top_mm: null
|
|
158
|
+
|
|
159
|
+
spacing:
|
|
160
|
+
horizontal_mm: null
|
|
161
|
+
vertical_mm: null
|
|
162
|
+
|
|
163
|
+
fonts:
|
|
164
|
+
family: null # matplotlib default (DejaVu Sans)
|
|
165
|
+
axis_label_pt: null
|
|
166
|
+
tick_label_pt: null
|
|
167
|
+
title_pt: null
|
|
168
|
+
suptitle_pt: null
|
|
169
|
+
legend_pt: null
|
|
170
|
+
annotation_pt: null
|
|
171
|
+
|
|
172
|
+
padding:
|
|
173
|
+
label_pt: null
|
|
174
|
+
tick_pt: null
|
|
175
|
+
title_pt: null
|
|
176
|
+
|
|
177
|
+
lines:
|
|
178
|
+
trace_mm: null
|
|
179
|
+
errorbar_mm: null
|
|
180
|
+
errorbar_cap_mm: null
|
|
181
|
+
|
|
182
|
+
ticks:
|
|
183
|
+
length_mm: null
|
|
184
|
+
thickness_mm: null
|
|
185
|
+
direction: null
|
|
186
|
+
n_ticks: null
|
|
187
|
+
|
|
188
|
+
markers:
|
|
189
|
+
size_mm: null
|
|
190
|
+
scatter_mm: null
|
|
191
|
+
edge_width_mm: null
|
|
192
|
+
|
|
193
|
+
legend:
|
|
194
|
+
frameon: null # matplotlib default (True)
|
|
195
|
+
bg: null # matplotlib default
|
|
196
|
+
edgecolor: null # matplotlib default
|
|
197
|
+
alpha: null # matplotlib default
|
|
198
|
+
loc: null # matplotlib default
|
|
199
|
+
|
|
200
|
+
output:
|
|
201
|
+
dpi: 300
|
|
202
|
+
transparent: false
|
|
203
|
+
format: "png"
|
|
204
|
+
|
|
205
|
+
behavior:
|
|
206
|
+
auto_scale_axes: false
|
|
207
|
+
hide_top_spine: false
|
|
208
|
+
hide_right_spine: false
|
|
209
|
+
grid: false
|
|
210
|
+
|
|
211
|
+
theme:
|
|
212
|
+
mode: "light"
|
|
213
|
+
dark:
|
|
214
|
+
figure_bg: "#1e1e1e"
|
|
215
|
+
axes_bg: "#1e1e1e"
|
|
216
|
+
legend_bg: "#1e1e1e"
|
|
217
|
+
text: "#d4d4d4"
|
|
218
|
+
spine: "#3c3c3c"
|
|
219
|
+
tick: "#d4d4d4"
|
|
220
|
+
grid: "#3a3a3a"
|
|
221
|
+
light:
|
|
222
|
+
figure_bg: "white"
|
|
223
|
+
axes_bg: "white"
|
|
224
|
+
legend_bg: "white"
|
|
225
|
+
text: "black"
|
|
226
|
+
spine: "black"
|
|
227
|
+
tick: "black"
|
|
228
|
+
grid: "#cccccc"
|
|
229
|
+
|
|
230
|
+
# Standard matplotlib color cycle (tab10)
|
|
231
|
+
colors:
|
|
232
|
+
palette:
|
|
233
|
+
- [31, 119, 180] # tab:blue
|
|
234
|
+
- [255, 127, 14] # tab:orange
|
|
235
|
+
- [44, 160, 44] # tab:green
|
|
236
|
+
- [214, 39, 40] # tab:red
|
|
237
|
+
- [148, 103, 189] # tab:purple
|
|
238
|
+
- [140, 86, 75] # tab:brown
|
|
239
|
+
- [227, 119, 194] # tab:pink
|
|
240
|
+
- [127, 127, 127] # tab:gray
|
|
241
|
+
- [188, 189, 34] # tab:olive
|
|
242
|
+
- [23, 190, 207] # tab:cyan
|
|
243
|
+
|
|
244
|
+
# EOF
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The recipe is human-readable, version-controllable, and inspectable.
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
### API Overview
|
|
251
|
+
|
|
252
|
+
| Function | Description |
|
|
253
|
+
| ----------------------------- | --------------------------------- |
|
|
254
|
+
| `fr.subplots()` | Create a recording-enabled figure |
|
|
255
|
+
| `fr.save(fig, 'fig.png')` | Save image + recipe |
|
|
256
|
+
| `fr.reproduce('fig.yaml')` | Reproduce figure from recipe |
|
|
257
|
+
| `fr.extract_data('fig.yaml')` | Extract plotted data |
|
|
258
|
+
| `fr.info('fig.yaml')` | Inspect recipe metadata |
|
|
259
|
+
| `fr.load_style()` | Load style preset (global) |
|
|
260
|
+
| `fr.list_presets()` | List available presets |
|
|
261
|
+
| `fr.crop('fig.png')` | Crop to content with mm margin |
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
### Examples
|
|
265
|
+
- 📓 Interactive demo notebook:
|
|
266
|
+
examples/figrecipe_demo.ipynb
|
|
267
|
+
|
|
268
|
+
- 🌐 View on nbviewer:
|
|
269
|
+
https://nbviewer.org/github/ywatanabe1989/figrecipe/blob/main/examples/figrecipe_demo.ipynb
|
|
270
|
+
|
|
271
|
+
The notebook includes side-by-side comparisons of original and reproduced figures.
|
|
272
|
+
|
|
273
|
+
## Positioning
|
|
274
|
+
|
|
275
|
+
FigRecipe is intentionally minimal.
|
|
276
|
+
It focuses on recording, reproduction, and layout fidelity.
|
|
277
|
+
|
|
278
|
+
Higher-level workflows (figures, tables, statistics, GUIs) are handled in:
|
|
279
|
+
|
|
280
|
+
FTS (Figure-Table-Statics Bundle) in SciTeX ecosystem (https://scitex.ai/vis/)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
AGPL-3.0 See [LICENSE](LICENSE)
|
|
286
|
+
.
|
|
287
|
+
|
|
288
|
+
<!-- EOF -->
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
|
|
10
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
+
rev: v0.8.4
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff
|
|
14
|
+
args: [--fix]
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
|
|
17
|
+
- repo: local
|
|
18
|
+
hooks:
|
|
19
|
+
- id: pytest
|
|
20
|
+
name: pytest
|
|
21
|
+
entry: python -m pytest tests/ -n auto --dist loadfile -x -q --tb=short
|
|
22
|
+
language: system
|
|
23
|
+
types: [python]
|
|
24
|
+
pass_filenames: false
|
|
25
|
+
stages: [pre-commit]
|