Reputation: 85
I have made a function which returns a value for a force depending on the z position (z_pos). I would like to plot these results (shear diagram for the engineers here), however I get the following error:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
I have tried it both with arange and linspace, see the code here:
import matplotlib.pyplot as plt
import numpy as np
#values in kN and m
FyFL = 520
FyRL = 1246
L = 40.
Lf1 = 2.
Lf2 = 25.5
g = 9.81
W = 60000
q = (3*g*W/L)/1000 #kN/m
print q
def int_force_y(FyFL, FyRL, L, Lf1, Lf2, q, z_pos):
if z_pos <= Lf1:
int_fc_y = -q*z_pos
elif z_pos > Lf1 and z_pos < Lf1+Lf2:
int_fc_y = -q*Lf1 + FyFL-q*z_pos
elif z_pos >= Lf2 and z_pos <= 40.:
int_fc_y = -q*Lf1 + FyFL-q*(Lf1+Lf2)-q*z_pos
else:
return "No valid z_pos"
return int_fc_y
z_pos = np.arange(0,41,1)
y = int_force_y(FyFL, FyRL, L, Lf1, Lf2, q, z_pos)
plt.plot(z_pos,y)
plt.show()
Help is very much appreciated!
Upvotes: 0
Views: 286
Reputation: 5177
The error you are getting has nothing to do with the plotting but arises when you call int_force_y
. The argument z_pos
is a np.ndarray
. If you now compare this to eg. Lf1
in your function then this gives you a boolean array where each element indicates if the corresponding element of z_pos
is smaller or equal to Lf1
in case of your first if
statement. As some elements are smaller or equal and some are not, he cannot decide whether he should consider this as True
or False
and asks you to use .any()
to indicate that it should be True
if any element is True
or .all()
to indicate that it should be True
if all elements are True
.
But both or these cases do not do what you want them to do. You want a decision for each element individually and to then set the corresponding value in int_fc_y
accordingly. You can do this by a for-loop or more elegantly by using boolean indexing and np.logical_and
. Just use this function to produce your result array instead of your version:
def int_force_y(FyFL, FyRL, L, Lf1, Lf2, q, z_pos):
if (z_pos>40.).any():
return "No valid z_pos"
int_force_y = np.zeros_like(z_pos)
int_fc_y[z_pos<=Lf1] = -q*z_pos
int_fc_y[np.logical_and(z_pos > Lf1,
z_pos < Lf1+Lf2)] = -q*Lf1 + FyFL-q*z_pos
int_fc_y[np.logical_and(z_pos >= Lf2,
z_pos <= 40.)] = -q*Lf1 + FyFL-q*(Lf1+Lf2)-q*z_pos
return int_fc_y
Upvotes: 1
Reputation: 837
The problem happens because you are asking python whether if an array is larger or smaller than certain value:
if z_pos <= Lf1:
This might be truth for some values and false for some others, with leaves the question of whether if that statement is true or false ambiguous.
You can try :
if np.array(z_pos <= Lf1).any():
or
if np.array(z_pos <= Lf1).all():
depending on what you want. Same for the following if statements.
Upvotes: 0