Analyst
Analyst

Reputation: 31

Count Number of cycles in graph/ plot using Python / Pandas / Numpy

How can I find out how many times the Y value (Speed) ramps up and down from 700 -800 RPM to 1600 to 1800 RPM and vice versa from graph plotted in matplotlib by using python / pandas / numpy libraries. I have plotted this graph using matplotlib and using dataframe.

Expected output should be---> Number of Ramps up in Speed = 2 & Down = 2 looking at attached graph

Attached image /graph below for more clarification

enter image description here

fig = plt.figure(figsize =(18,10))

ax =plt.subplot(311)
plt.plot(df.speed)

ax.set_yticks([0, 500, 700, 1000, 1500, 1700, 2000])

ax.set_xlabel("Time (Seconds)")
ax.set_ylabel("Speed (RPM)")
plt.grid()
plt.show()

Upvotes: 2

Views: 1975

Answers (3)

Zach Ingbretsen
Zach Ingbretsen

Reputation: 193

Here is a vectorized solution:

import pandas as pd

df = pd.DataFrame({'speed': [0,1600,0,1600,1600,1600,0,0,0]})

# Check if values are above or below a threshold
threshold = 1500
df['over_threshold'] = df['speed'] > threshold

# Compare to the previous row
# If over_threshold has changed, 
# then you either went above or fell below the threshold
df['changed'] = df['over_threshold'] != df['over_threshold'].shift(1)

# First one has, by definition, has no previous value, so we should omit it
df = df.loc[1:,]

# Count how many times a row is newly above or below threshold
counts = df.loc[df['changed']].groupby('over_threshold').agg({'changed': 'count'})
counts.index = ["Down", "Up"]
counts.columns = ["Count"]
counts

#     Count
#Down   2
#Up     2

You will then have counts of how many times you have ramped up or down.

Upvotes: 3

Zachary Oldham
Zachary Oldham

Reputation: 868

# state variables
decreasing = False
increasing = False
last_above = False
last_below = False
drop_count = 0
jump_count = 0

for rpm_str in df:
    rpm = int(rpm_str)    # Because OP indicated the data was a string
    # Crossing threshold
    if ((last_below or decreasing) and rpm < 700):
        drop_count = drop_count + 1
        decreasing = False
        last_below = False
    elif ((last_above or increasing) and rpm > 1600):
        jump_count = jump_count + 1
        increasing = False
        last_above = False
    if (last_above and rpm < 1600):
        decreasing = True
        increasing = False
    elif (last_below and rpm > 700):
        increasing = True
        decreasing = False

    # State
    last_below = False
    last_above = False
    if (rpm < 700):
        last_below = True
    elif (rpm > 1600):
        last_above = True

This is not a perfect solution and will probably miss some edge cases, but your data looks pretty normal

Upvotes: 2

Jake P
Jake P

Reputation: 480

try the following code:

y is the y data (rpm) lim is the amount of rpms at which a cycle has started

cycles = 0
for i in range(len(y)):
    if y[i] >= lim:
        cycles += 1
        while y[i] >= lim:
            i += 1

Upvotes: 0

Related Questions