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.
- figscribe-0.0.1/.gitignore +29 -0
- figscribe-0.0.1/LICENSE +21 -0
- figscribe-0.0.1/PKG-INFO +73 -0
- figscribe-0.0.1/README.md +51 -0
- figscribe-0.0.1/plan/project-brief.md +179 -0
- figscribe-0.0.1/pyproject.toml +33 -0
- figscribe-0.0.1/src/figscribe/__init__.py +7 -0
|
@@ -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/
|
figscribe-0.0.1/LICENSE
ADDED
|
@@ -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.
|
figscribe-0.0.1/PKG-INFO
ADDED
|
@@ -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"]
|