Search code examples
pythonscipyvalueerror

I have some problems with a value error in python


Here are my codes to plot a stress-strain curve

import matplotlib.pyplot as plt
import numpy as np
import math
from scipy.interpolate import interp1d
from matplotlib.offsetbox import AnchoredText
import pandas as pd


#both strain is a column in the given dataframe, and I manually calculated stress
df_1 = pd.read_csv('1045.csv',skiprows=25,header=[0,1])
print(df_1.head())

A1 = 40.602*(10e-6)
stress1 = ((df_1.Load)/A1)


plt.figure(figsize=(12,9))
plt.plot(df_1.Strain1.values,df_1.Load.values,'g')
plt.ylabel('stress(Pa)',fontsize=13)
plt.xlabel('Strain(%)',fontsize=13)
plt.xticks(np.arange(-6e-5,0.15,step=0.005),rotation = 45)
plt.yticks(np.arange(0,42000,step=1000))

strain = df_1.Strain1.values
stress = np.array(((df_1.Load.values)/A1))
strain = np.array((df_1.Strain1.values))

LinearLimit=1
Strain_values_linear = np.linspace(strain[0], strain[LinearLimit], num=50, endpoint=True)
Strain_values_eng = np.linspace(strain[LinearLimit], strain[-1], num=50, endpoint=True)
f1 = interp1d(strain, stress, fill_value='extrapolate')
f2 = interp1d(strain, stress, kind=3, fill_value='extrapolate')

Now I keep getting a value error saying : "x and y arrays must be equal in length along interpolation axis." I don't understand this...i printed the shape of strain and stress and they are the same Btw here is a screenshot of the csv file: enter image description here


Solution

  • You probably are passing an array of shape (..., N) as the first argument (meaning strain has shape of the form (..., N)). SciPy doesn't allow that and throws a ValueError. See the documentation for details. You should run a for loop if you have multiple vectors in strain array. The following code should work, considering you want to interpolate 1 function for each row in strain (and that strain is a 2-d array. If it isn't, you can easily convert it using strain.reshape(-1, N)):

    import matplotlib.pyplot as plt
    import numpy as np
    import math
    from scipy.interpolate import interp1d
    from matplotlib.offsetbox import AnchoredText
    import pandas as pd
    
    
    #both strain is a column in the given dataframe, and I manually calculated stress
    df_1 = pd.read_csv('1045.csv',skiprows=25,header=[0,1])
    print(df_1.head())
    
    A1 = 40.602*(10e-6)
    stress1 = ((df_1.Load)/A1)
    
    
    plt.figure(figsize=(12,9))
    plt.plot(df_1.Strain1.values,df_1.Load.values,'g')
    plt.ylabel('stress(Pa)',fontsize=13)
    plt.xlabel('Strain(%)',fontsize=13)
    plt.xticks(np.arange(-6e-5,0.15,step=0.005),rotation = 45)
    plt.yticks(np.arange(0,42000,step=1000))
    
    strain = df_1.Strain1.values
    stress = np.array(((df_1.Load.values)/A1))
    strain = np.array((df_1.Strain1.values))
    
    LinearLimit=1
    Strain_values_linear = np.linspace(strain[0], strain[LinearLimit], num=50, endpoint=True)
    Strain_values_eng = np.linspace(strain[LinearLimit], strain[-1], num=50, endpoint=True)
    
    f1, f2 = [], []
    for row in range(len(strain)):
        f1.append(interp1d(strain[row], stress, fill_value='extrapolate'))
        f2.append(interp1d(strain[row], stress, kind=3, fill_value='extrapolate'))
    

    Edit: From the comment, you have strain array of shape (222, 1). This means you already have a vector but the shape is not compatible with what SciPy accepts. In this case, you will have to reshape the strain and sress array to have the shape of the form (N,). Following code should work:

    import matplotlib.pyplot as plt
    import numpy as np
    import math
    from scipy.interpolate import interp1d
    from matplotlib.offsetbox import AnchoredText
    import pandas as pd
    
    
    #both strain is a column in the given dataframe, and I manually calculated stress
    df_1 = pd.read_csv('1045.csv',skiprows=25,header=[0,1])
    print(df_1.head())
    
    A1 = 40.602*(10e-6)
    stress1 = ((df_1.Load)/A1)
    
    
    plt.figure(figsize=(12,9))
    plt.plot(df_1.Strain1.values,df_1.Load.values,'g')
    plt.ylabel('stress(Pa)',fontsize=13)
    plt.xlabel('Strain(%)',fontsize=13)
    plt.xticks(np.arange(-6e-5,0.15,step=0.005),rotation = 45)
    plt.yticks(np.arange(0,42000,step=1000))
    
    strain = df_1.Strain1.values
    stress = np.array(((df_1.Load.values)/A1))
    strain = np.array((df_1.Strain1.values))
    strain = strain.reshape(-1,)
    stress = stress.reshape(-1,)
    
    LinearLimit=1
    Strain_values_linear = np.linspace(strain[0], strain[LinearLimit], num=50, endpoint=True)
    Strain_values_eng = np.linspace(strain[LinearLimit], strain[-1], num=50, endpoint=True)
    f1 = interp1d(strain, stress, fill_value='extrapolate')
    f2 = interp1d(strain, stress, kind=3, fill_value='extrapolate')