I have these randomly generated data:
import numpy as np
import pandas as pd
np.random.seed(42)
y1 = np.random.randint(5,10,5)
y2 = np.random.randint(15,20,5)
y3 = np.random.randint(5,10,5)
y = np.append(y1 , y2)
y = np.append(y , y3)
y_cum = y.cumsum()
df_test = pd.DataFrame({'x': range(len(y)), 'y_cum': y_cum, 'y': y})
if we plot these data we can see an "elbow" (at 4 in the x-axis) and a "knee" (at 9 in the x-axis)
import matplotlib.pyplot as plt
plt.plot(df_test['x'], df_test['y_cum'])
I am using from kneed import KneeLocator to detect them.
I use the following code to detect the elbow:
kneedle = KneeLocator(df_test['x'], df_test['y'], curve='convex', direction='increasing', online=False, S=1)
elbow_point = kneedle.elbow
elbow_point
and the following code to detect the knee:
kneedle = KneeLocator(df_test['x'], df_test['y'], curve='concave', direction='increasing', online=False, S=1)
elbow_point = kneedle.elbow
elbow_point
The first one gives as output 13 and the second gives as output 1, which are not the correct values
I am a bit lost why these values pop up. I have looked into the source code but I couldnt figure it out.
Any ideas ?
Related
I am trying to plot this data as a decaying exponential, all of the data has the same x values just the y values differ. y= a*[(-1)*exp(-x/t)].
I am not getting the correct chart when it goes through. csv file In the image is the type of curve I am looking for. I need to plot all of the data in csv (preferably on the same plot) in pycharm. I am relatively new to pycharm so I am starting from scratch! (excel just wouldn't behave for this data) Willing to start fresh as well if there is a simpler way of writing the code, I sparsed this together with some help from the internet.
import scipy.signal as scp
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import numpy.core.function_base
def decaying_exponential(x,a,t,c):
return a *(-1)* np.exp(-1 * (x) / t) + c
import os
for f in os.listdir("/Users/flyar/My Python Stuff/"):
print(f)
df = numpy.transpose(pd.read_csv("D:/Grad Lab/NMR/Data/T1 Data/mineral oil/F0009CH1.CSV", names= ['a','b','c','d']).to_numpy())
temp = scp.find_peaks(df[2], height = 0)
df_subset = [(df[1][n], df[2][n]) for n in temp[0]]
print(df_subset)
plt.scatter([df[2][n] for n in temp[0]], [df[1][n] for n in temp[0]])
y = np.linspace(min(df[2]), max(df[2]), 1000)
params, covs = curve_fit(decaying_exponential, [df[1][n] for n in temp[0][2::]],
[df[2][n] for n in temp[0][2::]], maxfev=10000)
print(params)
plt.plot(y, [decaying_exponential(l, 5, params[1], params[2]) for l in y])
plt.show()
I have constructed an interpolation code using rbf in python and following this tutorial. More precisely, the code displayed at 04:57.
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
import scipy
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
tokens_column_numberY = 1
tokens_column_numberF = 2
resulttokenX=[]
resulttokenY=[]
resulttokenF=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
resulttokenY.append(x.split()[tokens_column_numberY])
resulttokenF.append(x.split()[tokens_column_numberF])
token.close()
resulttokenX2 = np.array(resulttokenX)
resulttokenY2 = np.array(resulttokenY)
resulttokenF2 = np.array(resulttokenF)
newfunc=interpolate.Rbf(resulttokenX2.astype('float'), resulttokenY2.astype('float'), resulttokenF2.astype('float'), function='multiquadric')
xnew, ynew=np.mgrid[340:350:100j, 23:32:100j]
fnew=newfunc(xnew, ynew)
#create image plot
py.figure(1)
py.clf()
py.imshow(fnew, extent=[340, 350, 23, 32], cmap=py.cm.jet)
The code aboce is a sample of my program. And the result can be seen in this image
Unfortunately, I am doing something wrong. The resulting interpolation should look like a 90 degree turn of the previous image.
I have tried to alter the values of np.np.mgrid but I haven't found any combination which returns what I want. Note that I am working with latitudes and longitudes. I have 19 values of latitude and 21 of longitude in my original data.
Any idea on what might be going on?
In the end, I have managed to "fix" this by using a combination of flipped lists and changing the axis. This is the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
import scipy
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
tokens_column_numberY = 1
tokens_column_numberF = 2
resulttokenX=[]
resulttokenY=[]
resulttokenF=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
resulttokenY.append(x.split()[tokens_column_numberY])
resulttokenF.append(x.split()[tokens_column_numberF])
token.close()
resulttokenXflip=resulttokenX[::-1]
resulttokenYflip=resulttokenY[::-1]
resulttokenFflip=resulttokenF[::-1]
resulttokenX2 = np.array(resulttokenX)
resulttokenX2flip = np.array(resulttokenXflip)
resulttokenY2 = np.array(resulttokenY)
resulttokenY2flip = np.array(resulttokenYflip)
resulttokenF2 = np.array(resulttokenF)
resulttokenF2flip = np.array(resulttokenFflip)
#El error tiene que venir del hecho de que Y2 está definida de menor a mayor
len(resulttokenX2)
newfunc=scipy.interpolate.Rbf(resulttokenY2flip.astype('float'), resulttokenX2.astype('float'), resulttokenF2.astype('float'), function='linear')
xnew, ynew=np.mgrid[ 23:32:90j, 340:350:100j]
fnew=newfunc(xnew, ynew)
#create image plot
py.figure(1)
py.clf()
py.imshow(fnew, extent=[ 340, 350, 23,32], cmap=py.cm.jet)
import control
import numpy as np
import matplotlib.pyplot as plt
Ts = 1
G1 = control.tf([60], [1,0.1])
G2 = control.tf([0.5, 3], [1, 5, 12])
G3 = control.tf([1], [1, 5])
Gs= G1*G2*G3
Gz = control.c2d(Gs,Ts, method='tustin' )
print(Gz)
print(Gs)
cltf=(Gs/(1+Gs))
Zcltf=(Gz/(1+Gz))
T = np.arange(0, 15)
za = control.step_response(cltf, T)
Tout, y = control.step_response(cltf, T)
Tout, x = control.step_response(Zcltf, T)
plt.subplot(2,1,1)
plt.plot(Tout, y)
plt.subpolt(2,1,2)
plt.plot(Tout,y.Tout)
Hello everyone, this is my code. I am new to Python. And my step responses always look like this:This Graph
In Matlab I got those for the two step responses Like those
I couldn't figured it out what is the reason of it.
the time vector T need more points, if you do not put step use de default value. You can try whiht T = np.arange(0, 15,0.1).
on the other hand, if you dont use T in the function step_response calculate a time vector, but have some problems with some plants, for example, stiff plants.
try this:
Tout, y = control.step_response(cltf)
finaly, you never plot x (the digital step output), you can try use plt.step() in place of plt.plot() to stairs plot.
import control
import numpy as np
import matplotlib.pyplot as plt
Ts = 1
G1 = control.tf([60], [1,0.1])
G2 = control.tf([0.5, 3], [1, 5, 12])
G3 = control.tf([1], [1, 5])
Gs= G1*G2*G3
Gz = control.c2d(Gs,Ts, method='tustin' )
print(Gz)
print(Gs)
cltf=(Gs/(1+Gs))
Zcltf=(Gz/(1+Gz))
Tout1, y = control.step_response(cltf)
Tout2, x = control.step_response(Zcltf)
plt.plot(Tout1, y)
plt.figure()
plt.step(Tout2,x)
I'm quite new(ish) to python, so sorry if my syntax is basic or just downright bad.
I'm trying to create a simple 2D Line of Sight script where one point draws a line to all the other points using Matplotlib.
list of points in Matplotlib
Currently, I have a list of points, but I'm having trouble writing the For loop for it. My idea was to create a For loop to draw the lines from the origin to all the x,y coords as defined in positions, but it unfortunately doesn't work.
quality = 5
x = np.linspace(-1,1,quality)
y = np.linspace(-1,1,quality)
X,Y = np.meshgrid(x,y)
positions = np.vstack([Y.ravel(), X.ravel()])
plt.scatter(*positions[::-1])
plt.show()
origin = [0,0]
for i in range(len(positions)):
for j in range(len(positions[i])):
x1 = positions[0][j]
y1 = positions[1][j]
line = shapely.geometry.LineString([origin, [x1, y1]])
But when i run this script, all i get is this output.
What I'm trying to accomplish is something similar to the image below that I've done in another software.
points connect to all points
'shapely' is something I've never used before, but I've tried to recreate it by introducing a live riley, and I had to assign the coordinate information on shapely to a variable in matplotlib. The answer I was referring to is this.
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import LineString
quality = 5
x = np.linspace(-1,1,quality)
y = np.linspace(-1,1,quality)
X,Y = np.meshgrid(x,y)
positions = np.vstack([Y.ravel(), X.ravel()])
plt.scatter(*positions[::-1])
origin = (0, 0)
for i in range(len(positions)):
for j in range(len(positions[i])):
x1 = positions[0][j]
y1 = positions[1][j]
line = LineString([origin, (x1, y1)])
x2, y2 = line.xy
plt.plot(0, 0, x2, y2)
plt.show()
I have a function f(x,t) = cos(t)*t + x and i want to display the change of the result over the width x and time t at discretised time steps t_i and discretised width steps x_j.
Now I am a while here on SX and feel really embarrassed to only can post such little code or in other words nothing (since nothing worked I have done...):
Nevertheless if someone has the time to help, I`d appreciate it.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as pyplot
from astropy.io.ascii.latex import AASTex
def func(xi, ti):
res = np.cos(ti)*ti + xi
return res
timeSpacing = 100
timeStart = 0
timeEnd = 1
time = np.linspace(timeStart, timeEnd, timeSpacing)
widthSpacing = 300
widthStart = 0
widthEnd = 3
width = np.linspace(widthStart, widthEnd, widthSpacing)
resultList = [None]*timeSpacing
resultListInner = [None]*widthSpacing
for i, ithTime in enumerate(time):
for j, jthWidth in enumerate(width):
aas = np.zeros_like(width)
aas.fill(ithTime)
resultListInner[j] = ithTime, jthWidth, func(jthWidth, aas)
resultList[i] = resultListInner
So how do I correctly index the list and array and plot my data using matplotlib?
My plot should look like this:
where in my case the aperature should be the width x, the sky annulus is my time t and the RMS is my func(x,t).
A couple of points:
Numpy provides a very nice function for doing differences of array elements: diff
Matplotlib uses plot_wireframe for creating a plot that you would want (also using Numpy's meshgrid)
Now, combining these into what you may want would look something like this.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
def func(xi, ti):
res = np.cos(ti)*np.sin(xi)
return res
timeSpacing = 20
timeStart = 0
timeEnd = 1
time = np.linspace(timeStart, timeEnd, timeSpacing)
widthSpacing = 50
widthStart = 0
widthEnd = 3
width = np.linspace(widthStart, widthEnd, widthSpacing)
X,T = np.meshgrid(width,time)
F = func(X,T)
DF = np.diff(np.diff(F,axis=0),axis=1)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_wireframe(X[:-1,:-1],T[:-1,:-1],DF)
plt.show()
Note that diff is applied twice: once in each dimension axis= . I have also changed the toy function you provided to something that actually looks decent in this case.
For your more general use, it seems that you would want to just collect all of your F data into a 2D array, then proceed from the DF = line.