Hannes
Hannes

Reputation: 11

How to plot function of an array or alternative?

plt.plot(time,phi(time))

isnt working... whyyyyy????

tried to apply the function individually

import numpy as np import matplotlib.pyplot as plt

g = 9.81 l = 2 mu = 0.1

PHI_0 = np.pi / 3 PHI_PUNKT_0 = 0

def berrechne_phi_zwei_punkt(phi, phi_punkt):
   return -mu * phi_punkt - (g/l) * np.sin(phi)

def phi(t):
   phi = PHI_0
   phi_punkt = PHI_PUNKT_0
   delta_t = 0.001
   for time in np.arange(0,t,delta_t):
    phi_zwei_punkt = berrechne_phi_zwei_punkt(
      phi, phi_punkt
    )
    phi += phi_punkt * delta_t
    phi_punkt += phi_zwei_punkt * delta_t
   return phi

delta_t2 = 0.1
t_max = 10
time = np.arange(0, t_max+delta_t2 , delta_t2)
print(time)

plt.plot(time,phi(time))

plt.savefig('graph.png')

I want the correct plot of the function but it outputs "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"

Upvotes: 1

Views: 503

Answers (2)

hpaulj
hpaulj

Reputation: 231475

I think you need some guidance on how to debug and how to provide an informative question.

Here's your code, with a few syntax corrections.

In [3]: g = 9.81; l = 2; mu = 0.1 
   ...:  
   ...: PHI_0 = np.pi / 3; PHI_PUNKT_0 = 0 
   ...:  
   ...: def berrechne_phi_zwei_punkt(phi, phi_punkt): 
   ...:    return -mu * phi_punkt - (g/l) * np.sin(phi) 
   ...:  
   ...: def phi(t): 
   ...:    phi = PHI_0 
   ...:    phi_punkt = PHI_PUNKT_0 
   ...:    delta_t = 0.001 
   ...:    for time in np.arange(0,t,delta_t): 
   ...:     phi_zwei_punkt = berrechne_phi_zwei_punkt( 
   ...:       phi, phi_punkt 
   ...:     ) 
   ...:     phi += phi_punkt * delta_t 
   ...:     phi_punkt += phi_zwei_punkt * delta_t 
   ...:    return phi 
   ...:  
   ...: delta_t2 = 0.1 
   ...: t_max = 10 
   ...: time = np.arange(0, t_max+delta_t2 , delta_t2)                          
In [4]: time                                                                    
Out[4]: 
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ,
        1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9,  2. ,  2.1,
        2.2,  2.3,  2.4,  2.5,  2.6,  2.7,  2.8,  2.9,  3. ,  3.1,  3.2,
        3.3,  3.4,  3.5,  3.6,  3.7,  3.8,  3.9,  4. ,  4.1,  4.2,  4.3,
        4.4,  4.5,  4.6,  4.7,  4.8,  4.9,  5. ,  5.1,  5.2,  5.3,  5.4,
        5.5,  5.6,  5.7,  5.8,  5.9,  6. ,  6.1,  6.2,  6.3,  6.4,  6.5,
        6.6,  6.7,  6.8,  6.9,  7. ,  7.1,  7.2,  7.3,  7.4,  7.5,  7.6,
        7.7,  7.8,  7.9,  8. ,  8.1,  8.2,  8.3,  8.4,  8.5,  8.6,  8.7,
        8.8,  8.9,  9. ,  9.1,  9.2,  9.3,  9.4,  9.5,  9.6,  9.7,  9.8,
        9.9, 10. ])

phi with a single works fine:

In [5]: phi(1)                                                                  
Out[5]: -0.46063859245390176

But with the array, time, it produces your error:

In [6]: phi(time)                                                               
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-cdd824beb99b> in <module>
----> 1 phi(time)

<ipython-input-3-bc74d5ec1a6c> in phi(t)
     10    phi_punkt = PHI_PUNKT_0
     11    delta_t = 0.001
---> 12    for time in np.arange(0,t,delta_t):
     13     phi_zwei_punkt = berrechne_phi_zwei_punkt(
     14       phi, phi_punkt

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

You should have given us that full traceback/error message. It helps casual readers to focus on the problem. It should help you focus as well. Don Kirkby got it right.

Let's try that arange by itself:

In [7]: np.arange(0, time, 0.001)                                               
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-b37c7a8fd737> in <module>
----> 1 np.arange(0, time, 0.001)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

arange expects a stop, start and step. All should be scalars, not arrays. The error indicates that at some point it is testing size the stop value, either that it's bigger than the start or relative to some intermediate value. If you do `

A comparison on an array produces a boolean array:

In [9]: 2 <= np.arange(3)                                                       
Out[9]: array([False, False,  True])

Such an array cannot be used in Python context that expects a scalar boolean, such as a if or and. That's the kind of situation that produces this ambiguity error. Here it occurs inside the compiled arange function, so is a little harder to diagnose. In any case, the problem lies in using an array as argument to arange. I'm not going to guess as to why you are using two arange, one outside phi and one inside it. You need to sort that out for yourself.

Upvotes: 0

Don Kirkby
Don Kirkby

Reputation: 56680

I don't think you want to calculate phi(time), I think you want to calculate phi(t) where t is each element of time.

The important section is here:

def phi(t):
    # ...
    for time in np.arange(0,t,delta_t):

np.arange() takes a number as its second argument, so your phi() function must take a number. However, you call it with an array:

time = np.arange(0, t_max+delta_t2 , delta_t2)
print(time)

plt.plot(time,phi(time))

You can either loop through time calling phi(t) on each item, or vectorize your phi() function to take an array. The second option will probably be faster to run, but it's not always easy to see how to do it.

Upvotes: 1

Related Questions