GraphDigitizer is a small interactive GUI tool (Julia + Gtk) for extracting numeric data points from raster images of graphs (PNG/JPEG). It supports non-blocking calibration, manual point picking and editing, a color-based auto-trace routine, a precision circular zoom for pixel-level placement, and export to JSON and CSV. The application is defensive about platform differences in Gtk.jl and provides fallbacks when native dialogs are unavailable.
See Project.toml for the packaged version (1.0.0). The runtime binary identifies itself via constants in src/graph_digitizer.jl.
- Source: src/graph_digitizer.jl
- Docs: docs/*.md
- Features
- Requirements
- Installation
- Running
- Quickstart (how to use)
- File formats (JSON / CSV)
- Default filename & fallback behavior
- Keyboard shortcuts & UI notes
- Troubleshooting
- Contributing
- License
- Load PNG/JPEG images and display in a scalable canvas.
- Non-blocking calibration: record four clicks (X-left, X-right, Y-bottom, Y-top) then apply numeric axis ranges (linear or log10).
- Manual point picking: left-click to add, drag to move, right-click or Delete to remove.
- Precision placement overlay (Alt+Z): circular magnifier (~1 cm radius) with configurable magnification for pixel-accurate placement.
- Rectangular magnifier preview near the mouse (optional in UI).
- Auto-trace: column-by-column color matching using a dataset's hex color to extract curve points.
- Multiple datasets (color-coded), per-dataset editing and name/color controls.
- Export to JSON (metadata + datasets) and CSV (rows: dataset, x, y).
- Robust file chooser fallbacks: when a native save dialog cannot be created, a sensible fallback filename is written to your Downloads folder (or system temp) and the path is shown in the status label.
- Defensive Gtk usage: helpers attempt multiple Gtk.jl APIs so the app works across Gtk.jl and GTK versions.
- Julia 1.6 or newer is recommended.
- Gtk runtime (GTK 3/4) present on the system (Gtk.jl may require a system-provided GTK on some platforms).
- Project dependencies are pinned in
Project.toml/Manifest.tomland installed with the Julia package system.
- Clone the repository and change into it:
git clone <repo-url>
cd Graph_Digitizer
- Use Julia to instantiate the pinned environment (this will install packages listed in
Project.toml/Manifest.toml):
julia --project=@. -e 'using Pkg; Pkg.instantiate()'
Note: If Gtk.jl prints warnings about native dependencies while installing, follow the Gtk.jl instructions for your OS (Linux distributions typically need system GTK packages; Windows typically uses prebuilt binaries).
Start the GUI from the project root:
julia --project=@. src/graph_digitizer.jl
Keep the launching terminal open to view diagnostic messages, warnings, or crash traces — the app prints helpful startup and error information to stdout/stderr.
A minimal workflow to digitize a plot:
-
Load an image
- Click the
Load Imagetoolbar button and select a PNG or JPEG file. - After loading, the image displays in the central canvas.
- Click the
-
Calibrate (non-blocking)
- Click
Calibrate Clicks. The app enters calibration mode and waits for four clicks (do not close the dialog). - Click in this order on the image:
- X-left pixel — canvas pixel corresponding to the known left-hand x value.
- X-right pixel — pixel for the known right-hand x value.
- Y-bottom pixel — pixel for the known bottom y value.
- Y-top pixel — pixel for the known top y value.
- The status label updates as clicks are recorded.
- Click
-
Enter numeric axis ranges and apply
- Fill the
X min,X max,Y min,Y maxboxes. - Toggle
X log/Y logif the axis is logarithmic (base 10). - Click
Apply Calibration. After applying, data↔canvas transforms become active.
- Fill the
-
Add / move / delete points
- Add: left-click on the curve to add a point (coordinates mapped from canvas → data using the calibration).
- Move: left-click near an existing point to select then drag to reposition.
- Delete: right-click a point, use the
Delete Selected Pointbutton, or press Delete/Backspace when a point is selected.
-
Precision placement (Alt+Z)
- With the canvas focused, press Alt+Z to toggle the circular precision overlay centered on the last mouse position.
- Move the mouse to refine the center; left-click to add a point at the center of the overlay.
- Press Alt+Z again to exit precision mode.
-
Auto-trace
- Select the dataset you want to populate via the dataset combo box.
- Ensure calibration is applied and an image is loaded.
- Click
Auto Trace Active Dataset. The algorithm scans columns between the calibrated X pixel bounds and chooses, per column, the pixel row closest in RGB Euclidean distance to the dataset color. Results replace the active dataset's points.
-
Save / Export
- Use toolbar buttons,
Filemenu, or keyboard accelerators:- Primary+S (Ctrl+S on Windows and Linux) — Save JSON (metadata + datasets).
- Primary+Shift+S — Save CSV (rows: dataset, x, y).
- A Save dialog will be used when available. If a dialog cannot be constructed (some Gtk.jl or environment combinations), the app falls back to writing into your Downloads folder (or system temp) using a generated filename and updates the status label with the full path used.
- Use toolbar buttons,
JSON export
- Contains metadata and datasets. Example structure:
{
"title": "...",
"xlabel": "...",
"ylabel": "...",
"x_min": 0.0,
"x_max": 10.0,
"y_min": 0.0,
"y_max": 100.0,
"x_log": false,
"y_log": false,
"datasets": [
{
"name": "Dataset 1",
"color": "#0072B2",
"points": [[x1, y1], [x2, y2], ...]
}
]
}
CSV export
- Simple tabular export with columns:
dataset,x,y. Each row represents one point.
- Default filename base: the
Titlefield is used (sanitized — non-alphanumeric characters replaced with underscores and repeated underscores collapsed). If empty, a timestamped name is used. - Fallback save path: when a native save dialog is unavailable, the app chooses your
Downloadsfolder (if present) or the system temporary directory and writes the file there. The status label shows the chosen path so you can retrieve the file.
- Save JSON: Primary+S (Ctrl+S on Windows and Linux)
- Save CSV: Primary+Shift+S
- Exit: Primary+Q (Ctrl+Q on Windows and Linux)
- Precision Zoom toggle: Alt+Z (requires canvas focus)
- Delete selected point: Delete / Backspace or the
Delete Selected Pointbutton - The app registers accelerators defensively; behavior may vary slightly on some window managers or Gtk.jl builds.
- App window does not appear / Save dialogs do not open:
- Inspect the terminal where you launched the app for error messages. Gtk.jl prints helpful diagnostic information.
- If the Save dialog is unavailable the app will still try to save into
~/Downloads(or temp) and will show the path used in the status label.
- Gtk.jl errors about native GTK on Linux:
- Install your distribution's GTK development/runtime packages (for example
libgtk-3-dev,gtk3or similar).
- Install your distribution's GTK development/runtime packages (for example
- Keyboard accelerators not working:
- Some window managers intercept key combinations (e.g., global shortcuts). Use toolbar/menu actions as fallback.
- App crashes or shows UndefVarError:
- Ensure you used
julia --project=@.andPkg.instantiate()to create the same package environment as the repository'sProject.toml/Manifest.toml. If the problem persists, capture the terminal output and open an issue with steps to reproduce and the stack trace.
- Ensure you used
- Main source:
src/graph_digitizer.jl. Core utilities and helpers are documented indocs/*.md. - Coordinate transforms:
data_to_canvas(state, x, y)maps data coordinates to canvas pixels (respects log flags).canvas_to_data(state, cx, cy)maps canvas pixels back to data coordinates.- Calibration anchors are recorded as four canvas pixel positions:
px_xmin,px_xmax,px_ymin,px_ymax.
- Auto-trace:
- Uses a per-column nearest-RGB Euclidean match to the dataset color. It samples columns between the calibrated X pixel anchors and converts found pixel rows to data coordinates.
- Safe dialogs:
- The code has
safe_open_dialog/safe_save_dialoghelpers that attempt multiple Gtk APIs and provide fallbacks to ensure the app is usable in constrained environments.
- The code has
Helpful contributions:
- Bug reports with a minimal reproduction, OS, Julia version, and Gtk.jl version.
- Patches for compatibility across Gtk.jl/Gtk versions.
- Unit tests for coordinate transforms (
data_to_canvas/canvas_to_data) and_sanitize_filename. - Documentation improvements and example images for manual testing.
To develop:
- Open the repository and start a Julia REPL using the project environment:
julia --project=@.
- Run scripts or directly evaluate portions of
src/graph_digitizer.jlfrom the REPL, or run the app to interactively test.
This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.
If you encounter problems or have enhancement ideas, please open an issue on the repository with:
- Repro steps
- Platform (OS), Julia version, Gtk.jl version
- Terminal output (errors/tracebacks)
Thank you for using GraphDigitizer — if you find it useful, contributions and feedback are welcome.