All examples · Example 21 of 34
Bland–Altman Agreement Plot
Difference between point-of-care meter and reference analyser against their mean for 80 samples; solid line is the mean bias, dashed lines the 95% limits of agreement.

Key findings
- The meter reads 4.264 mg/dL high on average (paired t p = 4.3 × 10⁻⁸); 95% limits of agreement -8.06 to 16.59 mg/dL.
- The bias grows with glucose level: Pearson r of difference vs mean = 0.308, p = 0.005.
- The two methods correlate at r = 0.9961 — near-perfect correlation, yet clinically relevant disagreement.
Descriptive statistics
Location, spread and shape for every group — the first thing to read before choosing a test. Skewness near 0 and excess kurtosis near 0 are what a normal distribution looks like.
| Group | n | Mean | SD | SEM | Median | Q1 – Q3 | Min – Max | Skewness | Excess kurtosis |
|---|---|---|---|---|---|---|---|---|---|
| Reference | 80 | 177.2 | 66.83 | 7.472 | 183.6 | 128.5 – 233.7 | 61.6 – 297.9 | -0.0798 | -1.09 |
| Point-of-care | 80 | 181.5 | 68.77 | 7.688 | 187.9 | 128.8 – 232.5 | 61 – 307.8 | -0.0643 | -1.09 |
| Difference (POC − ref) | 80 | 4.264 | 6.287 | 0.703 | 4.25 | -0.275 – 7.9 | -7.6 – 20.8 | 0.5 | 0.253 |
LabTools call
stats.describelabtools stats describe --groups @groups.json
The same method is available as an MCP tool (stats_describe) and from the desktop app's statistics panel.
Normality of the differences
Limits of agreement (bias ± 1.96 SD) assume the differences are roughly normal — so the differences, not the raw readings, are tested. Differences and means are computed here before the data reach LabTools.
| Group | n | Shapiro–Wilk W | p | Anderson–Darling A² | p | K–S D | p | Verdict |
|---|---|---|---|---|---|---|---|---|
| Difference (POC − ref) | 80 | 0.9745 | 0.11 | 0.347 | 0.47 | 0.05 | 0.89 | Consistent with normal |
LabTools calls (3)
stats.normalitylabtools stats normality --groups @groups.json --method shapiro-wilk
stats.normalitylabtools stats normality --groups @groups.json --method anderson-darling
stats.normalitylabtools stats normality --groups @groups.json --method kolmogorov-smirnov
The same method is available as an MCP tool (stats_normality) and from the desktop app's statistics panel.
Outlier screen
Five detectors with different assumptions. Grubbs tests the single most extreme point, generalised ESD looks for up to several (immune to masking), Dixon's Q is the small-sample chemistry test, modified-z uses the median and MAD so needs no normality, and the IQR rule is Tukey's boxplot fence. LabTools flags points; it never deletes them.
| Method | Difference (POC − ref) |
|---|---|
| Grubbs | none |
| Generalised ESD | none |
| Modified z (MAD) | none |
| IQR fences (1.5×) | 3 (20.5, 20.6, 20.8) |
LabTools calls (4)
stats.outlierslabtools stats outliers --groups @groups.json --method grubbs
stats.outlierslabtools stats outliers --groups @groups.json --method generalized-esd --max-outliers 5
stats.outlierslabtools stats outliers --groups @groups.json --method modified-z
stats.outlierslabtools stats outliers --groups @groups.json --method iqr
The same method is available as an MCP tool (stats_outliers) and from the desktop app's statistics panel.
LabTools notes
- Grubbs tests only the single most extreme point, so a second outlier can mask the first. On larger samples use method='generalized_esd'.
- Flagged points are candidates, not verdicts, and nothing has been removed. Look for a physical cause before excluding anything; if there is none, keep the point and use a robust test instead. Any exclusion must be reported.
- The IQR rule is descriptive — it has no p-value and flags roughly 0.7% of a perfectly normal sample by construction.
Systematic bias
Is the meter reading consistently high or low? A paired t-test and a Wilcoxon signed-rank test of meter against reference, with a 95% interval for the mean difference (the bias).
LabTools call
stats.describelabtools stats describe --data @difference.json
The same method is available as an MCP tool (stats_describe) and from the desktop app's statistics panel.
Meter vs reference (paired)
Each unit is measured twice, so the analysis is on the within-unit differences. The paired t-test and the Wilcoxon signed-rank test answer the same question with and without a normality assumption; the unpaired Welch test is shown only to illustrate how much power ignoring the pairing throws away.
| Test | Statistic | df | p | Difference (Point-of-care − Reference) | 95% CI | Effect size |
|---|---|---|---|---|---|---|
| Paired t-test | t = 6.065 | 79 | 4.3 × 10⁻⁸ | 4.264 | [2.865, 5.663] | dz = 0.678 (medium) |
| Wilcoxon signed-rank | W = 517.5 | — | 2.1 × 10⁻⁷ | median 4.25 | — | r = 0.672 (rank-biserial) |
| Welch t-test (ignores pairing) | t = 0.3977 | 157.9 | 0.69 | 4.264 | [-16.91, 25.44] | g = 0.0626 |
LabTools calls (3)
stats.ttestlabtools stats ttest --a @Point-of-care.json --b @Reference.json --test paired
stats.wilcoxonlabtools stats wilcoxon --a @Point-of-care.json --b @Reference.json
stats.ttestlabtools stats ttest --a @Point-of-care.json --b @Reference.json --test welch
The same method is available as an MCP tool (stats_ttest) and from the desktop app's statistics panel.
LabTools notes
- Group 'a' departs from normality (Shapiro–Wilk W = 0.9612, p = 0.0160 < 0.05). Consider stats.wilcoxon (signed-rank).
- Group 'b' departs from normality (Shapiro–Wilk W = 0.9571, p = 0.0090 < 0.05). Consider stats.wilcoxon (signed-rank).
- 1 pair(s) had a difference of exactly zero and carry no rank information; the test uses the remaining 79.
Proportional bias
Does the disagreement grow with the glucose level? Correlate the difference with the mean of the two methods. A significant trend means a single bias figure understates the error at the high end.
| Coefficient | Estimate | r² | n | p |
|---|---|---|---|---|
| Pearson r (linear) | 0.3081 | 0.09492 | 80 | 0.005 |
| Spearman ρ (monotonic, rank) | 0.3412 | — | 80 | 0.002 |
| Kendall τ (rank, tie-robust; normal-approximation p) | 0.2361 | — | 80 | 0.002 |
LabTools calls (3)
stats.correlationlabtools stats correlation --a @Mean_of_methods.json --b @Difference.json --method pearson
stats.correlationlabtools stats correlation --a @Mean_of_methods.json --b @Difference.json --method spearman
stats.correlationlabtools stats correlation --a @Mean_of_methods.json --b @Difference.json --method kendall
The same method is available as an MCP tool (stats_correlation) and from the desktop app's statistics panel.
LabTools notes
- Pearson's r measures LINEAR association only, and is sensitive to outliers. A scatter plot (plot.create kind='scatter') is worth a look before reporting it; use method='spearman' if the relationship is monotonic but curved.
Correlation between methods (and why it is not agreement)
Two methods can correlate almost perfectly and still disagree by a constant or proportional amount — which is exactly why Bland and Altman proposed their plot. Shown for completeness.
| Coefficient | Estimate | r² | n | p |
|---|---|---|---|---|
| Pearson r (linear) | 0.9961 | 0.9922 | 80 | 4.9 × 10⁻⁸⁴ |
| Spearman ρ (monotonic, rank) | 0.9927 | — | 80 | 1.6 × 10⁻⁷³ |
| Kendall τ (rank, tie-robust; normal-approximation p) | 0.9342 | — | 80 | 1.4 × 10⁻³⁴ |
LabTools calls (3)
stats.correlationlabtools stats correlation --a @Reference.json --b @Point-of-care.json --method pearson
stats.correlationlabtools stats correlation --a @Reference.json --b @Point-of-care.json --method spearman
stats.correlationlabtools stats correlation --a @Reference.json --b @Point-of-care.json --method kendall
The same method is available as an MCP tool (stats_correlation) and from the desktop app's statistics panel.
LabTools notes
- Pearson's r measures LINEAR association only, and is sensitive to outliers. A scatter plot (plot.create kind='scatter') is worth a look before reporting it; use method='spearman' if the relationship is monotonic but curved.
Methods paragraph
Written to go straight into a manuscript.
Mean bias was +4.3 mg/dL (95% CI 2.9–5.7; paired t(79) = 6.07, p < 0.0001) with limits of agreement −8.1 to +16.6 mg/dL. The difference increased with concentration (r = 0.31, p = 0.005), indicating proportional bias.
Every number on this page was computed by the LabTools statistics engine (version 0.14.3) from the example's CSV on 2026-09-23. Where a value was derived before the data reached LabTools (replicate means, paired differences, log odds ratios), the text says so. The data are simulated from a fixed random seed.
Get started
Run the same analysis on your data
Every test on this page is built into LabTools — from the statistics panel, the command line, or an AI assistant through MCP.