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?


3 Answers 3


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.

  • $\begingroup$ 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. $\endgroup$ Nov 22, 2016 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.

  • $\begingroup$ 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. $\endgroup$
    – Tavrock
    Mar 8, 2017 at 19:12
  • 1
    $\begingroup$ 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. $\endgroup$
    – Nick Cox
    Mar 8, 2017 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

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')
        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)

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)

Bland-altman plot

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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.