0

I have an excel file witch contains a data set of velocity. using these libraries :

from xlrd import open_workbook
import matplotlib.pyplot as plt
import statistics
import numpy as np

after reading files of excel we have the 3 list. for example:

t=[0.02,0.6,0.01,0.14,0.18,0.22,0.26,0.3,0.34,0.38,0.42,0.46,0.5,0.54]
Vx=[-22.67,-20.74,-15.42,-17.83,-9.17,-7.1,-14.74,-11.84,-10.54,-18.4,-10.31,-6.84,-15.45,-4.81]
Vy=[6.9,7.99,-3.8,9.62,8.49,-3.55,-6.45,0.48,6.54,-1.13,-5.74,-2.45,2.63,-4.71]

in next steps we need the mean and these numbers as an array :

u = np.array(Vx)
V = np.array(Vy)
ubar,vbar=round(statistics.mean(Vx),3),round(statistics.mean(Vy),3)

after that other form of vectors are required. u' and v' with these formula :

uprime = [i-ubar for i in Vx]
vprime = [i-vbar for i in Vy]

now after some other formula and calculations we have major and minor axes of an ellipse : for example :

x0=16.69
y0=21.22

the whole ellipse has a rotation showing by theta. for example :

theta = -0.25  #rad

now i want to plot this datasets (u'-v') by scatter form and the ellipse on it. i have plotted the scatter :

plt.scatter(uprime,vprime,marker=".")
plt.xlabel("u'")
plt.ylabel("v'")
plt.show()

but i can't plot the ellipse and its rotation. after that i must find the datas out of the llipsoid to find them as spikes. somthing like the picture below. how can i do that?(the main dataset is near to 1300 datas and here is just a summary)

example plot

Sam Mason
  • 15,216
  • 1
  • 41
  • 60

1 Answers1

0

to break this down, when drawing an ellipse you basically sample some points on it and draw lines between these points (computers are good at drawing straight lines, almost everything is is transformed into them). you can either do the trig yourself, or use the Ellipse patch built into matplotlib to do this. in your case it's probably easiest to use the helper, but if you're doing anything more complicated then doing it yourself tends to be the only option

in your case, you'd make an Ellipse patch (patches are the primitive graphics objects in matplotlib) and add it to the relevant axes, e.g:

from matplotlib import patches

el = patches.Ellipse([0,0], x0, y0, theta * 180 / np.pi, fill=False)
plt.gca().add_patch(el)

the angle is in degrees to be annoying!

to draw your "spikes", I presume you just want to find every point that isn't in the ellipse. to do this I'd transform the space such that the ellipse is a unit circle, you can then do a simple test to see if points are within this or not. see here for some other ways of doing this. for example:

sx = uprime * np.cos(-theta) - vprime * np.sin(-theta)
sy = vprime * np.cos(-theta) + uprime * np.sin(-theta)
sx /= x0
sy /= y0

ii = np.where(np.sqrt(sx ** 2 + sy ** 2) > 0.5)

this leaves ii as the indices of the points that are "outside" the circle, which than then be plotted with:

plt.scatter(uprime[ii], vprime[ii], s=50, facecolors='none', edgecolors='r')

note that your use of numpy is somewhat non-idiomatic, I'd suggest looking into how it uses broadcasting to make things easier, e.g. you code at the top could become:

uprime = u - np.round(u.mean(), 3)
vprime = V - np.round(V.mean(), 3)

and would be much more efficient if you have large amounts of data

Sam Mason
  • 15,216
  • 1
  • 41
  • 60
  • thank you very much the first part was ok. but the second part for calculating the dataset out of ellipse (sx & sy) i goft this error : TypeError: can't multiply sequence by non-int of type 'numpy.float64' –  Jul 20 '19 at 13:42
  • Oops, the code assumes uprime and vprime are numpy arrays, try running the lines at the bottom first. I wrote them first, and hence it just worked for me – Sam Mason Jul 20 '19 at 13:57