Releases: katalystnord/plottracer
Release list
v1.5.1
PlotTracer 1.5.1
One fix: a curve fit through a flat series reported R² = 1.00000 — a
perfect score for a model that explained nothing.
Why it happened
R² is 1 − SSres/SStot, where SStot is how much the data varies about its own
mean — how much there was to explain in the first place. When every value in a
series is the same, SStot is exactly zero: every point is the mean. The ratio
divides by zero, and R² has no value at all.
The code returned 1 in that case. That was not a rounding artifact — the
residual never entered the calculation, so the 1 would have been identical had
the fit been wildly wrong. It was a written-in default standing where the formula
has no answer.
What it looked like
Fitting a horizontal baseline — an ordinary thing to trace: a control series that
doesn't move, a saturated plateau — printed R² = 1.00000 on the Curve fit card,
and wrote 1 into the R2 column of every export. On a nonlinear model it could
appear directly beside the red "this fit did not settle", which is a contradiction
the app should never show.
What it does now
R² is reported as absent when the series has no variation:
- the card shows
R² = —and says why: R² needs variation to measure against, and
every value in this series is the same - the
R2column exports a blank cell, never a fabricated number — the same
rule PlotTracer already applies to any value that was not measured - JSON omits
rSquaredrather than nulling it, matching the schema's
convention that an absent field means the thing does not apply
RMS is unaffected and is the number to read there. It needs no reference
variance, it is in the data's own units, and it was honest all along.
Unchanged on purpose: a negative R² on a genuinely poor nonlinear fit is
correct and still reported — for a nonlinear model R² is not a proportion of
explained variance and is not bounded below by zero. Only the zero-variance case
became absent.
Downloads
Installers for Linux (.AppImage, .deb), macOS (Apple Silicon .dmg) and
Windows (.exe) are attached below.
These builds are unsigned. macOS will need Right-click → Open the first time,
and Windows will show a SmartScreen warning — choose More info → Run anyway.
Full Changelog: v1.5.0...v1.5.1
v1.5.0
PlotTracer 1.5.0
Opens other digitizers' projects, fits shapes rather than only polynomials, and
says what an export will leave behind before you choose the format.
Opens other digitizers' projects
One Open Project command now reads projects written by WebPlotDigitizer,
Engauge Digitizer and StarryDigitizer, alongside PlotTracer's own. There
is no per-tool menu item and no per-tool file filter: the format is recognised by
what is inside the file, not by its extension, so a renamed file still opens.
Anything that cannot be read faithfully is refused with a reason — the old
binary Engauge format, an unsupported coordinate system, a calibration the file
does not actually contain. A partial import that looked complete would be worse
than no import at all.
When a project holds more than PlotTracer can open at once — an Engauge document
containing several coordinate systems is several figures — the first is opened and
the app says what it did not bring.
Fit a shape, not just a polynomial
Curve fitting adds five nonlinear models beside the polynomial:
| Model | Form |
|---|---|
| Exponential | y = a·e^(b·x) |
| Power | y = a·x^b |
| Logarithmic | y = a + b·ln(x) |
| Gaussian | y = a·e^(−(x−b)²/2c²) |
| Logistic | y = a / (1 + e^(−b(x−c))) |
Each option spells out its own equation, so the choice is readable without prior
knowledge. Degree belongs to the polynomial and disappears for the others. A
model that cannot take your data is refused by naming the requirement it needs
rather than returning a number it cannot stand behind, and Restrict fits over
a chosen x range.
A fit that did not settle now says so in the file, not just on screen. These
models are solved iteratively, and a solver that runs out of iterations still
returns something. The card has always shown that in red; the export did not carry
it, so a settled fit and an abandoned one were indistinguishable to whoever opened
the file. The Curve fit block gained a settled column, and the sampled
curve block says (did not settle) in its title — that block is built to be
lifted out on its own.
Exports say what they cannot carry
Choosing an export format now shows what that format will leave behind before
you pick it. No data format carries the figure image, the axis calibration or the
source document — save a project to keep those — and formats name their own limits
(MATLAB becomes a cell array once any cell holds text; flat text formats put every
block into one stream).
Fixes
- A number is never a date.
dateConversion.parseapplied its "must contain a
separator" guard only to strings, so a bare number between 0 and 23 was read as
an hour of today and ordinary axis values became timestamps around 1.78e12. Only
0–23 were affected, which is why 100 behaved and 10 did not. Fixed in the model,
so every entrance — interactive, project load, and every import filter — gets the
same answer. - Engauge angles in gradians or turns were read as radians: a point whose true
angle was 0° exported as 49.21 or 5.62. All four of the format's angle units are
now read correctly, and an unrecognised unit is refused by name. - A multi-figure Engauge document was reduced to its first, silently. The
disclosure was keyed on an element that does not exist in the format, so it could
never appear. On real files this dropped most of the recorded points without a
word. - StarryDigitizer projects with no tilt setting were rotation-corrected anyway,
the opposite of that tool's own default. - The import notice no longer outlives the figure it describes.
- The
Curve fitexport gained amodelcolumn, and no longer reports a
degree for models that have none — it was the leftover value of a hidden control. - The PNG snapshot is separated from the data formats, so the note about what those
formats cannot carry no longer reads as though it covered the one export that
carries exactly that.
Also
OpenDocument (.ods) export. Saved projects record which build wrote them.
Downloads
Installers for Linux (.AppImage, .deb), macOS (Apple Silicon .dmg) and
Windows (.exe) are attached below.
These builds are unsigned. macOS will need Right-click → Open the first time,
and Windows will show a SmartScreen warning — choose More info → Run anyway.
Full Changelog: v1.4.0...v1.5.0
v1.4.0
v1.3.0
Your exported data says which points you placed and which the app filled in
PlotTracer's whole claim is that a record tells you where its numbers came from.
That held inside the project file, but not once you handed the data to anyone
else: an interpolated spline sample left a CSV byte-identical to a point you had
judged by eye off the figure.
Now every text export (CSV, TSV, LaTeX, MATLAB, Python, R) and XLSX carries a
role column — anchor for a point you assigned, interpolated for one the
app filled in between, and blank for an ordinary traced point. It appears
only for a series that actually has roles, so a plain trace exports exactly as
it did before, byte for byte.
On screen, derived rows are now visibly derived: muted italic cells, read-only,
with a legend under the table saying what the italics mean. Typing into a derived
cell used to appear to work and then be silently wiped on the next rebuild.
Category names on bar and categorical-line figures
A bar chart's independent variable is a name you read off the tick labels —
the one thing on that axis the pixels cannot tell you. There was nowhere to put
it: bar exports had a Label column nothing in the app could write, so it always
said Bar0, and a categorical line exported a bare ordinal with no name at all.
The right-hand table gains a Category column you can type into, and the names
ride out with the data. On a grouped chart you type the category set once: a
point added to the next series takes the name of the nearest already-named bar,
so it lands on the right category however you click and whatever you skip. Each
name belongs to its own point, so any cell can be retyped without shifting its
neighbours — and where the app can't tell which category you meant, it leaves the
cell blank rather than guess.
One breaking change to note
A bar chart's category column is now called Category in exported files. It was
Label — a word inherited from WebPlotDigitizer that no other part of PlotTracer
used: the on-screen table, the box-plot category field and the new categorical
export all said Category. Now everything does.
The column's position and contents are unchanged, so anything reading the file by
column number is unaffected. If you have a script that looks up the column by
name, change Label to Category.
Two silent wrong-number bugs fixed
Both produced plausible numbers with nothing on screen to say they were wrong.
If you have traced a bar chart or captured error bars with an earlier version,
these are worth knowing about.
- Auto-extract on a bar chart recorded each bar's MIDPOINT — roughly half the
true value whenever the baseline is the axis zero, and wrong in general
otherwise. Colour tracing and blob detection both centre on a filled shape,
which is right for a curve and wrong for a bar, whose value is its top edge.
Auto-extract is now refused for the whole bar family at both doors — the
rail button and the4shortcut — with the reason on hover. Nothing correct is
lost: none of those mechanisms could produce a valid bar value. A proper
interval-native bar model is the next release's headline work. On a bar figure
the guidance now also tells you where to aim — "click the end of each bar,
never its middle" — because on a bar chart the height of your click is the
number, and the old line said "click anywhere on the image". - Capturing an error cap dragged its own data point along with it. The
gesture starts by pressing the datum the cap hangs off, and that one press did
both jobs: it recorded the cap and hauled the datum to wherever the drag
ended — which is, by definition, the cap. It then looked like a mis-aimed click
in the table rather than a bug. Data markers are now inert while the Error-bars
tool is active, exactly as they already were for Measure; the cap is still
recorded, and the point stays where you put it.
Fixes
- The Error-bars tool explains itself. It was the only tool with no guidance
of its own, so on a calibrated chart the tips bar fell through to "Pick a graph
type, then calibrate the axes to begin" — next to a Calibrated ✓ chip. It now
describes the drag, and tells you to place the data points first if the active
series is still empty. - The derived-row legend is actually visible. It sat inside the table's own
scroll container, so it scrolled out of sight on any table longer than about
180 rows — precisely the tables where you need it. - The empty-table hint no longer contradicts the tips bar. One said "click on
the image to add data points" while the other said a plain click does nothing;
both were on screen at the same time. On a bar figure it also no longer points
you at the Auto-extract tool that's greyed out there. - An interpolated point can't be moved by any route. Derived rows were already
read-only to typing; selecting one and using the arrow keys could still shift it,
and the move was then silently discarded on the next rebuild. - The Error-bars card and tips bar name how to adjust a cap, and say plainly
that the lower cap starts out mirrored through your data point rather than
measured — move it to where the figure actually draws it. - Corrected tool numbers. The first tip on a fresh figure pointed at the wrong
rail slot for rotate/crop/deskew, and the manual listed three tools under their
pre-v1.0.2 numbers — including sending you to the image editor for Select. - The Trace Challenge briefing no longer promises auto-tracing on the bar,
box-plot and histogram rounds, where it's deliberately refused.
Downloads
Linux .AppImage / .deb, Windows .exe, macOS .dmg / .zip (Apple Silicon).
Builds are unsigned — your OS will ask you to confirm on first launch.
Full Changelog: v1.2.0...v1.3.0
v1.2.0
The Trace Challenge
PlotTracer ships 14 example figures. Seven of them now come with the real
numbers behind the plot committed alongside the image — so the app can tell you
exactly how close your extraction landed.
Help ▸ Examples ▸ Take The Trace Challenge starts a timed game: five rounds
drawn at random from the seven, each pre-calibrated so you go straight to
tracing. Extract the curve, press Done, and the round is scored against the
ground truth. The score is a single number — time — because accuracy errors
are charged as added seconds. Rushing sloppily just trades placement time for
penalty time; the fun is finding the sweet spot.
- Use whatever tools you like. By-colour, Flood-fill, Guide points, manual
placement — the clock and the error penalty are the challenge, not an
artificial restriction. - The true answer is drawn on your figure after each round, next to a
breakdown of where your seconds went. - Five scoring families, each judged on its own terms: continuous curves
(scored against the interpolated truth, no penalty for using more or fewer
points), scatter (one-to-one nearest matching, with misses and extras counted),
histograms, bar charts, and box plots (compared as five-number summaries). - Local high-score table — name, date, time — kept on your machine.
It doubles as an honest accuracy check: if you want to know how much to trust a
digitizer before you trust it with your data, measure it against figures whose
values are known.
Also new
- Auto-extract ▸ By colour: drag a box directly on the image to limit the
trace to a region. No toggle first — the same gesture as the Select tool's
marquee. - Date axes read as dates in the table. A date-calibrated column showed a raw
serial number on screen while the CSV export already wrote a real date; the
table now uses the same formatter as the export.
Fixes
- The zoom loupe stays usable near the floating cards — it now paints above
them instead of behind, and hides while your cursor is over a card rather than
jumping to the middle of the plot. - Clicks no longer get eaten under the Auto-extract card. In Guide-points and
Flood-fill modes you place points by clicking the curve; a click landing under
the card's footprint silently did nothing. The card is click-through now,
except on its own controls. - "+ Add series" keeps the tracing tool you were using. Tracing a multi-curve
figure no longer dumps you back to place-point on every added series. - Tall fold-out cards scroll instead of spilling off a short window
(Measure, Image, Error bars). - The Select sub-mode strip closes when you click away from it.
- Geometry no longer leaks between series when switching or adding one.
- Smoother clicking during a timed round — the game clock used to re-render
the whole workspace ten times a second, which made canvas clicks feel dropped.
Packaging
The Electron entry files are now globbed rather than listed by hand, so a newly
added one can't be silently left out of the installer.
Downloads
Linux .AppImage / .deb, Windows .exe, macOS .dmg / .zip (Apple Silicon).
Builds are unsigned — your OS will ask you to confirm on first launch.
Full Changelog: v1.1.0...v1.2.0
v1.1.0
The tool rail, redesigned
Every tool that folds out a card — Select, Measure, Curve Fit, Geometry,
Auto-extract, Image edit, Error bars — now works the same way, and that way is
simpler than before.
Fold-outs are inputs only. A tool card holds the controls you act with and
nothing else: one compact row of icons or fields. Measure is Distance / Angle /
Area / Slope / Set-scale. Curve Fit is Degree · Restrict · Fit · Clear. Geometry
is ☐ Closed curve · Compute · Clear.
Results live in one place. Everything a tool produces — recorded
measurements, the fit equation with R² and RMS, the geometry summary — now
appears in the right-hand panel, bound to the series it belongs to, next to that
series' data. Nothing is buried in a popup you have to keep open to read.
Cards appear where you clicked. A fold-out is anchored to its own button and
vertically centred on it, then clamped so a card for a low button can't run off
the bottom of the window. Opening a fly-out closes any other open card, so two
never stack.
Every fold-out button says so. Rail buttons that open a card carry a small
fold-out arrow in the lower-right corner (the digit hotkey badge moved to the
upper-left to make room) — following Ketcher's design language.
Outputs that stay true
Measurements, curve fits and geometry are all derived from your current
points, so editing the series updates them with no re-run. If an edit makes a
result impossible — deleting points until a curve can't be measured — the panel
says so and the tips bar raises a callout, rather than leaving a stale number on
screen.
They also draw on the figure and export as their own labelled blocks,
never mixed into the recorded data. Geometry draws the path it measured, shades
the enclosed area when Closed, and rings the point of maximum curvature — so the
numbers have something visible to refer to.
Geometry is now saved with your project. It used to be a throwaway popup.
New tools and gestures
- Select is a multi-tool: Rectangle (click a point or drag a box), Lasso
(drag a freeform loop), Whole series (click any point, get all of them), and
Point. The rail button shows the active mode; click it again to pick another.
All four select data points only — never your calibration handles. - Measure snaps to your points. A measurement vertex lands exactly on a data
point within reach of the cursor, data markers no longer swallow the click, and
a dashed rubber-band shows direction and length before you commit the next one. - Click the fitted curve to edit it. The green fit line on canvas is a handle
to its own controls. Only in Pan and Select modes, so it never hijacks a click
that was placing a point.
Export
- R (
.R) export — each block renders as a nameddata.frame(), one vector
per column. Non-syntactic headers likeStrain (%)are back-ticked with
check.names = FALSEso they survive verbatim; blanks becomeNA, and
non-finite values emit real R literals (Inf,NaN). - Copy to clipboard — every text format (CSV, TSV, JSON, LaTeX, MATLAB,
Python, R) has a copy button beside it that puts exactly the same rendered text
on your clipboard.
Data entry
Points insert in place. Adding a point splices it into the curve edge it
disturbs least, so re-adding one you removed from the middle of a series lands
back in curve order — moving only that point, never renumbering the rest. A
normal left-to-right trace still just appends.
Downloads
Linux .AppImage / .deb, Windows .exe, macOS .dmg / .zip (Apple Silicon).
Builds are unsigned — your OS will ask you to confirm on first launch.
Full Changelog: v1.0.2...v1.1.0
v1.0.2
v1.0.1
v1.0.0
The first stable release. PlotTracer extracts numbers from figures — the
stress-strain curve, the fatigue plot, the dose-response chart that exists only
as a raster image in a paper, a standard, or a scanned report. Load it, calibrate
the axes, place or auto-trace the points, export the data.
It runs on Linux, Windows and macOS, installs from a single binary, and works
fully offline — no account, no telemetry, no cloud calls. Your figures never
leave your machine, including on an air-gapped one.
What's in 1.0
Chart and axis types — XY, Bar, Polar, Ternary, Map (scale bar), Circular
Chart Recorder, Histogram (captures true bin edges, not just centres), Box
Plot, Line with a categorical X axis, and Error Bars.
Getting points off a figure
- Manual placement across multiple series, drag to reposition, arrow-key nudge,
click a value to edit it. - Auto-extract, under one wand tool: flood fill, trace by colour (continuous
curve or scatter markers), a blob detector, and interpolation-assist (guide
points plus a centripetal spline). A live mask preview shows exactly which
pixels a trace will capture before you commit, and you can restrict a trace to
a drawn box. - Grid-line removal, to clean a busy plot first.
Analysis — polynomial curve fitting (degree 1–9, optional x-range), geometry
and statistics (arc length, enclosed area, curvature), and a Check Calibration
overlay that draws the calibrated axis box back onto the image so you can see
whether it landed.
Measurements — distance, angle, area, slope, and a px→real-unit "Set scale"
reference, kept as their own collection, separate from the series data.
Images and documents — PNG, JPG, GIF, BMP, WEBP, SVG, PDF (multi-page),
and TIFF / multipage TIFF for historic scans. Rotate, flip, crop and
fine-angle deskew, all undoable.
Multi-figure projects — one project holds several figures (every page of a
paper, say), each with its own image, calibration, graph type and series. Flip
between them, or extract another figure from the retained source document.
Export — CSV, TSV, JSON, Excel (.xlsx), LaTeX, MATLAB, Python, plus a
WYSIWYG PNG of the digitised figure. Fitted curves export as their own labelled
blocks rather than being mixed into your data.
A durable record — undo/redo across everything, project save and reload as a
self-contained .zip that can carry the source PDF or TIFF with it, and import of
existing WebPlotDigitizer .tar projects.
Honest about precision
PlotTracer records what the figure shows — pixels first, values derived from your
calibration — and reports numbers no finer than the pixel grid can support, so an
export never carries precision the source never had. If you want the raw
full-precision values anyway, there's an explicit opt-in.
How 1.0 was gated
Three independent blind audits ran over the release candidate — correctness and
data integrity, tenets and UX, release and security — and their findings were
fixed before the tag. Among them: two bugs that silently produced wrong numbers
(ternary axis orientation lost across a save/reload, and a month-overflow on date
axes), degenerate-calibration and non-finite-value guards, and a hardened Electron
shell (OS sandbox, CSP, navigation lock).
Lineage and licence
AGPL-3.0. The calibration engine began as an extraction of
WebPlotDigitizer by Ankit
Rohatgi (AGPL-3.0); some algorithms are clean-room reimplementations of Engauge
Digitizer ideas; the interface follows Ketcher's design language. The application
itself — interface, interaction model, workflow — is a ground-up rebuild in
TypeScript, React and Electron.
Downloads
Linux .AppImage / .deb, Windows .exe, macOS .dmg / .zip (Apple Silicon).
Builds are unsigned: on first launch macOS Gatekeeper needs a right-click →
Open, and Windows SmartScreen a More info → Run anyway. Code-signing is a
planned follow-up.
Full Changelog: v1.0.0-rc.3...v1.0.0