Eleven widgets, an end-to-end spectral-ID workflow
After installing, a new Spectra category appears in Orange's toolbox. Output tables follow the Orange-Spectroscopy convention (one column per wavenumber, one row per spectrum), so they plug straight into PCA, PLS, hierarchical clustering and other native Orange widgets.
Import Spectrum URL
Paste an IRUG id (e.g. 4119), an IRUG/SOPRANO page URL, or a direct JCAMP-DX / CSV URL — download, plot and output a table in one click. Fetch several to accumulate a set.
Merge Spectra
Overlay several spectra sources on one plot and output a single combined table (one spectrum per row, shared grid) for downstream analysis.
Load Spectra Files
Bulk-load a whole folder or .zip (no extraction): JCAMP-DX, CSV, matrix CSV and NetCDF .cdf all land in one combined table.
Spectrometer
Turn a camera + diffraction-grating spectrum photo into a calibrated spectrum: rotate the image, read intensity along a horizontal strip, snap an interactive peak cursor to auto-detected peaks and write known lines into the calibration table with one click (a Theremino-style spectrometer).
Spectra Similarity
Pairwise similarity: Pearson correlation, cosine, spectral angle (SAM) and Euclidean distance. Overlapping bands are auto-aligned before comparing.
Spectral Library
Collect reference spectra into a library, save as a .speclib file (fully interoperable with the SpectraView desktop app), then search unknowns and output a ranked hit list and best match.
Mixture Analysis
Non-negative least squares (NNLS) decomposition of mixture ≈ Σ cᵢ·refᵢ: reports each component's coefficient, percentage and fit R², and overlays the fit curve and residual.
Aquagram (aquaphotomics)
Aquaphotomics: sample normalized absorbance at water's 12 characteristic bands (WAMACs) and draw a 12-axis radar plot to compare water's hydrogen-bond structure across samples/perturbations.
Peak Finder
Detect peaks and label them on the plot; measures position, height, FWHM, prominence and area, with adjustable thresholds and smoothing.
XRF Element ID
Finds peaks in an XRF spectrum (keV) and matches them to element emission lines (Kα/Kβ/Lα/Lβ, 53 elements Na–U), labeling "Fe Kα1" etc. right on the plot.
PLS-DA
Partial least squares discriminant analysis: class-colored score plot, loadings and VIP variable importance — see at a glance which bands separate your classes.
Install
▸ Desktop App (the standalone program downloaded from orangedatamining.com, opened by its icon) → use Method A.
▸ pip Orange (you ran
pip install orange3 and launch with python -m Orange.canvas) → use Method B.The two have separate Python environments; installing into the wrong one means the widgets won't appear.
Method A ── Desktop App (recommended)
Use the App's built-in Add-ons dialog to install from PyPI by name:
Open Add-ons
Orange menu Options ▸ Add-ons…
Add more… and type the name
Click Add more… (top-right), type orange-spectra (not a git URL — this box only takes PyPI names), tick it and click OK. The package is on
PyPI (currently 0.7.0).
Restart Orange
The Spectra category with 11 widgets appears in the toolbox.
python.exe (e.g. …\Orange\python.exe) and run
python.exe -m pip install orange-spectra.Method B ── pip Orange
# 1) Orange + a Qt binding (without PyQt5 you get "PyQt5 ... not available" and it won't start) pip install orange3 PyQt5 PyQtWebEngine # 2) orange-spectra widgets (from PyPI; use the git URL only for the latest dev version) pip install orange-spectra # 3) Launch (use this command; do NOT click the desktop App icon — that's a different env) python -m Orange.canvas
▸
ImportError: PyQt5 … not available → missing Qt; run
pip install PyQt5 PyQtWebEngine.▸ Pasting a git URL into Add-ons ▸ Add more… gives "packages were not found" → that box only takes PyPI names; use Method B's
pip install for a git URL.▸ Reinstall only to update:
pip install --upgrade orange-spectra,
then fully close and reopen Orange.▸ Every widget has an "ℹ How to use" box and a "📖 Open tutorial" button at the top — click it whenever you're unsure.
Widget-by-widget guide
Import Spectrum URL — import a spectrum from a URL
- Paste a source into the box and click Fetch & add:
- IRUG id:
4119(=http://www.irug.org/jcamp-details?id=4119, the PB15 phthalocyanine-blue Raman spectrum) - A SOPRANO page URL (KIK-IRPA pigment Raman database, Belgium)
- A direct JCAMP-DX (AFFN) or two-column CSV URL
- IRUG id:
- The spectrum is plotted live on the right (IR/Raman convention: wavenumber high → low).
- Fetch repeatedly to accumulate spectra; remove one or clear all. Multiple spectra are resampled onto a shared band.
<script> (as
"wavenumber":intensity pairs); SOPRANO stores it in a Dygraph data array. The widget parses the page source to recover the numbers.Spectrometer — image spectroscopy (camera + grating)
- Click Choose spectrum photo… and pick a camera + diffraction-grating photo. If the colour band is vertical (common with phone shots), use Rotate 90°/270° to make the dispersion axis horizontal — rotation is lossless (an axis swap, no interpolation).
- Channel (luminance / R / G / B / sum) and Strip centre / height select the horizontal band to read (the yellow box on the image).
- Peak cursor: the widget auto-detects peaks (tune Min prominence / distance / Smoothing); the ◀ / ▶ buttons jump between peaks, and the cursor snaps to the sub-pixel peak position within ±4 px. The readout shows pixel, intensity and λ live.
- Calibration: put the cursor on a line you recognise → pick its wavelength from the λ = dropdown (built-in fluorescent-lamp lines: 405.4 / 435.8 / 546.1 Hg, 611.6 Eu; or type any value) → click write into the calibration table. Repeat for 2-3 lines, then fit linear / quadratic; you can also type
pixel=nmpairs by hand. Leave empty to keep the x-axis in pixels. - Check R² in the Status bar: a linear fit should give R² close to 1 (≥ 0.999); a mis-assigned line drags it down visibly. When points = degree + 1, R² = 1 by construction (the exact-fit warning) — add another line before trusting it.
- Tick Zoom plot to the calibrated range to show only the calibrated interval (polynomials diverge outside the calibration points; display only, the output is unaffected). Feed the output to Similarity / Library / Peak Finder / Data Table.
Load Spectra Files — bulk-load spectra files
- Add files… / Add folder… / Add .zip… — folders are scanned for every spectra file (optionally recursive); .zip archives are read without extraction.
- Formats: JCAMP-DX (AFFN), two-column CSV/TSV, matrix CSV (both SpectraView "combined export" layouts), and NetCDF .cdf/.nc (classic format — chemometrics datasets like applewine, ANDI chromatography exports).
- Everything previews on one plot; feed the output to Similarity / Library / PLS-DA / Data Table.
Merge Spectra — overlay & combine spectra
- Connect several sources to Spectra — multiple Import Spectrum URL widgets, Orange's File, or any wavenumber-column Table.
- All spectra overlay live; Normalize each (none / max=1 / area=1 / SNV) makes differently-scaled spectra comparable; Stack offset only spreads the display.
- The output is one combined Table (each row a spectrum on the shared overlap grid), ready for Similarity / Library / Mixture / PLS-DA.
Spectra Similarity — pairwise similarity
- Connect Data and References: outputs four metrics for every Data × References pair.
- Connect only Data: switches to all-pairs within Data (good for "how alike is this batch?").
- Sort by correlation / cosine (higher = more similar) or SAM / Euclidean (lower = more similar).
- The Similarity Matrix output (since 0.7.1) is a Data × References wide matrix of the "Sort scores by" metric (Data-only mode gives an n×n symmetric matrix, diagonal = 1) — feed it to Orange's native Heat Map widget for a similarity heatmap, or Data Table for the numbers.
| Metric | Meaning | Property |
|---|---|---|
| correlation | Pearson correlation | Invariant to offset and scale; the most common for ID |
| cosine | Cosine of the angle | Invariant to scale |
| SAM | Spectral angle (radians) | Common in remote sensing / hyperspectral; lower = more similar |
| euclid | Euclidean distance (unit-normalized) | Intuitive "how different is the shape" |
Spectral Library — build and search a library
- Connect references to the Spectra input and click Add input spectra to library.
- Save… as
.speclib; Load… an existing one — the file format is identical to the SpectraView desktop app. - Add built-in loads a built-in library in one click (pick it in the dropdown, press the button):
▸ Sugars & food additives NIR library (9 spectra; bundled with the package since 0.7.2, works offline) — the library used by demos ② and ③.
▸ UCL Raman Library of Pigments (55 pigments, Bell, Clark & Gibbs 1997) — the first press downloads from UCL's own site (falling back to the Internet Archive if unreachable); afterwards the local cache works offline. For licensing reasons the data is not bundled with the package. - Connect unknowns to Query: Hits outputs each query's ranking against every library entry with all four metrics — connect a Data Table to view.
- The Library output turns the whole library into a table — feed it straight into Mixture Analysis as references, or view it as spectra.
- Example: feed a cinnabar sample to Query — the top hit is Vermilion (HgS). Tip: the library holds raw, baseline-uncorrected intensities, so baseline-correct your query (e.g. ALS) first for clearer separation. Please cite Bell, Clark & Gibbs, Spectrochim. Acta A 53 (1997) 2159 when publishing.
Mixture Analysis — unmix a mixed spectrum
- Connect the mixed spectrum to Mixture and a set of pure references to References.
- Solves
mixture ≈ Σ cᵢ·refᵢ (+ offset)by non-negative least squares (NNLS); coefficients are forced ≥ 0, which is physically meaningful. - The widget shows the composition table (coefficient, percentage) and R²; the plot overlays mixture, fit and residual.
- Feed Composition into a Data Table or Bar Plot; Fit contains three rows: mixture / NNLS fit / residual.
Aquagram — aquaphotomics radar plot
Aquaphotomics (Tsenkova) uses water's 12 characteristic NIR bands (WAMACs, water matrix coordinates, ~1336–1522 nm) as a "water fingerprint," plotting each sample's normalized absorbance at these 12 coordinates on a radar chart to compare changes in water's hydrogen-bond structure across states (temperature, concentration, cultivar… perturbations). Method after the NIRPY Research aquagram tutorial.
- Connect NIR spectra (load via Import Spectrum URL / File, or through Orange-Spectroscopy preprocessing).
- Pick a normalization:
- raw: absorbance sampled at the 12 bands, as-is.
- snv: SNV (Standard Normal Variate) each spectrum first, then sample.
- aquagram (default, classic): after SNV, standardize across the sample set at each band, (value − mean)/std — 0 is the group-average water spectrum, outward = above-average absorbance at that band, inward = below.
- The 12-axis radar plots live, one line per spectrum; the WAMACs bands are editable (defaults to the standard 12).
- The Aquagram Coordinates output is an n×12 table — feed it into PCA, clustering or a Data Table for quantitative comparison.
Peak Finder — detect & label peaks
- Connect spectra; every peak is marked with a triangle + position label immediately.
- Raise Min height / Min prominence (both % of the signal's full range) to reject noise; Min distance (x units) merges near-duplicate peaks.
- Smoothing window (Savitzky-Golay points, 0 = off) affects detection only — heights are still read from the raw signal.
- Feed the Peaks output to a Data Table: one row per peak (spectrum, position, height, FWHM, prominence, Gaussian-estimate area).
XRF Element ID — label elements on an XRF spectrum
- Connect an energy-calibrated (keV) XRF spectrum; the widget finds peaks automatically.
- Each peak is matched within Energy tolerance (default 0.10 keV) against a line database — Kα1/Kβ1/Lα1/Lβ1 (X-ray Data Booklet values, 53 elements Na–U).
- Peaks are labeled directly ("Fe Kα1", "Pb Lα1"); unmatched peaks get "?". The Lines menu restricts matching to K or L lines.
- The Elements output lists every candidate per peak (peak energy, line energy, Δ, height, element, line) — inspect in a Data Table.
PLS-DA — partial least squares discriminant analysis
- The data needs a class variable: after File/Datasets, use Select Columns to move the class column to Target.
- Classes are one-hot encoded and fit with PLS2 (NIPALS); the score plot is colored by class, the title shows training accuracy, and the status pane shows the confusion matrix.
- Components sets the number of latent variables (too many overfits — a permanent 100% accuracy is a warning sign).
- The VIP output (sorted): VIP > 1 is commonly read as an important variable — i.e. which wavenumbers separate the classes.
- Predictions = the input table + a predicted-class meta column, ready for Orange's evaluation widgets.
Run it on the bundled example data
Every figure and number below was produced by actually running these widgets'
algorithms on real example data (NIR spectra of 9 sugars/additives — load it with Spectral
Library's Add built-in since 0.7.2, also in the repo as examples/sugars_nir.speclib)
and real corn NIR — not mock-ups. Do the same on your machine and you get the same results.
① Import Spectrum URL → load a set of spectra at once
The 9 sugar NIR reference spectra loaded and overlaid on one chart (a table with one row per spectrum).
② Spectra Similarity → 9×9 correlation heatmap
Pairwise correlation of the 9 sugar spectra. Chemically sensible: sucrose vs fructose ≈ 0.99 (sucrose = glucose + fructose), while sugars vs caffeine ≈ 0.71 separate clearly.
Heat Map settings: set Clustering Rows/Columns to (None) (this figure is alphabetical; Clustering is also instructive — the sugars group together and caffeine stands alone), set Row Annotations to spectrum (row labels = spectrum names), and pick a red-yellow-green-ish palette (Orange has no exact match for the matplotlib colours). Heat Map does not print numbers inside cells — connect the Similarity Matrix to a Data Table to read each value.
③ Spectral Library → ranked search of an unknown sugar
Searching unknown_glucose.csv against the 9-sugar library correctly ranks glucose #1 (correlation = 1.0000).
| Rank | Match | correlation |
|---|---|---|
| 1 | glucose ✅ | 1.0000 |
| 2 | sucrose | 0.9562 |
| 3 | fructose | 0.9533 |
| … | … | … |
| 9 | caffeine | 0.7078 |
④ Mixture Analysis → NNLS unmixing of a real CGL NIR mixture
Using Eigenvector's CGL three-component NIR mixture design (casein / glucose / lactate, 1104–2496 nm): estimate each component's pure spectrum from the calibration set by classical least squares (CLS), then unmix a real test mixture with NNLS. Spectral fit R² = 1.0000; recovered proportions are close to the reference wt%.
| Component | NNLS recovered | Reference wt% |
|---|---|---|
| casein | 31.3% | 31.3% |
| glucose | 33.9% | 37.6% |
| lactate | 34.7% | 31.1% |
examples/cgl_mixture_nnls.py
generates this figure and writes cgl_components.speclib (3 pure-component
references) and cgl_mixture.csv (one mixture) — load them with Load Spectra
Files into Mixture Analysis (References + Mixture) to run the same NNLS unmixing inside Orange.
(The pure spectra are CLS estimates from real data, so recovered proportions differ from the reference by a few %; the spectral fit itself is R²≈1.)
⑤ Aquagram → real corn-NIR water aquagram
Real corn near-infrared spectra (split into low vs high moisture): normalized absorbance at the 12 WAMACs drawn as an aquagram (radar plot).
Three classroom workflows
① View: paste URL → spectrum → table
The shortest path: one widget lets you "paste a URL and see the spectrum"; connect Orange-Spectroscopy's Spectra widget or a Line Plot to view it another way.
② Identify: build a library → search an unknown
Connect the unknown from a second source (a File widget reading a CSV, or another Import
URL) to the Library's Query. The .speclib file is fully interoperable with the
SpectraView desktop app and the bundled example library.
③ Quantify: mixture component analysis
References can come from the library's Library output — "build a library" and "unmix a mixture" chain naturally into one pipeline.
Integration with SpectraView and Orange-Spectroscopy
| Interop point | Detail |
|---|---|
| .speclib library | A library saved in Orange opens directly in the SpectraView desktop app via Library ▸ Load library…, and vice versa (e.g. examples/sugars_nir.speclib). |
| Table format | Column names = wavenumbers, one row per spectrum — the same as Orange-Spectroscopy and SpectraView's "combined-export X-matrix." Exported CSVs load both ways. |
| Algorithms | The four similarity metrics and NNLS are defined identically to SpectraView, so desktop and Orange results validate each other. |
| Downstream | The Spectra output feeds straight into Orange's PCA, PLS (chemometrics), distance matrix, hierarchical clustering and more. |
FAQ
Desktop Add-ons install fails: UnicodeDecodeError: 'cp950' codec can't decode…?
A known Orange desktop issue on Traditional-Chinese Windows (system code page cp950/Big5): the Add-ons dialog decodes pip's output with cp950 and crashes on UTF-8 characters (e.g. the "━" progress bar). It is unrelated to the package being installed. Two fixes:
- Install from the command line into the App's environment (recommended) — open Command Prompt and run:
"C:\Users\YOU\AppData\Local\Programs\Orange\python.exe" -m pip install orange-spectra
then fully close and reopen Orange. Add--upgradeto update later. - Make Python use UTF-8 — add a user environment variable
PYTHONUTF8=1(Edit system environment variables ▸ Environment Variables ▸ New), restart Orange, then use the Add-ons dialog normally.
Do I have to pip-install every time I use it?
No. Installation is one-off — once installed, the 11 widgets in the Spectra category are
there every time you open Orange. Reinstall only to update to a new version
(pip install --upgrade orange-spectra), and after reinstalling
fully close and reopen Orange for it to take effect.
Spectrometer: why doesn't the cursor line land on a calibration dashed line?
The red dashed lines are drawn at the reference wavelengths you typed; the solid cursor line is drawn at the fitted wavelength of its pixel — the gap between them is the fit residual. A gap of several nm usually means one pixel=nm pair is assigned to the wrong line: switch Fit to linear, check R² (should be ≥ 0.999), re-aim the peak cursor at the actual peak and write the pair again. Also note the ◀ / ▶ buttons only jump between detected peaks — lower Min prominence to pick up weak lines first.
I don't know how to use a widget — how do I learn?
Every widget has an "ℹ How to use" box (short guidance) and a "📖 Open tutorial" button at the top-left; the button opens the matching section of this page. You can also look at the Live demo above to see what each widget actually produces.
IRUG fetch fails (connection error) — what now?
First check the page opens in a browser; campus networks sometimes block external sites. If it still fails, use the SpectraView desktop app's File ▸ Import from URL / IRUG… in a browser, save as CSV, then load that with Orange's File widget.
A JCAMP-DX file comes out garbled / fails to parse?
URL import supports AFFN (plain-number) JCAMP; for compressed forms (SQZ/DIF/DUP) open it in SpectraView (which has a full decoder) and export as CSV.
Can I compare two spectra with different bands?
Yes. Similarity and NNLS both take the overlapping band and interpolate onto a common grid first; only when there is no overlap at all do they report an error.
Can I baseline-correct / smooth before comparing?
Recommended: connect Orange-Spectroscopy's Preprocess Spectra widget (baseline, SNV, Savitzky-Golay, etc.) before comparison; or do airPLS in SpectraView first and export.
Getting started
New to spectral analysis? Start with the tutorial
This page is a reference manual for the 11 widgets. If terms like baseline correction, peak finding or spectral library matching are new to you, work through the beginner tutorial first, then come back here for widget details.
📘 Raman Pigment Analysis — A Beginner's Tutorial Chinese-language tutorial 中文教材
Written for first-year undergraduates with no prior coding experience. Using real pigment spectra, it walks through the whole chain — baseline correction → peak finding → spectral library matching → mixture unmixing — three times over, once in Python, once in R, and once entirely code-free using the widgets on this page.
- Part 4 covers exactly how to chain the widgets on this page: Load Spectra Files → Peak Finder → Spectra Similarity → Spectral Library → Mixture Analysis.
- Part 5 works through three real cases, plus the three kinds of mistakes an automated matcher will always make — the part beginners most need, and least often get told.