2017-02-22 10 views
0

Я создал функцию, которая возвращает значение для силы в зависимости от позиции z (z_pos). Я хотел бы построить эти результаты (диаграмма сдвига для инженеров здесь), однако я получаю следующую ошибку:Как построить результаты функции с помощью matplotlib в python

ValueError: Значение истинности массива с более чем одним элементом неоднозначно. Используйте a.any() или a.All()

Я попытался это как с arange и LINSPACE, увидеть код здесь:

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() 

Помощь очень ценится!

ответ

1

Ошибка, которую вы получаете, не имеет ничего общего с заговором, но возникает, когда вы звоните int_force_y. Аргумент z_pos - это np.ndarray. Если вы сейчас сравните это, например. Lf1 в вашей функции, то это дает вам логический массив, в котором каждый элемент указывает, если соответствующий элемент z_pos меньше или равен Lf1 в случае вашего первого заявления if. Поскольку некоторые элементы меньше или равны, а некоторые нет, он не может решить, следует ли считать это True или False и просит вас использовать .any(), чтобы указать, что он должен быть True, если какой-либо элемент равен True или .all(), чтобы указать, что он должен быть True, если все элементы: True.

Но оба эти случая не делают того, что вы хотите от них делать. Вы хотите принять решение для каждого элемента отдельно и затем установить соответствующее значение в int_fc_y соответственно. Вы можете сделать это за цикл или более элегантно, используя boolean indexing и np.logical_and. Просто используйте эту функцию, чтобы произвести свой результат массив вместо вашей версии:

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 
0

Проблема происходит потому, что вы спрашиваете питона если ли массив больше или меньше определенного значения:

if z_pos <= Lf1: 

Это может быть правдой для некоторых значений и ложной для некоторых других, с вопросом о том, является ли это утверждение истинным или ложным двусмысленным.

Вы можете попробовать:

if np.array(z_pos <= Lf1).any(): 

или

if np.array(z_pos <= Lf1).all(): 

в зависимости от того, что вы хотите. То же самое для следующих операторов if.

+0

Это не даст ему желаемого результата, так как функция вернет только одно значение, а не массив всех значений результата. – jotasi