Frequency response function (FRF) and coherence from CSV
FRF (H1, H2) and coherence of two CSV columns, in your browser. Nothing is uploaded.
Open a CSV with an input and an output
Drop it here or choose a file. The FRF settings open as soon as it is read.
The sample: made-up wind force on a mast and the mast’s sway, 100 readings a second.
Tip: drop several files to compare them.
Your file never leaves your device. It is read and charted by your browser. Nothing is uploaded.
Opens on the FRF settings, with these defaults
Every one of them can be changed in the dialog before you open the plot:
- Channels
- The plotted channel as the input (excitation), the file’s next number column as the output (response); the sample rate from the time column.
- Spectra
- Hann window; segments of 2,048 samples (fewer for a short file); 50 % overlap; each segment’s mean removed; averaged.
- Result
- H1 (choose H2, or H1 and H2, under Estimator): magnitude on a log scale, phase in degrees, and the coherence, in three panels.
At a glance
- Estimators
- H1 = Gxy / Gxx (the default), H2 = Gyy / Gyx, or both on the same plot.
- Outputs
- Magnitude and phase (degrees) of each estimator, and the magnitude-squared coherence of the two signals, from 0 to 1.
- Spectra
- Welch’s method: segments of 2,048 samples by default (fewer for a short file), 50 % overlap, each segment’s mean removed, averaged.
- Window
- Hann by default; Hamming, Blackman, flat top and rectangular too.
- Units
- The output’s unit per the input’s: a sway in mm against a force in N gives mm/N; an acceleration in g against a force in N, g/N.
- Sample rate
- Read from the time column, the same for both signals. Without one, you type it in.
- Accuracy
- Checked against SciPy by our own tests: 24 checks of the FRF and coherence, all passing.
- Processing
- Calculated in your browser. Your file is never uploaded.
- Price
- Free. No account or sign-up.
How to calculate an FRF and coherence from a CSV file
- Open your file. Choose a CSV, TSV, TXT, Excel, JSON, MATLAB, Parquet, HDF5 or LabVIEW TDMS file with a time column, the input (the excitation, such as a force) and the output (the response, such as an acceleration or a displacement). No file to hand? Click “Try a sample input and output”.
- Pick the input and the output. The FRF settings open as soon as the file is read: the plotted channel is the input and the next column the output. Swap them or pick others, choose H1, H2 or both, the window and the segment length.
- Open the plot. Click “Open plot”. Three panels share the frequency axis: the magnitude (output unit per input unit), the phase in degrees and the coherence from 0 to 1. Download them as a CSV or an image.


