Repository navigation
Releases
v3.2.0
EaglePlot is now also a desktop app for Windows, macOS and Linux, with Python and every
package included: download it from the release page, install it without admin rights, and
use it offline. The web app starts faster, can be installed from Chrome or Edge, and works
offline too. EaglePlot has a new logo in NCCU colors and a new loading screen.
Added
- A desktop app for Windows, macOS and Linux (
packaging/desktop/): the same app
in its own window, with Python and every package included, so it needs no Python
install and no network. Installers are built for every release and need no admin
rights. Settings are kept between sessions. Links open in your web browser. They are
not code-signed yet: the first launch shows a warning (see the
Download page).
Data Upload → Batch Import reads folders on your computer: type the folder's path as
usual (C:\Users\you\data,~/data). - A Download page on the website (
docs/download.md): the web app, desktop app and
Python package side by side, first-launch steps, the code signing policy and the
privacy policy (EaglePlot collects no data).
Changed
- The EaglePlot logo is now in NCCU maroon and gray (it was blue): the same disc, bars
and line, on the Home page, in the sidebar, as the browser-tab icon and inlogo.ico.
eagleplot/assets/logo.svgis the master. - A new loading screen for the web app. The logo's pieces (the rings, the axes, the
bars, the line and the points) fly in from all sides of the screen and lock together,
then a highlight sweeps across while Python loads. Below it, four real steps
(downloading Python, installing the science libraries, starting EaglePlot, opening your
workspace) replace the endlessly sliding bar. The note about the 45 MB download appears
only on a first visit. If loading fails, the screen says why and offers Reload
instead of sliding forever. With reduced motion turned on in the system settings, the
logo appears complete and nothing moves. - The web app starts faster: ready in about 7 s instead of 11 s (measured on a fast
local connection), and the first plot from Home ("Plot this example") appears about 4 s
sooner. scipy is loaded in the background after the app appears, and pandas and the
plotting libraries are imported while you read the Home page. A page that needs scipy
says so for a moment if you open it within the first seconds. - Install the web app like a program. Chrome and Edge offer Install EaglePlot:
it then opens in its own window from a desktop icon, with no admin rights, and after one
online visit it also works offline. Later visits load from the computer instead of the
network. - Importing
eagleplot.plottingno longer imports seaborn, plotly or scipy (they load when
a plot type needs them), and importingeagleplot.utilsno longer imports pandas. This
also makes the installed GUI start a little faster.
v3.1.0
EaglePlot now also runs in your browser, with nothing to install:
https://the-schultz-lab.github.io/eagleplot/app/. This release also makes the GUI much
faster, gives it a simpler first screen, and fixes JCAMP-DX loading, which was broken in
3.0.0 for anyone with the current jcamp package.
Added
- EaglePlot runs in your browser:
the-schultz-lab.github.io/eagleplot/app/.
Nothing to install and nothing uploaded: your data stays on your computer, which makes it
usable on laptops where you can't install software. It takes 15–30 seconds to start.
Features that can't work in a browser are turned off with an explanation instead of
failing: loading a whole folder, downloading from NIST (the page links to NIST instead),
and changing the theme. Settings, presets and workflows are kept in the browser. The
documentation site and README link to it. Every change to the app is tested in a real
browser before it is published (packaging/web/,scripts/web/smoke.js). EAGLEPLOT_CONFIG_DIRsets the folder that holdsconfig.json(saved defaults,
presets and workflows). Unset, it stays where it was.
Changed
- A "Get started" Home page. With no data loaded, Home offers three example datasets,
each a single click away from a plot in Quick Plot, plus buttons to upload a file or
browse all examples, instead of "Datasets 0 · Plots 0 · Analyses 0". - Quick Plot shows the plot on the first screen. Dataset, library and plot type sit in
one row with a Style presets button, and the dataset size and plot description share
one line. On a 1366×768 laptop the plot used to start below the bottom of the screen.
All pages have less empty space at the top. - Clearer menu names: Basic is now Quick Plot, Multiplot Dashboard, Single
Analysis Tools and Batch Batch Analysis. Page addresses are unchanged, so
bookmarks still work. - The sidebar's About box starts closed, and on phones the sidebar starts closed.
- Quick Plot is much faster and easier to use.
- Settings sit on the left and the plot on the right, so you see each change as you
make it. The plot stays in view while the settings scroll. - Live preview: the plot redraws as you change settings (toggle it off if you prefer).
Generate Plot still saves the plot to the plot history. - Changing a setting now updates only the settings and plot area, not the whole page.
In a test with a line plot, the time from a change to seeing it on the plot fell from
about 1.3 s to about 0.6 s. - Downloads are created only when you ask for one. Before, every click re-created the
plot as PNG at 150, 300 and 600 dpi, SVG and PDF, whether or not you were downloading.
The export panel now has one format menu and one Download button. - A marker appears as soon as you click a point on an interactive plot.
- Settings sit on the left and the plot on the right, so you see each change as you
- Export Results is much faster. It used to re-create every saved plot as PNG (150 and
300 dpi), SVG and PDF, and re-save the dataset as CSV and JSON, on every click: 1.2 s per
click with three saved plots, now 0.03 s. Files are now created only when you download them. - PDF report: on current Streamlit it is one click, and the report is built when you
press Download PDF Report. On older Streamlit the download button no longer
disappears after the next click. - Batch Analysis: results stay on screen after you run a tool. Before, they disappeared
at the next click, including when you clicked Download CSV. - Molecular Viz: the HTML and frequency-table exports are one click (Streamlit 1.52+),
instead of "Export", then "Download", with the button disappearing afterwards. - Analysis Tools is faster. Each tool now updates on its own, so changing a setting or
running a tool no longer reloads the whole page. A setting change takes about 0.23 s
instead of about 0.38 s. A result from one tool stays on screen while you use another, and
downloading the peak report no longer clears it. - Multi-Plot Dashboard:
- Each panel has its own settings, shown above its plot. Editing a panel redraws only that
panel, and the dashboard updates live after Generate Dashboard: a title edit shows up
in about 0.4 s, where before you had to press Generate again. - The dashboard stays on screen when you change something or download it.
- Turning shared axes off restores each panel's own axis limits.
- Each panel has its own settings, shown above its plot. Editing a panel redraws only that
- Advanced Plotting: each tab updates on its own, so a change in one tab no longer
clears the plot in another. The interactive HTML file (about 5 MB) is created only when
you download it, and the plot stays on screen afterwards. - Plots are drawn at 150 dpi, as Quick Plot already was (other pages used 200), at
about half the cost to draw. Unchanged Multi-Plot Dashboard panels are no longer
redrawn when the page refreshes: a refresh of a 2×2 dashboard takes about 0.4 s instead
of 1 s. - A missing optional package (for example h5py for HDF5 files) is reported with what to
install, and where installing isn't possible, says so.
Fixed
- JCAMP-DX files (
.jdx,.dx) load again. With jcamp 1.3 installed, every such file
failed with "the jcamp package is required". jcamp is now part of theformatsextra
(pip install "eagleplot[formats]"). - Quick Plot's dataset CSV download was named
name.csv.csv. - Multi-Plot Dashboard: the combined PNG and PDF downloads work. Before, pressing either
button made the dashboard disappear without downloading anything.
v3.0.0
Plottle is now EaglePlot. PyPI does not accept the name plottle (it counts as too
similar to an existing project), so 3.0.0 is the first release on PyPI, under the new name.
Nothing else about the toolkit changes in this release.
⚠️ Changed: name, import path and command
- Install:
pip install eagleplot(with extras:pip install "eagleplot[formats,nist]"). - Import:
import eagleplot/from eagleplot.io import load_data. Code that imports
plottlemust be updated; there is noplottlecompatibility package. - Command:
eagleplot, replacingplottle. From a source checkout:
python -m eagleplot.cli, and the GUI isstreamlit run eagleplot/Home.py. - Setting:
EAGLEPLOT_ALLOW_FOLDER_LOADreplacesPLOTTLE_ALLOW_FOLDER_LOAD. The old
name still works for now and shows a deprecation warning. - Links: the repository is
The-Schultz-Lab/eagleplotand the documentation is at
https://the-schultz-lab.github.io/eagleplot/.
Still works
- Session files saved by Plottle 2.x load unchanged.
- Saved defaults and presets (
config.json) stay where they were.
v2.1.0
⚠️ Changed: import paths and the CLI command
- The package is now imported as
plottle. Code that didfrom modules.io import load_datamust change tofrom plottle.io import load_data. The README for 2.0.x already
documentedplottle.*, but the code still shipped asmodules. The old name also meant
installing the wheel claimed the generic top-level namesmodulesandcli, which could
collide with other projects. - The CLI is the
plottlecommand, installed bypip install. From a source checkout
without installing, usepython -m plottle.cli. The repo-rootcli.pyis gone. - Setup scripts install the package (
pip install -e ".[formats,nist]") rather than
requirements.txt, so theplottlecommand exists after setup.
Security
- Session files no longer execute code. Loading a
.jsonsession ranpickle.loadson
data inside it, so opening a session someone else shared ran their code. Arrays are now
stored as dtype, shape and raw bytes. Sessions saved by 2.0.1 or earlier that contain
pickled entries are refused, and the Export page lists what was skipped. - Formula evaluation is sandboxed properly. Data Tools formulas used
eval()with
empty builtins, which can be escaped. They are now parsed and checked against a whitelist
of operators and functions.SECURITY.mdnow describes what is and isn't guaranteed. .pklfiles are no longer accepted by the GUI uploader or batch import. Use
plottle.io.load_pickle()from Python for files you trust.- Batch import from a folder reads a path on the machine running Plottle, so it is now
available only to local connections. SetPLOTTLE_ALLOW_FOLDER_LOAD=1to allow it
everywhere, or0to turn it off. - Uploaded files go into a private temporary directory that is deleted after loading,
instead of a shared folder where two users uploadingdata.csvoverwrote each other.
Fixed
- Quick Plot failed to load on Python 3.9 (
TypeError: unsupported operand type(s) for |). The Molecular Viz and Batch Analysis pages had the same problem in code paths reached
later. - The Settings page failed on Python 3.9 and 3.10 (
ModuleNotFoundError: tomllib).
tomliis now used as a fallback. - Quick Plot (Plotly mode): clicking a data point crashed the page with
AttributeError: 'dict' object has no attribute 'x'. Marker labels on dates and
categories no longer raise either. - A pip-installed GUI was missing its assets. The logo, NCCU branding, example datasets
and gallery images now ship inside the package. - Theme settings: "Theme saved" was shown even when nothing was written, and saving
discarded every comment inconfig.tomland could write invalid TOML. The theme is now
written to.streamlit/config.tomlin the working directory, where Streamlit reads it,
with comments and other sections preserved. Page styling follows the active theme
instead of a hard-coded dark palette, which left white text on a light background. - Export → Save session: the download button disappeared after any other click, so it
took two tries to download. It now stays available until the session changes. - Settings: "Reset defaults", "Delete preset" and "Delete config.json" each need a
confirmation tick first, and "Delete config.json" offers a backup download. - The macOS
setup.commandandlaunch.commandfiles are executable again, so Finder will
run them from a fresh clone. - The Data Tools page is reachable from the navigation. The sidebar can be collapsed again,
and images have alt text. streamlit>=1.49is now the declared minimum. The code needed it, but the old>=1.25
floor allowed versions that fail.
Added
setup.shandlaunch.shfor Linux. All setup scripts now check the Python version
first.formats(HDF5/NetCDF),nist(NIST WebBook lookups),testandallinstall extras,
so a normal install no longer pulls in the developer tools.- A documentation site built from the guides by
build_docs.py, replacing the unbuilt
Sphinx setup. Every guide is linked from the landing page. CONTRIBUTING.md,CODE_OF_CONDUCT.md, issue forms and a pull request template.
Development
-
CI tests Python 3.9 to 3.12 on Linux, plus macOS and Windows, and runs the whole test
suite. It used to run a hand-written list of files that skipped the CLI and integration
tests. Python 3.9 is pinned toubuntu-24.04and macOS tomacos-15. -
mypy runs with the project installed, so it checks real types instead of treating
numpy, pandas and matplotlib asAny. ruff and mypy are pinned to exact versions. -
ruff checkandruff format --checkcover the whole repository, and ruff flags
X | Noneannotations that would fail on Python 3.9 (FA102). -
New tests:
- every GUI page renders on a fresh session,
- the "Seaborn/Plotly not installed" errors (9 of these tests were always skipped),
- the Settings, Export and upload behaviour above.
The suite has 1,100+ tests.
-
The version number has a single source,
plottle/__init__.py.
v2.0.1 macOS launchers & pandas 2.x session fix
[2.0.1] - 2026-04-08
Fixed
- Session save/load: wrap DataFrame JSON string in
io.StringIObefore passing to
pd.read_json(), fixing aFileNotFoundErroron pandas 2.x where a bare string
argument is now treated as a file path rather than inline content
(modules/utils/session_state.py)
Changed
- Added macOS one-click setup and launch scripts (
setup.command,launch.command) - Updated
launch.batto check for the virtual environment and print a helpful error
if it is missing - README: added platform-specific setup/launch instructions, PyPI badge, and updated
programmatic import examples to useplottle.*namespace pyproject.toml: bumped minimumsetuptoolsto 78.0, normalizedlicensefield
to PEP 639 format, corrected author email, addedbuild/twinedev dependencies
and changelog URLmodules/Home.py: use.resolve()for path construction (improves symlink and
working-directory robustness); moved NCCU wings logo to sidebar
v2.0.0
[2.0.0] - 2026-03-17
Added
Statistical Testing Suite (modules/math.py)
- 12 new hypothesis-testing functions: one-sample/two-sample/paired t-tests, Mann-Whitney U,
Wilcoxon signed-rank, Kruskal-Wallis, one-way ANOVA, Tukey HSD, Bonferroni correction,
Pearson/Spearman correlation, chi-square independence - Two-way ANOVA (
anova_twoway) via optionalstatsmodelsdependency - Effect size display (Cohen's d with Small/Medium/Large interpretation) in the GUI
Signal Processing (modules/signal.py — new module)
- 16 functions: moving-average/Savitzky-Golay/Gaussian smoothing; Butterworth low/high/band/band-stop
filters (zero-phasesosfiltfilt); FFT + inverse FFT + power spectrum; 1st/2nd derivative;
polynomial/rolling-ball/asymmetric-least-squares baseline correction; cubic/linear/nearest interpolation - "Signal Processing" tab (6 sub-tabs) added to Analysis Tools page
Peak Analysis (modules/peaks.py — new module)
- 5 functions:
find_peaks,integrate_peaks,compute_fwhm,fit_peak,fit_multipeak - Gaussian/Lorentzian/Voigt/pseudo-Voigt peak models; multi-peak simultaneous fitting
- "Peak Analysis" tab (2 sub-tabs: Find & Measure, Fit Peaks) in Analysis Tools page
Extended Plot Types (modules/plotting.py)
- 13 new plot types: bar chart (simple/grouped/stacked), waterfall plot, dual y-axis, z-colored
scatter, bubble chart, polar plot, pair plot, 2D histogram/hexbin, interactive 3D scatter,
scatter with regression, residual plot, interactive ternary, broken axis, inset plot - Error bar support (
yerr/xerr) added toscatter_plotandline_plot COLORBLIND_PALETTE(Okabe-Ito 8 colors) added;get_color_palette('colorblind', n)works- Total plot types: 26 (was 13 at v1.0.0)
Data Manipulation Layer (modules/data_tools.py — new module)
- 12 non-destructive functions: formula columns (safe eval), normalization, transpose,
pivot/melt, row filter, sort, merge/join, fill/drop NaN, resample, rolling transforms - Page 9 — Data Tools: dedicated Streamlit page with 10 operation tabs
Figure Layout & Annotation (modules/annotations.py — new module)
- 7 overlay types: hline, vline, hspan, vspan, text, rectangle, ellipse
- Annotation panel added to Quick Plot (add/delete/clear overlays; persists across re-renders)
- Multi-Plot Dashboard expanded: 10 grid layouts up to 4×4; axis sharing; combined PNG/PDF export
Instrument File Import (modules/io.py)
- 5 new loaders: JCAMP-DX (
.jdx/.dx), HDF5 (.h5/.hdf5), NetCDF (.nc/.cdf),
SPC (.spc), generic ASC/text (.asc) - mzML/mzXML loader (
load_mzml) via optionalpymzmldependency
Spectroscopy & Molecular Analysis (modules/spectroscopy.py, modules/molecular/ — new)
- 18 spectroscopy functions covering IR/Raman, UV-Vis/Beer-Lambert/FRET, NMR, and mass spec
modules/molecular/package: CPK atom data, Gaussian/ORCA/Molden vibrational parsers,
Plotly 3D molecule + displacement-arrow figure builder (no RDKit dependency)- Page 10 — Spectroscopy; Page 11 — Molecular Viz (vibrational mode animation)
- NIST WebBook integration (
modules/nist.py): fetch IR JCAMP spectra by CAS number
Batch GUI & Automation (modules/batch.py — new module)
- 5 functions:
scan_directory,batch_load_files,batch_statistics,batch_curve_fit,
batch_peak_analysis - Page 12 — Batch Analysis: Statistics/Curve Fit/Peak Analysis across multiple datasets + CSV export
- Workflow presets: save/load/delete named analysis pipeline configs persisted to
config.json - Batch folder import expander added to Data Upload page
PDF Report Generation (modules/report.py — new module)
generate_pdf_report()usingmatplotlib.backends.backend_pdf.PdfPages(no new dependencies)- Report section added to Export Results page (title, author, DPI slider, one-click download)
Plugin System (modules/plugin_loader.py — new module)
- Auto-discovers
plugin_*.pyfiles from theplugins/directory viaimportlib.util discover_plugins,get_plugin_plot_types,get_plugin_analysis_tools,list_pluginsplugins/plugin_example.pystarter template; plugin status shown in Settings page
Performance Utilities (modules/io.py)
downsample_for_preview(df, max_rows=10_000, method='systematic')— fast preview for large dataload_large_csv(filepath, max_rows=500_000, chunksize=50_000)— chunked CSV loading- Large-file warning (> 50 MB or > 10k rows) with auto-downsampled preview in Data Upload
New GUI Pages (7 total added)
- Page 7 — Export Results (plots, datasets, analysis JSON, session save/load, PDF report)
- Page 8 — Gallery (pre-generated example figures for all 26 plot types; "Load this config" button)
- Page 9 — Data Tools
- Page 10 — Spectroscopy
- Page 11 — Molecular Viz
- Page 12 — Batch Analysis
- Page 13 — Help (Getting Started, Plot Types, Analysis Tools, File Formats, Tips & Tricks)
- Page 14 — Settings (moved to bottom of sidebar)
- Home page redesigned: Dashboard tab (metric cards, smart CTA) + Help tab (Quick Start, formats, tips)
UX & Visual Polish
- Nunito Google Font applied globally via CSS injection
- Style presets: save/load/delete named Quick Plot configurations persisted to
config.json - "Convert to Plotly (zoom/pan)" toggle on every matplotlib figure in Quick Plot
- PNG bytes stored in session state (fixes
MediaFileHandler: Missing fileStreamlit bug) - Equal-height CSS for Gallery cards; compact Data Upload (3-tab layout)
Testing
- Test suite expanded from 258 to ~900+ tests across 17 test files
- 12 new test modules:
test_signal,test_peaks,test_data_tools,test_annotations,
test_spectroscopy,test_molecular_parsers,test_batch,test_report,
test_plugin_loader,test_nist, plus expansions totest_plotting,test_math,test_io
Code Quality
- Switched formatter from
blacktoruff-format - Line length bumped to 100; E501 enforced
.pre-commit-config.yaml: ruff, ruff-format, trailing-whitespace, end-of-file-fixer,
check-merge-conflict
Changed
- GUI entry point renamed from
modules/gui.pytomodules/Home.py - Settings page renumbered from
6_Settings.pyto14_Settings.py(sidebar ordering) use_container_width=fully replaced withwidth='stretch'/width='content'(all pages)blackreplaced byruff-formatin CI lint job andpyproject.tomldev dependenciesruff checknow covers all new modules in CI
Fixed
- NIST WebBook IR fetch: corrected URL format to
?JCAMP=C{cas}&Index={idx}&Type=IR-SPEC
(was returning HTTP 404 with old?ID=cas&JCAMP=1format) mpl_to_plotlyconversion now re-applies style config after conversion so font sizes
and colors persist when toggling "Convert to Plotly"generate_gallery.py: fixed 7 bugs (column name mismatches,dpileaking into plot kwargs,
duplicate kwargs, unsupportedannotatekwarg for heatmap, broken figsize handling)