Как получить значение площади под несколькими вершинами - PullRequest
0 голосов
/ 19 января 2019

У меня есть некоторые данные из биоанализатора, который дает мне время (ось X) и значения поглощения (ось Y). Время составляет каждые 0,05 секунды и составляет от 32 до 138 секунд, поэтому вы можете представить, сколько у меня точек данных. Я создал график с использованием plotly и matplotlib, просто чтобы у меня было больше библиотек, с которыми можно работать, чтобы найти решение, поэтому решение в любой библиотеке в порядке! То, что я пытаюсь сделать, это заставить мой скрипт найти область под каждым пиком и вернуть мое значение.

def create_plot(sheet_name):
    sample = book.sheet_by_name(sheet_name)
    data = [[sample.cell_value(r, c) for r in range(sample.nrows)] for c in range(sample.ncols)]
    y = data[2][18:len(data[2]) - 2]
    x = np.arange(32, 138.05, 0.05)
    indices = peakutils.indexes(y, thres=0.35, min_dist=0.1)
    peaks = [y[i] for i in indices]

Этот фрагмент получает мои значения Y, значения X и индексы пиков. Есть ли способ получить площадь под каждой кривой? Допустим, есть 15 индексов.

Вот как выглядит график: enter image description here

1 Ответ

0 голосов
/ 20 января 2019

Автоматический ответ

Учитывая набор значений x и y, а также набор peaks (x -координат пиков), вот как вы можете автоматически найти область под каждым из пиков. Я предполагаю, что x, y и peaks являются массивами Numpy:

import numpy as np

# find the minima between each peak
ixpeak = x.searchsorted(peaks)
ixmin = np.array([np.argmin(i) for i in np.split(y, ixpeak)])
ixmin[1:] += ixpeak
mins = x[ixmin]

# split up the x and y values based on those minima
xsplit = np.split(x, ixmin[1:-1])
ysplit = np.split(y, ixmin[1:-1])

# find the areas under each peak
areas = [np.trapz(ys, xs) for xs,ys in zip(xsplit, ysplit)]

Выход:

enter image description here

Пример данных был настроен таким образом, чтобы площадь под каждым пиком (более или менее) гарантированно составляла 1.0, поэтому результаты на нижнем графике верны. Зеленые метки X - это места минимума между каждыми двумя пиками. Часть кривой, «принадлежащая» каждому пику, определяется как часть кривой между минимумами, примыкающими к каждому пику.

Полный код

Вот полный код, который я использовал для генерации данных примера:

import scipy as sp
import scipy.stats

prec = 1e5
n = 10
N = 150
r = np.arange(0, N+1, N//n)

# generate some reasonable fake data
peaks = np.array([np.random.uniform(s, e) for s,e in zip(r[:-1], r[1:])])
x = np.linspace(0, N + n, num=int(prec))
y = np.max([sp.stats.norm.pdf(x, loc=p, scale=.4) for p in peaks], axis=0)

и код, который я использовал для построения графиков:

import matplotlib.pyplot as plt

# plotting stuff
plt.figure(figsize=(5,7))
plt.subplots_adjust(hspace=.33)
plt.subplot(211)
plt.plot(x, y, label='trace 0')
plt.plot(peaks, y[ixpeak], '+', c='red', ms=10, label='peaks')
plt.plot(mins, y[ixmin], 'x', c='green', ms=10, label='mins')
plt.xlabel('dep')
plt.ylabel('indep')
plt.title('Example data')
plt.ylim(-.1, 1.6)
plt.legend()

plt.subplot(212)
plt.bar(np.arange(len(areas)), areas)
plt.xlabel('Peak number')
plt.ylabel('Area under peak')
plt.title('Area under the peaks of trace 0')
plt.show()
...