How can I find an angle of rotated geometry? - python-3.x

I have 2d geometry and corresponding X and Y coordinates. How can find the rotation angle (in degree) of geometry with respect to X or Y axis? Suggestions will always be welcomed.
X = [0.71, 1.41, 2.12, 2.83, 2.12, 2.83, 3.54, 4.24, 4.95, 5.66, 4.95, 4.24, 3.54, 2.83, 2.12, 1.41]
Y = [-0.71, 0.0, 0.71, 1.41, 2.12, 2.83, 2.12, 1.41, 0.71, 0.0, -0.71, 0.0, 0.71, 0.0, -0.71, -1.41]
I have mentioned coordinates as above. My aim is to align the geometry's principal axis to the X or Y coordinates.

In order to find a principal axis, I have applied Principal Componenet Analysis (PCA).
I created a dataframe of X and Y coordinate. Then,
First I centered the geometry considering the mean of X and Y coordinate.
data_centered1 = df_1.apply(lambda x: x-x.mean())
data_centered1
Then I separated a list of X and Y coordinate (after centering) to two different list.
Then to apply PCA, I followed these steps,
(1) compute covariance matrix
def create_covariance_matrix(data_matrix):
n = data_matrix.shape[0]
cov_matrix = (1 / (n - 1)) * np.dot(data_matrix.T, data_matrix)
return cov_matrix
cov_matrix = create_covariance_matrix(first_coord)
(2) Compute eigenvalues and eigenvectors from covariance matrix
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
(3) find the angle of first principal component
alpha = np.degrees(np.arctan(eigenvectors[1][1]/eigenvectors[0][1]))
beta = 90-alpha
(4) visulize a plot with original geometry with principal component
plt.scatter(X1_coordinate, Y1_coordinate)
plt.plot([0, eigenvectors[0][1]], [0, eigenvectors[1][1]], marker = 'o')
plt.show()
(5) Rotate all points of geometry with the angle obtained from eigenvectors (either alpha or beta). It will rotate the geometry such that geometry's principal axis aligned with global reference system axis.
I followed these steps and it works fine!!

Related

Scipy Optimize Minimize - Syntax for function with array of arguments, and input fixed vector

getting some difficulty in setting up my scipy.optimize minimize function.
I thought I had set-it-up correctly, but my internal results just looks strange.
Basically, I have this function (vol_function), which depends on 6 parameters
I have two vectors,
one vector x which is an array of values calculated from vol_function
one vector y, which is an array of target values
I want to 'calibrate' 3 params out of 6 from this vol_function, which will make the absolute difference between vector x and vector y minimized.
Vector x is the 'volcurve_' in the example below. Vector y is the 'targets' in the example below.
Am I setting the scipy minimize correctly? Help!!! Below is the format of my code.
vol_function(strike, fwd, time, alpha, beta, rho, volvol):
.....
.....
return vol_
strikes = [-1.0, -0.8, -0.6, -0.2, 0.0, .... 0.6, 0.8, 1.0]
targets = [10.0, 9.0, 8.0, ......, 16.0, 18.0, 20.0]
calib_(strikes, targets, fwd, time):
volcurve_ = []
for strike_ in strikes:
vol_ = vol_function(strike_, fwd, time, alpha, beta, rho, volvol)
volcurve_.append(vol_)
return np.sum((volcurve_ - targets)**2)
x0 = np.array([alpha, beta, rho, volvol])
bounds = [(0.0001, None), (0.001, 0.9999), (-0.9999, +0.99999), (0.00001, None)]
res = minimize(calib_, x0, method = 'L-BFGS-B', bounds = bounds)

How to generate "triangles" parameter of Mayavi triangular_mesh using triangles which are known vertices coordinates

I have triangles which construct surface of sphere. I want to draw the surface using mayavi triangular_mesh function. The function has "triangles" parameter which is list of triplets (or an array) list the vertices in each triangle. I know vertices coordinate all of triangles. But I don't know how to generate this parameter.
I also tried to generate "triangles" parameter using matplotlib Triangulation function (triangles = matplotlib.tri.Triangulation(longitudes, latitudes).triangles). However, in some places of surface, the triangles are connected incorrectly (can be seen Figure 1).
Figure 1. Incorrect connection of triangles
How to generate "triangles" parameter of Mayavi triangular_mesh using triangles which are known vertices coordinates
Data Format
x, y and z are Cartesian coordinate of triangles. For example; (x[0], y[0], z[0]), (x[1], y[1], z[1]) and (x[2], y[2], z[2]) are vertices of a triangle. Next triangle has (x[3], y[3], z[3]), (x[4], y[4], z[4]) and (x[5], y[5], z[5]) vertices coordinate.
You just need to put it together using the indices.
Take a look at the shape of triangles.
It has three indices per triangle that is used
on x, y and z.
import numpy as np
import mayavi.mlab as mlab
x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
s = np.random.rand(30)
triangles = np.random.randint(0, 30, size=(10, 3))
print(triangles)
mlab.triangular_mesh(x, y, z, triangles, scalars=s)
mlab.orientation_axes()
mlab.show()

It's related to ROC curve

