wptmdoorn / methcomp

Python package providing functionality and plotting for chemistry method comparison
MIT License
14 stars 9 forks source link

implement mountain plot for method comparison #13

Closed wptmdoorn closed 3 years ago

wptmdoorn commented 3 years ago

https://www.medcalc.org/manual/mountain-plot.php

Krouwer, J. S., & Monti, K. L. (1995). A simple, graphical method to evaluate laboratory assays. European journal of clinical chemistry and clinical biochemistry, 33(8), 525-528. Monti, K. L. (1995). Folded empirical distribution function curves—mountain plots. The American Statistician, 49(4), 342-345. Xue J., Titterington D. M. (2010, unpublished). The p-folded Cumulative Distribution Function and the Mean Absolute Deviation from the p-quantile.

https://cran.r-project.org/web/packages/mountainplot/index.html (R implementation)

thomasburgess commented 3 years ago

Here is a an early attempt

# m1, m2 = method1 and method2 data
n=100
qrange=np.linspace(0, 1, n)
mrange=np.where(qrange<0.5,qrange,1.0-qrange)*100
mq = np.quantile(m1-m2, qrange)
fig, ax = plt.subplots()
ax.step(mq, mrange, where='mid', label='mid')
fig.savefig("mtn.png")

mtn

thomasburgess commented 3 years ago

somewhat improved

n=100
qrange=np.linspace(0, 1, n)
mrange=np.where(qrange<0.5,qrange,1.0-qrange)*100
mq = np.quantile(m1-m2, qrange)
auc = (np.diff(mq)*(mrange[:-1]+mrange[1:])/2).sum()
fig, ax = plt.subplots()
ax.step(mq, mrange, where='mid', label='Method1-Method2', )
ax.set(xlabel="Difference between methods", ylabel="Folded CDF %")
ax.axvline(0, label="median", linestyle=":")
ax.legend(title=f"AUC={auc:.2f}")
fig.savefig("mtn.png")

mtn

thomasburgess commented 3 years ago

Added new branch feature/mountain, to try it out:

    >>> import matplotlib.pyplot as plt
    >>> from methcomp import mountain
    >>> method1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    >>>    18, 19, 20]
    >>> method2 = [1.03, 2.05, 2.79, 3.67, 5.00, 5.82, 7.16, 7.69, 8.53, 10.38,
    >>>    11.11, 12.17, 13.47, 13.83, 15.15, 16.12, 16.94, 18.09, 19.13, 19.54]
    >>> method3 = [0.82, 2.09, 4.31, 4.18, 4.85, 6.01, 7.73, 7.95, 9.78, 10.07,
    >>>    11.64, 11.88, 12.90, 13.55, 14.57, 16.82, 16.95, 17.62, 18.44, 20.14]
    >>> mountain.Mountain(method1, method2, n_percentiles=500, unit="ng/ml").plot(
    >>>    color="blue", label="$M_1$ - $M_2$")
    >>> mountain.Mountain(method1, method3, n_percentiles=500, unit="ng/ml").plot(
    >>>    color="green", label="$M_1$ - $M_3$")
    >>> plt.show()

mountain

I need to find time to also add tests for this before PR

thomasburgess commented 3 years ago

Done: @wptmdoorn https://github.com/wptmdoorn/methcomp/pull/17

thomasburgess commented 3 years ago

Merged, so this issue is closed