pythonif-statementplotconditional-statementssympy

how to plot a function with a condition on the output?


I am trying to figure out how to plot a function with a condition on the output. I've looked into various sites and questions here, but I didn't manage to find a solution to my problem (or at least one I managed to understand).

(note : I'm using jupyter)

I managed to plot a curve for the torque of an engine vs the rpms. I would like to limit the output value of the torque to 500. torque vs rpms, torque rpms with limiter

I've defined a function with an "if" condition (on cell 2 below) which can calculate the values.

The function calculates correctly (verification made on cell 3 below) but I don't manage to plot it.

I'm getting the error "TypeError: cannot determine truth value of Relational", and I don't manage to understand why, since the inpendent values seem to be calculated correctly)

Would you have a solution, or could the issue come from the "inflexion points"?

Thanks for your help.

my code below :

1st cell (defining the equation torque vs rpm + plotting it, works fine)

#ENGINE
rpm_eng, torq_eng = symbols('rpm_eng, torq_eng')

def eq_torq_eng(rpm_eng):
    return -8.6916*10**-14*rpm_eng**4 + 2.3789*10**-9*rpm_eng**3 - 2.8710*10**-5*rpm_eng**2 + 1.9178*10**-1*rpm_eng + 1.5105

plot(eq_torq_eng(rpm_eng), (rpm_eng, 0, 13000), \
     title="engine output : torque vs rpm", xlabel="rpm", ylabel="torque in N.m")

second cell (defining the equation for the limited torque vs rpm + plotting. the plot doesn't work)

def eq_torq_limiter(rpm_eng):
    if -8.6916*10**-14*rpm_eng**4 + 2.3789*10**-9*rpm_eng**3 - 2.8710*10**-5*rpm_eng**2 + 1.9178*10**-1*rpm_eng + 1.5105>500:
        return 500
    else:
        return -8.6916*10**-14*rpm_eng**4 + 2.3789*10**-9*rpm_eng**3 - 2.8710*10**-5*rpm_eng**2 + 1.9178*10**-1*rpm_eng + 1.5105

plot(eq_torq_limiter(rpm_eng), (rpm_eng, 0, 13000), \
     title="engine output : torque vs rpm", xlabel="rpm", ylabel="torque in N.m")

third cell (verification that the function calculates the limited torque correctly)

for rpm_eng in range(1000, 14000, 1000):
  print(eq_torq_limiter(rpm_eng))

Solution

  • You can use Piecewise to construct a new function, like this:

    rpm_eng, torq_eng = symbols('rpm_eng, torq_eng')
    
    def eq_torq_eng(rpm_eng):
        return -8.6916*10**-14*rpm_eng**4 + 2.3789*10**-9*rpm_eng**3 - 2.8710*10**-5*rpm_eng**2 + 1.9178*10**-1*rpm_eng + 1.5105
    
    torque = eq_torq_eng(rpm_eng)
    
    torque_limited = Piecewise(
        (500, torque > 500),
        (torque, True)
    )
    
    plot(torque_limited, (rpm_eng, 0, 13000), \
         title="engine output : torque vs rpm", xlabel="rpm", ylabel="torque in N.m")
    

    enter image description here