How does one interpret a Bland-Altman plot?

In Plain English, how does one interpret a Bland-Altman plot?

What are the advantages of using a Bland-Altman plot over other methods of comparing two different measurement methods?

The Bland-Altman plot is more widely known as the Tukey Mean-Difference Plot (one of many charts devised by John Tukey http://en.wikipedia.org/wiki/John_Tukey).

The idea is that x-axis is the mean of your two measurements, which is your best guess as to the "correct" result and the y-axis is the difference between the two measurement differences. The chart can then highlight certain types of anomalies in the measurements. For example, if one method always gives too high a result, then you'll get all of your points above or all below the zero line. It can also reveal, for example, that one method over-estimates high values and under-estimates low values.

If you see the points on the Bland-Altman plot scattered all over the place, above and below zero, then the suggests that there is no consistent bias of one approach versus the other (of course, there could be hidden biases that this plot does not show up).

Essentially, it is a good first step for exploring the data. Other techniques can be used to dig into more particular sorts of behaviour of the measurements.

• What does it mean if B&A mass is lower diagonally? I am studying ECG signals and thinking if it could indicate the mean electrical axis. – Léo Léopold Hertz 준영 Nov 22 '16 at 6:52

In addition to difference versus average plot, Bland and Altman plots can also be ratio versus average. plots.

For example, a new weighing machine gives the following data when people of weights 60, 70 and 80 kg step on it..

66 kg 77 kg 88 kg

In such a scenario, the weighing machine overestimates the weight by 10% every time. So a ratio versus average plot will give a better visualization of the data in this case.

• Welcome to Cross Validated! Please take a moment to view our tour. It would also be helpful if you provided a citation with your response. – Tavrock Mar 8 '17 at 19:12
• Arguably, (1) geometric mean is a better reference here than mean (2) log ratio = log one - log other and log geometric mean could then be plotted. – Nick Cox Mar 8 '17 at 19:18

This is the Wikipedia definition of a Bland-Altman plot:

A Bland–Altman plot (difference plot) in analytical chemistry or biomedicine is a method of data plotting used in analyzing the agreement between two different assays. It is identical to a Tukey mean-difference plot1, the name by which it is known in other fields, but was popularised in medical statistics by J. Martin Bland and Douglas G. Altman

If you want to implement a Bland-Altman plot in Python you can use this:

If you would like to do this in Python you can use this code

import matplotlib.pyplot as plt
import numpy as np
from numpy.random import random
%matplotlib inline
plt.style.use('ggplot')


I just added the last line because I like the ggplot style.

def plotblandaltman(x,y,title,sd_limit):
plt.figure(figsize=(20,8))
plt.suptitle(title, fontsize="20")
if len(x) != len(y):
raise ValueError('x does not have the same length as y')
else:
for i in range(len(x)):
a = np.asarray(x)

b = np.asarray(x)+np.asarray(y)
mean_diff = np.mean(b)
std_diff = np.std(b, axis=0)
limit_of_agreement = sd_limit * std_diff
lower = mean_diff - limit_of_agreement
upper = mean_diff + limit_of_agreement

difference = upper - lower
lowerplot = lower - (difference * 0.5)
upperplot = upper + (difference * 0.5)
plt.axhline(y=mean_diff, linestyle = "--", color = "red", label="mean diff")

plt.axhline(y=lower, linestyle = "--", color = "grey", label="-1.96 SD")
plt.axhline(y=upper, linestyle = "--", color = "grey", label="1.96 SD")

plt.text(a.max()*0.85, upper * 1.1, " 1.96 SD", color = "grey", fontsize = "14")
plt.text(a.max()*0.85, lower * 0.9, "-1.96 SD", color = "grey", fontsize = "14")
plt.text(a.max()*0.85, mean_diff * 0.85, "Mean", color = "red", fontsize = "14")
plt.ylim(lowerplot, upperplot)
plt.scatter(x=a,y=b)


And finaly I just make some random values and compare them in this function

x = np.random.rand(100)
y = np.random.rand(100)
plotblandaltman(x,y,"Bland-altman plot",1.96)


With some minor modification, you can easily add a for-loop and make several plots