figscribe 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ # macOS
2
+ .DS_Store
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.egg-info/
8
+ build/
9
+ dist/
10
+ .eggs/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+
16
+ # Tests and tooling
17
+ .pytest_cache/
18
+ .mypy_cache/
19
+ .ruff_cache/
20
+ .coverage
21
+ htmlcov/
22
+
23
+ # Test artifacts (image comparisons)
24
+ tests/**/output/
25
+ *.actual.png
26
+
27
+ # Editors
28
+ .idea/
29
+ .vscode/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 f4ren
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.5
2
+ Name: figscribe
3
+ Version: 0.0.1
4
+ Summary: A lean desktop GUI for scientific Matplotlib plots that exports clean, standalone Python code instead of a proprietary project file.
5
+ Project-URL: Homepage, https://github.com/f4ren/figscribe
6
+ Project-URL: Source, https://github.com/f4ren/figscribe
7
+ Project-URL: Issues, https://github.com/f4ren/figscribe/issues
8
+ Author: Christian Krause
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: code-generation,gui,matplotlib,plotting,science
12
+ Classifier: Development Status :: 1 - Planning
13
+ Classifier: Environment :: X11 Applications :: Qt
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Visualization
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+
23
+ # figscribe
24
+
25
+ A lean desktop GUI for scientific plots: build and fine-tune figures
26
+ interactively, and get **clean, standalone Python code** (Matplotlib) as the
27
+ result instead of a proprietary project file.
28
+
29
+ Intended for scientists and engineers who find Origin unwieldy but don't want to
30
+ hand-write every detail of a Matplotlib figure just to fine-tune it.
31
+
32
+ ## Status
33
+
34
+ **Very early — planning stage.** Nothing usable has been implemented yet; the
35
+ PyPI entry is a placeholder release that reserves the name.
36
+
37
+ The full project plan lives in [`plan/`](plan/).
38
+
39
+ ## Design principle
40
+
41
+ The declarative plot model is the single source of truth:
42
+
43
+ ```
44
+ Plot model (typed, JSON-serializable)
45
+ ├──> Renderer: model -> Matplotlib figure (GUI preview AND export)
46
+ ├──> Code generator: model -> standalone Python script
47
+ └──> Persistence: model <-> JSON project file
48
+ ```
49
+
50
+ The GUI only ever reads and mutates the model, through commands with undo/redo —
51
+ it never manipulates Matplotlib objects directly. Preview and export share the
52
+ same renderer, so what you see is what you get. The generated code reproduces the
53
+ same figure and runs without figscribe installed.
54
+
55
+ ## Scope
56
+
57
+ Planned for the MVP: data import (CSV, HDF5, NPY/NPZ), line/scatter/errorbar
58
+ plots, histograms, 2D images and color meshes, curve fitting via
59
+ `scipy.optimize.curve_fit`, multi-panel layouts with shared axes, LaTeX labels,
60
+ undo/redo, export to PDF/SVG/PNG at exact millimeter sizes, and Matplotlib style
61
+ templates for journal-column widths.
62
+
63
+ Deliberately out of scope: spreadsheet-style data editing, a statistics suite, a
64
+ custom scripting language, and reading generated or third-party Python code back
65
+ in.
66
+
67
+ ## Stack
68
+
69
+ Python >= 3.11, PySide6, Matplotlib, NumPy, SciPy, h5py.
70
+
71
+ ## License
72
+
73
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,51 @@
1
+ # figscribe
2
+
3
+ A lean desktop GUI for scientific plots: build and fine-tune figures
4
+ interactively, and get **clean, standalone Python code** (Matplotlib) as the
5
+ result instead of a proprietary project file.
6
+
7
+ Intended for scientists and engineers who find Origin unwieldy but don't want to
8
+ hand-write every detail of a Matplotlib figure just to fine-tune it.
9
+
10
+ ## Status
11
+
12
+ **Very early — planning stage.** Nothing usable has been implemented yet; the
13
+ PyPI entry is a placeholder release that reserves the name.
14
+
15
+ The full project plan lives in [`plan/`](plan/).
16
+
17
+ ## Design principle
18
+
19
+ The declarative plot model is the single source of truth:
20
+
21
+ ```
22
+ Plot model (typed, JSON-serializable)
23
+ ├──> Renderer: model -> Matplotlib figure (GUI preview AND export)
24
+ ├──> Code generator: model -> standalone Python script
25
+ └──> Persistence: model <-> JSON project file
26
+ ```
27
+
28
+ The GUI only ever reads and mutates the model, through commands with undo/redo —
29
+ it never manipulates Matplotlib objects directly. Preview and export share the
30
+ same renderer, so what you see is what you get. The generated code reproduces the
31
+ same figure and runs without figscribe installed.
32
+
33
+ ## Scope
34
+
35
+ Planned for the MVP: data import (CSV, HDF5, NPY/NPZ), line/scatter/errorbar
36
+ plots, histograms, 2D images and color meshes, curve fitting via
37
+ `scipy.optimize.curve_fit`, multi-panel layouts with shared axes, LaTeX labels,
38
+ undo/redo, export to PDF/SVG/PNG at exact millimeter sizes, and Matplotlib style
39
+ templates for journal-column widths.
40
+
41
+ Deliberately out of scope: spreadsheet-style data editing, a statistics suite, a
42
+ custom scripting language, and reading generated or third-party Python code back
43
+ in.
44
+
45
+ ## Stack
46
+
47
+ Python >= 3.11, PySide6, Matplotlib, NumPy, SciPy, h5py.
48
+
49
+ ## License
50
+
51
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,179 @@
1
+ # Project brief: figscribe
2
+
3
+ ## Goal
4
+
5
+ Build a lean desktop GUI for scientific plots that lets you create and fine-tune
6
+ figures interactively and produces **clean, standalone Python code**
7
+ (Matplotlib) as its output, rather than a proprietary project file.
8
+
9
+ Audience: scientists and engineers who find Origin unwieldy but don't want to
10
+ hand-write every detail in Matplotlib just to fine-tune a figure.
11
+
12
+ ## Architectural principle (binding)
13
+
14
+ **The declarative plot model is the single source of truth.**
15
+
16
+ ```
17
+ Plot model (dataclasses, JSON-serializable)
18
+ │
19
+ ├──> Renderer: model -> Matplotlib figure (for GUI preview AND export)
20
+ ├──> Code generator: model -> standalone Python script
21
+ └──> Persistence: model <-> JSON project file
22
+ GUI: reads and mutates the model exclusively, via commands (see undo/redo)
23
+ ```
24
+
25
+ Rules:
26
+ - The GUI never manipulates Matplotlib objects directly in a persistent way.
27
+ Every change runs as a command against the model, followed by a re-render.
28
+ - Preview and export use the same renderer. What you see is exactly what gets
29
+ exported (at the same figure size and DPI).
30
+ - The generated code must run without figscribe installed and must produce the
31
+ same figure as the renderer.
32
+ - Reading generated code back in is **not** a goal. Users are free to edit the
33
+ code further; from that point it is theirs.
34
+
35
+ ## Plot model (first draft, may be refined)
36
+
37
+ - `Project`: list of `Figure`, list of `DataSource`, metadata (version, creation
38
+ date)
39
+ - `DataSource`: path, format (CSV, HDF5, NPY/NPZ), import options (delimiter,
40
+ header row, HDF5 dataset path), SHA-256 of the file
41
+ - `Figure`: size in mm, DPI, stylesheet, layout (grid of rows and columns,
42
+ shared axes)
43
+ - `Axes`: position in the grid, x/y label (LaTeX allowed), units, scale
44
+ (linear/log/symlog), limits (auto or fixed), ticks, optional secondary y-axis,
45
+ legend (position, visibility, frame)
46
+ - `Artist` (union type):
47
+ - `LinePlot`, `ScatterPlot`, `ErrorbarPlot` (x, y, xerr, yerr as column
48
+ references)
49
+ - `Histogram` (bins, normalization)
50
+ - `ImagePlot` / `ColorMesh` (2D data, colormap, colorbar, normalization)
51
+ - `FitCurve` (reference to a data artist, model function, initial values,
52
+ resulting parameters with uncertainties, optional residual panel)
53
+ - `Annotation` (text, position in data or axes coordinates, optional arrow)
54
+ - Style properties per artist: color, line style, marker, line width, alpha,
55
+ label, z-order
56
+
57
+ All model classes: typed, validatable, losslessly JSON-serializable with a
58
+ schema version for later migrations.
59
+
60
+ ## MVP feature set
61
+
62
+ 1. **Data import**: CSV, HDF5, NPY/NPZ. Column preview, selection of columns for
63
+ x, y and errors. No spreadsheet, no column formulas.
64
+ 2. **Plotting**: the artist types from the model.
65
+ 3. **Canvas interaction**:
66
+ - Click an element: it gets selected, its properties appear in the property
67
+ panel
68
+ - Drag the legend, annotations and labels to move them
69
+ - Zoom and pan, and adopt the current view as fixed limits
70
+ 4. **Property panel**: generated generically from the model fields, with
71
+ specialized editors where it makes sense (color picker, marker selection).
72
+ 5. **Axes**: log/linear, secondary y-axis, LaTeX labels, units.
73
+ 6. **Layouts**: multi-panel grid with shared axes.
74
+ 7. **Fits**: `scipy.optimize.curve_fit`, predefined models (linear, polynomial,
75
+ Gaussian, Lorentzian, exponential) plus a custom expression. Output:
76
+ parameters with 1-sigma uncertainties, reduced chi-square, optional residual
77
+ plot.
78
+ 8. **Undo/redo**: command pattern across all model changes.
79
+ 9. **Export**: PDF, SVG and PNG at exact sizes in mm.
80
+ 10. **Code generation**: a single Python script with
81
+ - header: date, figscribe version, package versions, data paths with SHA-256
82
+ - data loading, plotting and saving in clearly commented sections
83
+ - only standard dependencies (numpy, matplotlib, optionally scipy, h5py)
84
+ 11. **Style templates**: Matplotlib stylesheets (`.mplstyle`), shipping with a
85
+ neutral default and a journal-style template (single column approx. 85 mm,
86
+ double column approx. 175 mm).
87
+
88
+ ## Deliberate non-goals
89
+
90
+ - No spreadsheet or data editing
91
+ - No statistics suite
92
+ - No custom scripting language
93
+ - No reading back generated or third-party Python code
94
+ - No Origin import in the MVP (possibly later for .opj via liborigin)
95
+
96
+ ## Non-functional requirements
97
+
98
+ - Pixel-identical agreement between preview and export
99
+ - Fluid interaction up to approx. 10^6 data points (downsampling in the preview
100
+ only; export always uses the full data)
101
+ - Platforms: Linux, Windows, macOS
102
+ - Reproducibility: project file and generated code contain data hashes and
103
+ versions
104
+
105
+ ## Technical stack
106
+
107
+ - Python >= 3.11
108
+ - PySide6 (Qt) for the GUI, Matplotlib canvas via `FigureCanvasQTAgg`
109
+ - Matplotlib as the only renderer
110
+ - NumPy, SciPy, h5py
111
+ - Model: dataclasses or pydantic (make a reasoned decision and document it)
112
+ - Tests: pytest, pytest-qt
113
+ - Packaging: `pyproject.toml`, later PyInstaller or Briefcase for installers
114
+ - License: MIT
115
+
116
+ ## Proposed project structure
117
+
118
+ ```
119
+ figscribe/
120
+ model/ # dataclasses, validation, JSON (de)serialization, schema versions
121
+ render/ # model -> Matplotlib
122
+ codegen/ # model -> Python script
123
+ io/ # data import (CSV, HDF5, NPY)
124
+ fit/ # fit models and execution
125
+ commands/ # command pattern, undo/redo
126
+ gui/ # main window, canvas, property panel, dialogs
127
+ styles/ # bundled .mplstyle files
128
+ tests/
129
+ examples/ # example data and example projects
130
+ ```
131
+
132
+ ## Test strategy (important)
133
+
134
+ 1. **Model roundtrip**: model -> JSON -> model yields equality.
135
+ 2. **Codegen equivalence** (core test): for each example project
136
+ - the renderer produces PNG A
137
+ - the generated script is run in a subprocess and produces PNG B
138
+ - A and B must be pixel-identical (or within a very small, justified
139
+ tolerance)
140
+ 3. **Image regression tests** for the renderer against reference images.
141
+ 4. **Command tests**: every change must be exactly reversible via undo.
142
+ 5. **GUI smoke tests** with pytest-qt.
143
+
144
+ ## Milestones
145
+
146
+ 1. **M1 model and renderer**: model, JSON persistence, renderer for line,
147
+ scatter and errorbar, export. No GUI yet. Tests 1 and 3.
148
+ 2. **M2 code generator**: codegen for all M1 features, equivalence test (test 2)
149
+ green.
150
+ 3. **M3 GUI skeleton**: main window, data import dialog, canvas, click to
151
+ select, generic property panel, undo/redo.
152
+ 4. **M4 interaction**: drag for legend, labels and annotations, adopt zoom as
153
+ limits.
154
+ 5. **M5 extensions**: multi-panel layouts, secondary y-axis, histogram, 2D
155
+ plots, colorbar.
156
+ 6. **M6 fits**: fit dialog, result display, residual panel, codegen including
157
+ the fit.
158
+ 7. **M7 polish**: style templates, snapping and alignment guides, packaging.
159
+
160
+ Every milestone ends with green tests and a runnable state.
161
+
162
+ ## Working agreement for the coding agent
163
+
164
+ - Before M1: present the plot model as a code draft with a rationale, and only
165
+ then implement.
166
+ - Work in small, test-driven steps: test first, then implementation.
167
+ - Record architectural decisions briefly in `docs/decisions.md` (context,
168
+ decision, alternatives).
169
+ - No new dependencies without a rationale.
170
+ - When the model is unclear, ask rather than guess.
171
+ - Generated code should look the way an experienced human would write it:
172
+ readable, commented, free of figscribe-internal helper functions.
173
+
174
+ ## Optional, after the MVP
175
+
176
+ - Natural-language input via an LLM that produces **commands against the model**
177
+ (not code), so that everything stays traceable and undoable.
178
+ - Import of older Origin projects (.opj) via liborigin.
179
+ - Live data mode (watch a file, update the plot).
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "figscribe"
7
+ version = "0.0.1"
8
+ description = "A lean desktop GUI for scientific Matplotlib plots that exports clean, standalone Python code instead of a proprietary project file."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [{ name = "Christian Krause" }]
12
+ keywords = ["matplotlib", "plotting", "gui", "science", "code-generation"]
13
+ classifiers = [
14
+ "Development Status :: 1 - Planning",
15
+ "Environment :: X11 Applications :: Qt",
16
+ "Intended Audience :: Science/Research",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Scientific/Engineering :: Visualization",
22
+ ]
23
+ license = "MIT"
24
+ license-files = ["LICENSE"]
25
+ dependencies = []
26
+
27
+ [project.urls]
28
+ Homepage = "https://github.com/f4ren/figscribe"
29
+ Source = "https://github.com/f4ren/figscribe"
30
+ Issues = "https://github.com/f4ren/figscribe/issues"
31
+
32
+ [tool.hatch.build.targets.wheel]
33
+ packages = ["src/figscribe"]
@@ -0,0 +1,7 @@
1
+ """figscribe - scientific plots via a GUI, exported as standalone Python code.
2
+
3
+ This is a placeholder release that reserves the package name. Implementation has
4
+ not started yet; see the project repository for the plan.
5
+ """
6
+
7
+ __version__ = "0.0.1"