A worked example you can check
“Try a sample input and output” opens a made-up file of 20,000 readings taken 100 times a second (200 seconds): Wind_Force in N and Mast_Sway in mm, gusts of wind force (400 N on average, varying by 100 N) and the sway of a mast that responds to them as a 2nd-order system: resonance at 8 Hz, 5 % damping, 0.05 mm per N at rest, with measurement noise (0.5 mm) on the sway. Click Open plot without changing anything, and this is what you should get:
| Input | Wind_Force [N], sample rate 100 Hz from time_s |
|---|---|
| Output | Mast_Sway [mm] |
| Window | Hann |
| Segment length | 2,048 samples, frequency step 0.0488 Hz |
| Overlap | 50 % (1,024 samples): 18 segments averaged |
| Estimator | H1 (H1 and H2 for |H2|) |
| Peak of |H1| | 8.06 Hz: 0.499 mm/N (the mast: 0.500 at 8 Hz) |
|---|---|
| Phase H1 | -84.5° at 7.96 Hz, -90.4° at 8.01 Hz: through −90° at the resonance |
| Coherence at the peak | 0.995 |
| At 20.02 Hz | Coherence 0.692; |H1| 0.00705 mm/N (the mast: 0.00711); |H2| 0.01018 mm/N |
The magnitude peaks at the mast’s resonance, about ten times its response at rest (0.05 mm/N), and the phase falls through −90° there, as a 2nd-order system’s does. Near the peak the sway is large and the coherence is close to 1. At 20 Hz the mast barely moves, the 0.5 mm of measurement noise on the sway is a large part of what is measured, and the coherence drops to 0.692: H1 still reads the mast’s own value, while H2 reads too high by a factor of 1 ÷ 0.692.
The same in Python
With the sample file downloaded, these lines give SciPy’s answer for the same settings (skiprows=[1] skips the units row):
import numpy as np, pandas as pd
from scipy import signal
d = pd.read_csv("megarows-sample-frf.csv", skiprows=[1])
x, y = d["Wind_Force"].to_numpy(), d["Mast_Sway"].to_numpy()
kw = dict(fs=100, window="hann", nperseg=2048, noverlap=1024)
f, pxy = signal.csd(x, y, **kw)
_, pxx = signal.welch(x, **kw)
_, pyy = signal.welch(y, **kw)
_, coh = signal.coherence(x, y, **kw)
h1, h2 = pxy / pxx, pyy / np.conj(pxy)
k = np.argmax(np.abs(h1[1:])) + 1
print(f"peak {f[k]:.2f} Hz |H1| {abs(h1[k]):.3f} mm/N coherence {coh[k]:.3f}")
i = np.argmin(np.abs(f - 20))
print(f"{f[i]:.2f} Hz coherence {coh[i]:.3f} |H1| {abs(h1[i]):.5f} |H2| {abs(h2[i]):.5f}")They print:
peak 8.06 Hz |H1| 0.499 mm/N coherence 0.995
20.02 Hz coherence 0.692 |H1| 0.00705 |H2| 0.01018We ran them on 8 October 2026 with NumPy 2.1.3, SciPy 1.14.1, pandas 2.2.3 and Python 3.12. A test runs the same calculation through MegaRows on every change to the site and checks that its numbers are the ones on this page, and that they match SciPy’s to about 12 significant digits. Download the sample file (CSV, 427 KB).
H1 or H2
Both estimate the same frequency response from averaged spectra: Gxx and Gyy, the power spectral densities of the input and the output, and Gxy, their cross spectral density.
- H1 = Gxy / Gxx is not biased by noise on the output, the usual case: a response measured with sensor noise, as in the sample. It is the default.
- H2 = Gyy / Gyx is not biased by noise on the input. It is often the better estimate right at a sharp resonance, where a shaker’s force drops and the input is the noisier signal.
- H1 and H2 on the same plot show where the two agree: H1 is never above H2, and H1 ÷ H2 is the coherence, so they agree where the coherence is close to 1 and part where it drops.
What the coherence tells you
The magnitude-squared coherence of the two signals, |Gxy|² / (Gxx Gyy), runs from 0 to 1 at each frequency: the share of the output’s power that follows the input in a straight line. High coherence supports a consistent linear relation between input and output at these settings. Check calibration, alignment, noise and leakage before relying on the FRF. Low coherence means something else is in the output:
- noise on the output or the input, as at 20 Hz in the sample;
- another input you did not measure, such as a second load or a vibration from nearby;
- a nonlinear system, such as a joint that rattles or a spring that stiffens;
- segments too short for a sharp resonance, or a delay between the signals of more than a fraction of a segment: try a longer segment.
Units and the phase
The magnitude is in the output’s unit per the input’s: mm/N for the sample, g/N for an accelerometer against a force, (m/s²)/N in SI. Give each column its unit in a units row under the header. The phase is in degrees, from −180° to 180°: negative when the output lags the input. The coherence has no unit.
Checked against SciPy
24 checks of the FRF and coherence, all passing. Our own tests run H1, H2, their phase and the coherence with every window and estimator through MegaRows and through SciPy’s csd, welch and coherence on the same file, and compare every value: the largest difference was 4.5 × 10⁻¹⁴ of the size of the result. See every check.
Private by design: nothing is uploaded
Test data is often confidential. This tool reads your file and calculates the FRF in your browser, so the file and its name never leave your device. It works on files with millions of rows: the spectra use every sample of both channels.
More for measured signals
- FFT from CSVThe amplitude spectrum or the PSD of a column (you choose which first), with a table of its peaks.
- PSD calculatorPower spectral density (Welch) in g²/Hz, with the Grms of any band and of each peak.
- Spectrogram from CSVHow the frequencies of a measured signal change over time, as a heat map.
- How we check our mathsEvery calculation checked against NumPy and SciPy by our own tests.
- CSV plotterPlot the signals themselves, zoom in and read the statistics.
Frequently asked questions
What is a frequency response function?
The ratio of a system’s output to its input at each frequency: how much it responds, and how late (the phase). From an FRF you can read resonances, where the magnitude peaks and the phase passes −90° for a simple resonance, and the damping, from how sharp the peak is.
How do I calculate an FRF from a CSV file?
Open a CSV with a time column, the input and the output in the tool at the top of this page. The FRF settings open with the plotted channel as the input and the next one as the output; check them and click “Open plot”.
H1 or H2: which should I use?
H1 when the noise is on the output, the usual case for a measured response: it is not biased by that noise. H2 when the noise is on the input, and often at sharp resonances, where the input force drops. H1 is never above H2; where they differ, the coherence is low.
What does low coherence mean?
That at that frequency the output does not follow the input in a straight line: noise on either signal, another input you did not measure, a nonlinear system, or segments too short for a sharp resonance. High coherence supports a consistent linear relation between input and output at these settings. Check calibration, alignment, noise and leakage before relying on the FRF.
Is a magnitude plot a full Bode plot?
No: a Bode plot shows both the magnitude and the phase of a response against a log frequency axis. This page works out both from the input and output signals, with the coherence, and Log X above the result plot puts the frequency on a log axis. A CSV that holds only frequency and magnitude gives the magnitude plot alone, as the guide to plotting frequency data on a log X axis explains.
Is this coherence the same as SciPy’s?
Yes: the magnitude-squared coherence, |Gxy|² / (Gxx Gyy), with the same window, segments and overlap as SciPy’s coherence. Our own tests compare it with SciPy on every change; MegaRows keeps it between 0 and 1 where rounding would step outside.
Is my data uploaded?
No. The file is read and the FRF is calculated by your browser, on your own device. Neither the file nor its name is sent anywhere; you can check it in the Network tab of your browser’s developer tools.
Related tools and guides
- CSV plotterOpen a CSV, Excel, TXT, JSON, MATLAB, Parquet, HDF5 or LabVIEW TDMS file with millions of rows and plot it in several linked charts, with zoom and statistics. Works today.
- Large CSV viewerOpen a CSV with millions of rows in your browser: scroll every row, see each column’s type and statistics, chart any column. Works today.
- MATLAB .mat file viewerOpen v4 to v7.3 .mat files without MATLAB and plot any signal. Works today.
- Parquet viewerOpen large .parquet files, see the schema at once and plot millions of rows, without Python. Works today.
- TDMS viewerOpen .tdms files from LabVIEW, DIAdem and DAQmx loggers: every group, channel and property, each channel plotted against its time. Works today.
- HDF5 viewerOpen .h5, .hdf5 and NetCDF-4 .nc files: every group, dataset and attribute, each group’s datasets plotted against their time. Works today.
- MAT to CSVConvert the signals of a .mat file, v4 to v7.3, to a CSV for Excel or Python, without MATLAB. Works today.
- Parquet to CSVConvert a .parquet file to CSV in your browser, with the columns you pick. Works today.
- TDMS to CSVConvert the channels of a .tdms file to CSV, a group at a time, with its time column, without LabVIEW or Excel add-ins. Works today.
- HDF5 to CSVConvert the datasets of an .h5 or NetCDF-4 file to CSV, a table at a time, with its time column, without Python. Works today.
- Excel to CSVConvert any sheet of an .xlsx or .xlsm workbook to CSV, with the saved results of formulas, real dates and 15 significant digits. Works today.
- JSON to CSVConvert JSON and JSON Lines files to CSV: nested fields become columns named by their path, arrays stay as JSON text. Works today.
- CSV to MATConvert a CSV, Excel, JSON or Parquet file to a MATLAB .mat file: a field per column, with names and units, every row. Works today.
- Merge CSV filesAppend many CSV files into one, even with different columns or separators. Works today.
- Split CSV filesSplit a CSV too big for Excel into parts of 1,000,000 rows, parts of a size you choose, or one file per value of a column. Works today.
- CSV row counterCount the lines in a CSV, TSV or TXT file of any size. Works today.
- CSV statisticsCount, missing values, min, max, mean, standard deviation, RMS and peak to peak of each number column, for the whole file or the rows you zoom into. Works today.
- CSV histogramA histogram of any number column, with automatic bins or 10 to 200 of them, and each bin’s count as a table. Works today.
- CSV too large for Excel?Open every row of a CSV beyond Excel’s 1,048,576-row limit, or work around the limit in six other ways.
- FFT and PSD from a CSVTurn a signal column into an FFT spectrum or a PSD with Grms, with results checked against SciPy. Works today.
- PSD calculatorTurn a vibration column into a power spectral density (Welch) in g²/Hz, with the Grms of any band and a dB view. Works today.
- Spectrogram from CSVSee how the frequencies of a measured signal change over time, as a heat map in dB, with the window and range you choose. Works today.
- The MegaRows toolboxWhat works today and what is coming next, and why nothing is ever uploaded.
Coming soon to MegaRows: CSV to Excel and PDF reports · Compare CSV versions.
MegaRows processes files locally in your browser. Nothing is uploaded, not even the file name.