-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfind_y_given_x.py
More file actions
132 lines (75 loc) · 3.62 KB
/
Copy pathfind_y_given_x.py
File metadata and controls
132 lines (75 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'''
This program will produce accurate restricted polynomial fitting for the data inputted. This program will find the y value for a given x value of a graph.
'''
import numpy.polynomial.polynomial as poly
import sys
import numpy as np
import matplotlib.pyplot as plt
import time
import math
from matplotlib.colors import LogNorm
import matplotlib.colors as colors
import scipy
from scipy import stats
from matplotlib.pyplot import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.ticker import AutoMinorLocator
import pandas as pd
import scipy.ndimage
import warnings
warnings.simplefilter('ignore', np.RankWarning)
def progress(count, total, status=''):
bar_len = 60
filled_len = int(round(bar_len * count / float(total)))
percents = round(100.0 * count / float(total), 1)
bar = '=' * filled_len + '-' * (bar_len - filled_len)
sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', status))
sys.stdout.flush()
#function finding the y value corresponding to an x value based on fitting parameters
def f_individual_value(x,COEFS,DEG):
ret2=0
for count2 in range(len(COEFS)):
ret2+=COEFS[count2]*(x**(DEG))
DEG-=1
return ret2
#input array of y_values
y_values=[...]
#input array of x_values
x_values=[...]
#fill the gaps in the data distribution for better approximation of the fitting parameters(recommended)
y_values= scipy.ndimage.zoom(y_values, 40)
x_values = scipy.ndimage.zoom(x_values, 40)
#create a pandas data frame with the arrays
Dframe=pd.DataFrame({'y_values': y_values, 'x_values': x_values })
#order the arrays in the data frame
dataframe = Dframe[['y_values','x_values']]
#the degree of the polynomial fitting (recommended deg=12)
deg=12
#the x value corresponding to the y value to be found
x_value=float(input("Enter x value: "))
#y range decrease percentage (the lower the more accurate the result will be at the cost of the program being slower)
percentage=0.001
#calculate the maximum and minimum x and y values
y_max=np.array(dataframe)[:,0].max()
y_min=np.array(dataframe)[:,0].min()
x_max=np.array(dataframe)[:,1].max()
x_min=np.array(dataframe)[:,1].min()
#calculate the fitting parameters of the first iteration
coefs=np.polyfit(np.array(dataframe)[:,1],np.array(dataframe)[:,0], deg)
#calculate the y value corresponding to the x value inputted from the first fitting y range
y_value=f_individual_value(x_value,coefs,deg)
#calculate the value by which the fitting y range decreases each loop
decreasing_step=-percentage*(y_max-y_min)
percentageX=0.05
x_length=percentageX*abs(x_max-x_min)
progress_control=0
for y_length in np.arange(y_max,y_min,decreasing_step):
#creating a data frame for the new y range of y and x values with the central y value being the one found in the previous iteration and the central x value between x_value-x_length and x_value+x_length
dataframe_filtered=dataframe[(dataframe.y_values > y_value-y_length) & (dataframe.y_values < y_value+y_length) & (dataframe.x_values > x_value-x_length) & (dataframe.x_values < x_value+x_length)].values
if len(dataframe_filtered)==0:
break
else:
#calculate the new fitting parameters and find the new y value
new_coefs=np.polyfit(np.array(dataframe_filtered)[:,1],np.array(dataframe_filtered)[:,0], deg)
y_value=f_individual_value(x_value,new_coefs,deg)
print('The y value corresponding to x = '+str(x_value)+' is y = '+str(y_value))