4

Lets assume I have the following numpy array:

import numpy as np
import matplotlib.pyplot as plt
x = np.array([11.53333333, 11.86666667, 11.1, 10.66666667, 11.2, 11.3,
              11.06666667, 12.06666667, 11.8, 13.03333333, 12.4,
              12.33333333, 12.53333333, 13.33333333, 12.43333333, 13., 13.2,
              13.76666667, 14.96666667, 19.16666667, 25.1, 32.,
              83.33333333, 103.76666667, 110.7, 118.63333333, 129.26666667,
              139.06666667, 150.3, 161.53333333, 171.16666667, 184.56666667,
              196.6, 210.26666667, 221.63333333, 231.3, 244.16666667,
              253.5, 254.66666667, 255., 255., 255., 255.,
              255., 255., 255., 255., 255., 255.,
              255., 255., 255., 255., 255., 255.,
              255., 255., 255., 255., 255.])

plt.plot(x)
plt.show()

Here's the plotted output:

plotted x

How can I easily get the turning points in this graph? For example the first turning point is round about at x=20, another one at x=37.

Is it possible to get all turning points in an descending order, so I can afterwards grab the 3 most destinctive turning points?


Update: I am interested in getting the Inflection Points as well as the Stationary points. Is there a simple solution in numpy / scipy?

Mirko
  • 743
  • 1
  • 7
  • 18
  • You could try to approximate some derivative function from the data you have. – SylvainD Jan 22 '15 at 15:22
  • 1
    Define "turning point". And please define it mathematically, not with "the curve turns". – Ffisegydd Jan 22 '15 at 15:23
  • 1
    My guess is that "turning point" is supposed to mean ["inflection point"](http://en.wikipedia.org/wiki/Inflection_point). (Wrong translation from German?) – Sven Marnach Jan 22 '15 at 15:29
  • 1
    I updated the article a little bit. Accordingly to the wikipedia article "Inflection Point" they are also describing a "turning point" (see [this image](https://en.wikipedia.org/wiki/Inflection_point#mediaviewer/File:Cubic_graph_special_points.svg) – Mirko Jan 22 '15 at 15:39

2 Answers2

2

There are many possible answers -- depending what you actually want. One idea would be to smooth the data by taking moving averages or splines or something and then take the second derivative and look for when it changes sign. This would find approximate "inflection points" or "turning points" -- literally, it would find when the concavity changes.

See:

Community
  • 1
  • 1
gabe
  • 2,521
  • 2
  • 25
  • 37
2

I was looking for this answer too. This is one way how to find inflection point in python:

How to find the inflection point in a noisy curve?

The inflection point is [x0, y0]

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import gaussian_filter


def generate_fake_data():
    """Generate data that looks like an example given."""
    xs = np.arange(0, 25, 0.05)
    ys = - 20 * 1./(1 + np.exp(-(xs - 5.)/0.3))
    m = xs > 7.
    ys[m] = -20.*np.exp(-(xs - 7.)[m] / 5.)

    # add noise
    ys += np.random.normal(0, 0.2, xs.size)
    return xs, ys


def main():
    xs, ys = generate_fake_data()

    # smooth out noise
    smoothed = gaussian_filter(ys, 3.)

    # find the point where the signal goes above the background noise
    # level (assumed to be zero here).
    base = 0.
    std = (ys[xs < 3] - base).std()
    m = smoothed < (base - 3. * std)
    x0 = xs[m][0]
    y0 = ys[m][0]

    plt.plot(xs, ys, '.')
    plt.plot(xs, smoothed, '-')
    plt.plot(x0, y0, 'o')
    plt.show()


if __name__ == '__main__':
    main()

Example output of how to find inflection point in python