Извлеченные минимальные и максимальные значения нескольких массивов каждого x и y

#python #matplotlib #max #min

Вопрос:

Я пытаюсь составить список минимальных и максимальных значений 4 различных наборов данных. Наборы данных представляют собой полиномиальное соответствие 4-го порядка нескольким тестам, которые я провел в лаборатории. Ниже я привел пример кода, чтобы показать, в чем заключаются трудности. Массивы наборов данных имеют разную длину и начинаются с разных значений x. Вот почему мне не удалось решить эту проблему с помощью простого цикла for.

Синие и красные линии показывают, как должны выглядеть минимальные и максимальные массивы при построении графика.

Я надеюсь, что с примером кода все ясно.

 # -*- coding: utf-8 -*-
"""
Created on Mon Oct  4 10:49:21 2021

@author: Lodewijk
"""
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from numpy import arange

#%% Creating X and Y example values
XTest1=list(range(0,40))
YTest1=np.empty(len(XTest1))
XTest2=list(range(10,40))
YTest2=np.empty(len(XTest2))
XTest3=list(range(2,40))
YTest3=np.empty(len(XTest3))
XTest4=list(range(5,38))
YTest4=np.empty(len(XTest4))
for i in range(len(XTest1)):
    YTest1[i]=math.sin(XTest1[i])
for i in range(len(XTest2)):
    YTest2[i]=3*math.sin(XTest2[i])
for i in range(len(XTest3)):
    YTest3[i]=2*math.sin(XTest3[i])-0.5
for i in range(len(XTest4)):
    YTest4[i]=0.5*math.sin(XTest4[i]) 1



plt.plot(XTest1,YTest1, label='Data 1')
plt.plot(XTest2,YTest2, label='Data 2')
plt.plot(XTest3,YTest3, label='Data 3')
plt.plot(XTest4,YTest4, label='Data 4')
plt.legend()
plt.show()
#%% Making a 4th order polynomial best fit graph through the data sets



def objective_4(x,a,b,c,d,e):
    return a * x**4  b*x**3  c*x**2 d*x e 
pars, cov = curve_fit(objective_4, XTest1,YTest1)
x_line1 = arange(min(XTest1), max(XTest1), 1)
a, b, c, d, e = pars
y_line1 = objective_4(x_line1, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest2,YTest2)
x_line2 = arange(min(XTest2), max(XTest2), 1)
a, b, c, d, e = pars
y_line2 = objective_4(x_line2, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest3,YTest3)
x_line3 = arange(min(XTest3), max(XTest3), 1)
a, b, c, d, e = pars
y_line3 = objective_4(x_line3, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest4,YTest4)
x_line4 = arange(min(XTest4), max(XTest4), 1)
a, b, c, d, e = pars
y_line4 = objective_4(x_line4, a, b, c, d, e)

            
plt.plot(x_line1,y_line1, label='Test1')
plt.plot(x_line2,y_line2, label='Test2')
plt.plot(x_line3,y_line3, label='Test3')
plt.plot(x_line4,y_line4, label='Test4')
plt.legend()
plt.show()
    
 

Ответ №1:

Один из вариантов сделать это-дополнить ваши данные, np.nan чтобы убедиться, что все они имеют одинаковое измерение. Как только вы это сделаете, вы сможете использовать np.nanmin и np.nanmax для вычисления минимального и максимального значений при отбрасывании np.nan значений. В целом код выглядит так:

 import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from numpy import arange

#%% Creating X and Y example values
XTest1=list(range(0,40))
YTest1=np.empty(len(XTest1))
XTest2=list(range(10,40))
YTest2=np.empty(len(XTest2))
XTest3=list(range(2,40))
YTest3=np.empty(len(XTest3))
XTest4=list(range(5,38))
YTest4=np.empty(len(XTest4))
for i in range(len(XTest1)):
    YTest1[i]=math.sin(XTest1[i])
for i in range(len(XTest2)):
    YTest2[i]=3*math.sin(XTest2[i])
for i in range(len(XTest3)):
    YTest3[i]=2*math.sin(XTest3[i])-0.5
for i in range(len(XTest4)):
    YTest4[i]=0.5*math.sin(XTest4[i]) 1

plt.plot(XTest1,YTest1, label='Data 1')
plt.plot(XTest2,YTest2, label='Data 2')
plt.plot(XTest3,YTest3, label='Data 3')
plt.plot(XTest4,YTest4, label='Data 4')
plt.legend()
plt.show()
#%% Making a 4th order polynomial best fit graph through the data sets



def objective_4(x,a,b,c,d,e):
    return a * x**4  b*x**3  c*x**2 d*x e 
pars, cov = curve_fit(objective_4, XTest1,YTest1)
x_line1 = arange(min(XTest1), max(XTest1), 1)
a, b, c, d, e = pars
y_line1 = objective_4(x_line1, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest2,YTest2)
x_line2 = arange(min(XTest2), max(XTest2), 1)
a, b, c, d, e = pars
y_line2 = objective_4(x_line2, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest3,YTest3)
x_line3 = arange(min(XTest3), max(XTest3), 1)
a, b, c, d, e = pars
y_line3 = objective_4(x_line3, a, b, c, d, e)

pars, cov = curve_fit(objective_4, XTest4,YTest4)
x_line4 = arange(min(XTest4), max(XTest4), 1)
a, b, c, d, e = pars
y_line4 = objective_4(x_line4, a, b, c, d, e)

            
plt.plot(x_line1,y_line1, label='Test1')
plt.plot(x_line2,y_line2, label='Test2')
plt.plot(x_line3,y_line3, label='Test3')
plt.plot(x_line4,y_line4, label='Test4')

######## Padding start #######
min_x=min(XTest1[0],XTest2[0],XTest3[0],XTest4[0])
max_x=max(XTest1[-1],XTest2[-1],XTest3[-1],XTest4[-1])
x=np.arange(min_x,max_x)
y_line1_pad=(XTest1[0]-min_x)*[np.nan] list(y_line1) (max_x-XTest1[-1])*[np.nan]
y_line2_pad=(XTest2[0]-min_x)*[np.nan] list(y_line2) (max_x-XTest2[-1])*[np.nan]
y_line3_pad=(XTest3[0]-min_x)*[np.nan] list(y_line3) (max_x-XTest3[-1])*[np.nan]
y_line4_pad=(XTest4[0]-min_x)*[np.nan] list(y_line4) (max_x-XTest4[-1])*[np.nan]
y_line_pad_all=np.array([y_line1_pad,y_line2_pad,y_line3_pad,y_line4_pad])

####### Compute min and max ######
min_y=np.nanmin(y_line_pad_all,axis=0)
max_y=np.nanmax(y_line_pad_all,axis=0)

####### PLot min and max ######
plt.plot(x,min_y,color='r',ls='--',lw=2,label='min')
plt.plot(x,max_y,color='b',ls='--',lw=2,label='max')

plt.legend()
plt.show()
 

И результат дает:

введите описание изображения здесь