I would like to know if there is any way in python to automatically determine the values of point a and b marked in the graph below. Said a different way, finding the values when my plot shows a marked decrease or after a marked increase.

two muppets

This is the source code of my plot if it is helpful:

#load data

min_duration = data['Time_Secondes'].min()
max_duration = data['Time_Secondes'].max()
xr_ = list(range(min_duration,  max_duration,  60))
y_ = []

for i in range(0,(len(xr_)-1)):
    Time_proba_ = np.logical_and(data['Time_Secondes'].values >= xr_[i], data['Time_Secondes'].values < xr_[i+1])
    Time_proba_1_ = np.logical_and(np.logical_and(data['Time_Secondes'].values >= xr_[i], data['Time_Secondes'].values < xr_[i+1]), data['outcome'].values==1)
    y_.append(sum(Time_proba_1_ )/sum(Time_proba_))

import matplotlib
matplotlib.pyplot.plot(xr_[1:len(xr_)], y_)


1 Answer 1


It seems what you are looking for is a function of your data, not of matplotlib. I would think of this as a second derivative problem -- you care about differences in slopes of successive lines.

  1. Sort a dataframe [x,y] by x values, in increasing order.
  2. Calculate the first discrete derivative delta1 = (y[i+1] - y[i]) / (x[i+1] - x[i]). This tells you the slope of each line.
  3. Now you can do one of two things, depending on what you want to identify.
    1. Calculate the second discrete derivative delta2 = (delta1[i+1] - delta1[i]) / (x[i+1] - x[i]).
    2. Calculate the difference of successive slopes diff = delta1[i+1] - delta1[i]
  4. Select all is for which absolute value of {diff or delta2} is greater than a certain threshold.

Selecting all x values for which np.abs(x[i]) > threshold will give you the x-locations of these large changes in slope.

Here's an example I just coded up,for identifying the jump in a jump function $x / |x|$.

import numpy as np
import pandas as pd

n_data = 100

x = np.random.uniform(-10,10,n_data)
y = x / np.abs(x)

delta = [0] * n_data
diff = [0] * n_data

data = pd.DataFrame({'x':x, 'y':y})
data = data.sort_values('x')

for i in range(n_data - 1):
    a, fa = data.iloc[i]
    b, fb = data.iloc[i+1]
    diff_quot = (fb - fa) / (b-a)
    delta[i] = diff_quot

data['delta'] = delta

for i in range(n_data - 1):
    a, fa, da = data.iloc[i]
    b, fb, db = data.iloc[i+1]
    dd = db - da
    diff[i] = np.abs(dd)

data['diff'] = diff


threshold = 1
jumps = [dd > threshold for dd in diff]

Here is the jump function, whose jump we might want to locate

jump function

Here is a graph of the differences in slopes, where we see the jump is located near x = 0

diff function

  • 1
    $\begingroup$ Depends on whether the asker has data or the plot. Maybe the asker has plots and needs to determine the data from it. But I have to tell you that's a good answer $\endgroup$ Commented Apr 18, 2019 at 23:53
  • $\begingroup$ @JuanEstebandelaCalle I figured based on the way the plot was defined that the asker had data. You're right though, and if this is entirely dependent on a picture I don't really have an answer. Thanks for the compliment :) $\endgroup$ Commented Apr 19, 2019 at 2:59
  • $\begingroup$ Thank you, Andrew, for your answer. I do appreciate it. Actually, I have data frame contains 2 columns: Time that gamers spent on seconds and their scores (correct and incorrect). I want to know the range of time when the probability of score can be 0 , i.e I want to get all the markable decrease on the plot . I dont know wich fonction can help me. $\endgroup$
    – Nirmine
    Commented Apr 19, 2019 at 13:53
  • $\begingroup$ I want to get the range on x-axis . for example in the plot picture I would like to get as result 450---600 where I have markable decrease $\endgroup$
    – Nirmine
    Commented Apr 19, 2019 at 13:56
  • $\begingroup$ @Nirmine But in your picture 450--600 has a net increase -- it's not a markable decrease. There's a decrease between (I would say) 425 -- 475, and an increase from 475 -- 600. $\endgroup$ Commented Apr 20, 2019 at 4:04

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.