I have no problem in plotting the ROC curve and it also gets plotted as per my requirement, but the problem I am facing is in (ylim axes) it starts from 0.1 to 1.05, and it plots only even numbers (0.0 0.2 0.4...1.05), but I want to extend the ylim axes (for eg. 0.0 0.1 0.2 0.3...1.05). I want a code which includes both even and odd number while plotting ROC curve.
I searched in matplotlib but I didn't find anything related to my problem.
lw = 2
plt.figure()
plt.plot(fpr11, tpr11, 'o-', ms=2, label='ROC_curve_APOE(AUC11 = %0.4f)'
% roc_auc11, color='deeppink', linestyle=':', linewidth=2)
plt.plot(fpr51, tpr51, 'o-', ms=2, label='ROC_curve_Combined AUC5 =
%0.4f)' % roc_auc51, color='cornflowerblue', linestyle=':', linewidth=2)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0, 1])
plt.ylim([0, 1.05])
plt.xlabel('1-Specificity(False Positive Rate)')
plt.ylabel('Sensitivity(True Positive Rate)')
# plt.title('ROC curve for MCIc vs MCIs')
plt.title('ROC curve for AD vs NC')
plt.legend(loc="lower right")
plt.show()
# plt.savefig('roc_auc.png')
plt.close()
My expected output must be the same as over here https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/#roc_curve_for_binary_svm
You can see in this figure that ylim has plotted every point from (0.0 0.1 ....up to 1).
Please help me solve it.
Not sure if you can set steps in ylim/xlim but you can use xticks/yticks instead
def frange(x, y, jump):
while x < y:
yield x
x += jump
yield y
plt.yticks(list(frange(0, 1.05, 0.1)))
How you choose to replace the frange is up to you, but you can also do something like
plt.yticks([0, 0.1, 0.2, 0.3, 0.4,....,1.0, 1.05])

How to visualize feasible region for linear programming (with arbitrary inequalities) in Numpy/MatplotLib?

I need to implement a solver for linear programming problems. All of the restrictions are <= ones such as
5x + 10y <= 10
There can be an arbitrary amount of these restrictions. Also , x>=0 y>=0 implicitly.
I need to find the optimal solutions(max) and show the feasible region in matplotlib. I've found the optimal solution by implementing the simplex method but I can't figure out how to draw the graph.
Some approaches I've found:
This link finds the minimum of the y points from each function and uses plt.fillBetween() to draw the region. But it doesn't work when I change the order of the equations. I'm not sure which y values to minimize(). So I can't use it for arbitrary restrictions.
Find solution for every pair of restrictions and draw a polygon. Not efficient.
An easier approach might be to have matplotlib compute the feasible region on its own (with you only providing the constraints) and then simply overlay the "constraint" lines on top.
# plot the feasible region
d = np.linspace(-2,16,300)
x,y = np.meshgrid(d,d)
plt.imshow( ((y>=2) & (2*y<=25-x) & (4*y>=2*x-8) & (y<=2*x-5)).astype(int) ,
extent=(x.min(),x.max(),y.min(),y.max()),origin="lower", cmap="Greys", alpha = 0.3);
# plot the lines defining the constraints
x = np.linspace(0, 16, 2000)
# y >= 2
y1 = (x*0) + 2
# 2y <= 25 - x
y2 = (25-x)/2.0
# 4y >= 2x - 8
y3 = (2*x-8)/4.0
# y <= 2x - 5
y4 = 2 * x -5
# Make plot
plt.plot(x, 2*np.ones_like(y1))
plt.plot(x, y2, label=r'$2y\leq25-x$')
plt.plot(x, y3, label=r'$4y\geq 2x - 8$')
plt.plot(x, y4, label=r'$y\leq 2x-5$')
plt.xlim(0,16)
plt.ylim(0,11)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
This is a vertex enumeration problem. You can use the function lineqs which visualizes the system of inequalities A x >= b for any number of lines. The function will also display the vertices on which the graph was plotted.
The last 2 lines mean that x,y >=0
from intvalpy import lineqs
import numpy as np
A = -np.array([[5, 10],
[-1, 0],
[0, -1]])
b = -np.array([10, 0, 0])
lineqs(A, b, title='Solution', color='gray', alpha=0.5, s=10, size=(15,15), save=False, show=True)
Visual Solution Link

How to density based clustering for speed trajectories in a video?

I have a speed of feature points at every frame. Here I have 165 frames in a video where every frame contains speed of feature points.This is my data.
TrajDbscanData
array([[ 1. , 0.51935178],
[ 1. , 0.52063496],
[ 1. , 0.54598193],
...,
[165. , 0.47198981],
[165. , 2.2686042 ],
[165. , 0.79044946]])
where first index is frame number and second one is speed of a feature point at that frame.
Here I want to do density based clustering for different speed range. For this , I use following code.
import sklearn.cluster as sklc
core_samples, labels_db = sklc.dbscan(
TrajDbscanData, # array has to be (n_samples, n_features)
eps=0.5,
min_samples=15,
metric='euclidean',
algorithm='auto'
)
core_samples_mask = np.zeros_like(labels_db, dtype=bool)
core_samples_mask[core_samples] = True
unique_labels = set(labels_db)
n_clusters_ = len(unique_labels) - (1 if -1 in labels_db else 0)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
plt.figure(figcount)
figcount+=1
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = 'k'
class_member_mask = (labels_db == k)
xy = TrajDbscanData[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col, markeredgecolor='k', markersize=6)
xy = TrajDbscanData[class_member_mask & ~core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'x', markerfacecolor=col, markeredgecolor='k', markersize=4)
plt.rcParams["figure.figsize"] = (10,7)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.grid(True)
plt.show()
I got the following result.
Y axis is speed and x axis is frame number
I want to do density based clustering according to speed. for example speed upto 1.0 in one cluster , speed from 1 to 1.5 as outlier , speed from 1.5 to 2.0 another cluster and speed above 2.0 in another cluster. This helps to identify common motion pattern types. How can I do this ?
Don't use Euclidean distance.
Since your x and y a is have very different meaning, that is the wrong distance function to use.
Your plot is misleading, because the axes have different scale. If you would scale x and y the same way, you would understand what has been happening... The y axis is effectively ignored, and you slice the data by your discrete integer time axis.
You may need to use Generalized DBSCAN and treat time and value separately!

Resources