import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import math
na = 400
ma = [2, 1]
Sa = [[3, -2], [-2, 3]]
sigma1 = [3, 3]
nb = 400
mb = [8, 6]
Sb = [[3, -2], [-2, 3]]
xa, ya = np.random.multivariate_normal(ma, Sa, na).T
xb, yb = np.random.multivariate_normal(mb, Sb, nb).T
plt.plot(xa, ya, 'x')
plt.plot(xb, yb, 'x')
plt.axis('equal')
plt.show()
I have randomly generated data from 2-dimensional Gaussian Distributions and need to project this on w=[0, 1] and plot the histogram. I tried using plt.hist but it does not allow the multiplication.
Below links may be useful for learning numpy.
https://docs.scipy.org/doc/numpy-1.15.0/user/basics.creation.html
https://jakevdp.github.io/PythonDataScienceHandbook/02.02-the-basics-of-numpy-arrays.html
I think what you are asking is the below:
w = np.array([2,1])
a = np.array([xa,ya]).T
b = np.array([xb,yb]).T
aw = np.dot(a,w)
bw = np.dot(b,w)
plt.figure(0)
plt.hist(aw,label='a',histtype='step')
plt.hist(bw,label='b',histtype='step')
plt.title('projected')
plt.legend()
Related
I want to correlate geometry of surfaces with the target variable. In tutorials on scikit learn or tensorflow and so on some routine features are evaluated. For example relation between price of house in Boston with some other features like numbers of rooms, neighborhood and so on.
In my work I have some coordinates in 3D space (x, y and z) representing surfaces. Then, I want to find out how the arrangement of this points can affect the target variable. I very much appreciate if anyone can propose me maybe especial types of ML methods in python that can do so. I have uploaded a view on two simple surfaces created. Then, I want to correlate depth (z values) of surfaces with an arbitrary target. For each surface I may have hundreds of points i.e. z values.
Follwong code makes the fig:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.ticker import (AutoMinorLocator, MultipleLocator)
%matplotlib qt5
x_s_up = np.array([[1, 1, 1], [2, 2, 2]])
y_s_up = np.array([[1, 2, 3], [1, 2, 3]])
z_s_up = np.array([[5, 5, 5], [5.1, 5.2, 5.1]])
x_s_d = np.array([[1, 1, 1], [2, 2, 2]])
y_s_d = np.array([[1, 2, 3], [1, 2, 3]])
z_s_d = np.array([[3.9, 4., 3.8], [4.1, 4.1, 4.2]])
fig = plt.figure()
ax = fig.add_subplot (111, projection="3d")
ax.plot_surface(x_s_up, y_s_up, z_s_up, color='b') # upper surface
ax.plot_surface(x_s_d, y_s_d, z_s_d, color='r') # lower surface
ax.set_xlabel('X'); ax.set_ylabel('Y'); ax.set_zlabel('Z')
I have something similar to this problem respectivly the answer of this problem: RBF interpolation: LinAlgError: singular matrix
But I want to do the probability distribution with rbf.
My code until now:
from scipy.interpolate.rbf import Rbf # radial basis functions
import cv2
import matplotlib.pyplot as plt
import numpy as np
x = [1, 1, 2 ,3, 4, 4, 2, 6, 7]
y = [0, 2, 5, 6, 2, 4, 1, 5, 2]
rbf_adj = Rbf(x, y, function='gaussian')
plt.figure()
# Plotting the original points.
plot3 = plt.plot(x, y, 'ko', markersize=12) # the original points.
plt.show()
My problem is I have only coordinates of the points: x, y
But what can i use for z and d?
This is my error message:
numpy.linalg.linalg.LinAlgError: Matrix is singular.
This is, first, a 1D example to emphasis the difference between the Radial Basis Function interpolation and the Kernel Density Estimation of a probability distribution:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
from scipy.interpolate.rbf import Rbf # radial basis functions
from scipy.stats import gaussian_kde
coords = np.linspace(0, 2, 7)
values = np.ones_like(coords)
x_fine = np.linspace(-1, 3, 101)
rbf_interpolation = Rbf(coords, values, function='gaussian')
interpolated_y = rbf_interpolation(x_fine)
kernel_density_estimation = gaussian_kde(coords)
plt.figure()
plt.plot(coords, values, 'ko', markersize=12)
plt.plot(x_fine, interpolated_y, '-r', label='RBF Gaussian interpolation')
plt.plot(x_fine, kernel_density_estimation(x_fine), '-b', label='kernel density estimation')
plt.legend(); plt.xlabel('x')
plt.show()
And this is the 2D interpolation using Gaussian RBF for the provided data, and by setting arbitrarily the values to z=1:
from scipy.interpolate.rbf import Rbf # radial basis functions
import matplotlib.pyplot as plt
import numpy as np
x = [1, 1, 2 ,3, 4, 4, 2, 6, 7]
y = [0, 2, 5, 6, 2, 4, 1, 5, 2]
z = [1]*len(x)
rbf_adj = Rbf(x, y, z, function='gaussian')
x_fine = np.linspace(0, 8, 81)
y_fine = np.linspace(0, 8, 82)
x_grid, y_grid = np.meshgrid(x_fine, y_fine)
z_grid = rbf_adj(x_grid.ravel(), y_grid.ravel()).reshape(x_grid.shape)
plt.pcolor(x_fine, y_fine, z_grid);
plt.plot(x, y, 'ok');
plt.xlabel('x'); plt.ylabel('y'); plt.colorbar();
plt.title('RBF Gaussian interpolation');
I found a piece of code which is passing a 1D Numpy array to MatplotLib. The values of array are either 1 or 0, but the graph plotted has colours as yellow or purple. I am unable to find any documentation around it.
Here is the code:
import numpy as np
import matplotlib.pyplot as plt
num_observations = 5000
x1 = np.random.multivariate_normal([0, 0], [[1, .85],[.85, 1]], num_observations) # mean, covariance
x2 = np.random.multivariate_normal([1, 4], [[1, .85],[.85, 1]], num_observations)
features = np.vstack((x1, x2)).astype(np.float32)
labels = np.hstack((np.zeros(num_observations),np.ones(num_observations)))
plt.figure(figsize=(12,8))
plt.scatter(features[:, 0], features[:, 1],
c = labels, alpha = .4)
plt.show()
Can anyone explain how we are getting the colors as yellow and violet? Relevant Documentation would also help.
Its using the default viridis colormap, and so purple represents 0 and yellow represents 1. See here for more about colormaps: https://matplotlib.org/examples/color/colormaps_reference.html.
Adding a colorbar helps here. Adding one to your example is easy:
import numpy as np
import matplotlib.pyplot as plt
num_observations = 5000
x1 = np.random.multivariate_normal([0, 0], [[1, .85],[.85, 1]], num_observations) # mean, covariance
x2 = np.random.multivariate_normal([1, 4], [[1, .85],[.85, 1]], num_observations)
features = np.vstack((x1, x2)).astype(np.float32)
labels = np.hstack((np.zeros(num_observations),np.ones(num_observations)))
plt.figure(figsize=(12,8))
p = plt.scatter(features[:, 0], features[:, 1],
c = labels, alpha = .4)
plt.colorbar(p)
plt.show()
I'm trying to make a Voronoi plot update in real time as the generating points change position.
My problem is how to reuse the same figure, since currently I get a new window each time I call voronoi_plot_2d.
See code:
#!/usr/bin/env python
import numpy as np
import time
from scipy.spatial import Voronoi, voronoi_plot_2d
import matplotlib.pyplot as plt
plt.ion()
(x,y) = (1,2)
plt.show()
while True:
print "loop "
x += 0.1
y += 0.1
points = np.array([[0, 0], [1, 3], [0, 2.5], [x,y], [4, 1], [6, 4]])
vor = Voronoi(points)
apa = voronoi_plot_2d(vor)
time.sleep(0.5)
I got some ideas for this from
http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.spatial.Voronoi.html
real-time plotting in while loop with matplotlib
The code in the guide can be used to acheive this.
http://docs.scipy.org/doc/scipy/reference/tutorial/spatial.html
I haven't yet had time to read through and understand all the code, but it "manually" does what I want and it works.
Instead of using
voronoi_plot_2d(vor)
It step by step uses the different parts of vor to plot the voronoi plot, and this can be repeated in the loop. Full code example below:
#!/usr/bin/env python
import numpy as np
import time
from scipy.spatial import Voronoi, voronoi_plot_2d
import matplotlib.pyplot as plt
plt.ion()
(x,y) = (1,2)
plt.draw()
while True:
print "loop "
x += 0.1
y += 0.1
points = np.array([[0, 0], [1, 3], [0, 2.5], [x,y], [4, 1], [6, 4]])
plt.clf()
vor = Voronoi(points)
####MANUAL PLOTTING
plt.plot(points[:,0], points[:,1], 'o')
plt.plot(vor.vertices[:,0], vor.vertices[:,1], '*')
plt.xlim(-1, 3); plt.ylim(-1, 3)
for simplex in vor.ridge_vertices:
simplex = np.asarray(simplex)
if np.all(simplex >= 0):
plt.plot(vor.vertices[simplex,0], vor.vertices[simplex,1], 'k-')
center = points.mean(axis=0)
for pointidx, simplex in zip(vor.ridge_points, vor.ridge_vertices):
simplex = np.asarray(simplex)
if np.any(simplex < 0):
i = simplex[simplex >= 0][0] # finite end Voronoi vertex
t = points[pointidx[1]] - points[pointidx[0]] # tangent
t /= np.linalg.norm(t)
n = np.array([-t[1], t[0]]) # normal
midpoint = points[pointidx].mean(axis=0)
far_point = vor.vertices[i] + np.sign(np.dot(midpoint - center, n)) * n * 100
plt.plot([vor.vertices[i,0], far_point[0]], [vor.vertices[i,1], far_point[1]], 'k--')
plt.draw()
time.sleep(0.5)
I have this problem. I try to triangulate points cloud by scipy.spatial.Delaunay. I used:
tri = Delaunay(points) # points: np.array() of 3d points
indices = tri.simplices
vertices = points[indices]
But, this code return tetrahedron. How is it possible return triangle of surface only?
Thanks
To get it to work as in code form, you have to parametrize the surface to 2D. For example in the case of ball (r,theta, psi), radius is constant (drop it out) and points are given by (theta,psi) which is 2D.
Scipy Delaunay is N-dimensional triangulation, so if you give 3D points it returns 3D objects. Give it 2D points and it returns 2D objects.
Below is a script that I used to create polyhedra for openSCAD. U and V are my parametrization (x and y) and these are the coordinates that I give to Delaunay. Note that now the "Delaunay triangulation properties" apply only in u,v coordinates (angles are maximized in uv -space not xyz -space, etc).
The example is a modified copy from http://matplotlib.org/1.3.1/mpl_toolkits/mplot3d/tutorial.html which originally uses Triangulation function (maps to Delaunay eventually?)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.tri as mtri
from scipy.spatial import Delaunay
# u, v are parameterisation variables
u = np.array([0,0,0.5,1,1])
v = np.array([0,1,0.5,0,1])
x = u
y = v
z = np.array([0,0,1,0,0])
# Triangulate parameter space to determine the triangles
#tri = mtri.Triangulation(u, v)
tri = Delaunay(np.array([u,v]).T)
print 'polyhedron(faces = ['
#for vert in tri.triangles:
for vert in tri.simplices:
print '[%d,%d,%d],' % (vert[0],vert[1],vert[2]),
print '], points = ['
for i in range(x.shape[0]):
print '[%f,%f,%f],' % (x[i], y[i], z[i]),
print ']);'
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
# The triangles in parameter space determine which x, y, z points are
# connected by an edge
#ax.plot_trisurf(x, y, z, triangles=tri.triangles, cmap=plt.cm.Spectral)
ax.plot_trisurf(x, y, z, triangles=tri.simplices, cmap=plt.cm.Spectral)
plt.show()
Below is the (slightly more structured) text output:
polyhedron(
faces = [[2,1,0], [3,2,0], [4,2,3], [2,4,1], ],
points = [[0.000000,0.000000,0.000000],
[0.000000,1.000000,0.000000],
[0.500000,0.500000,1.000000],
[1.000000,0.000000,0.000000],
[1.000000,1.000000,0.000000], ]);
It looks like you want to compute the convex hull of your point cloud. I think this is what you want to do:
from scipy.spatial import ConvexHull
hull = ConvexHull(points)
indices = hull.simplices
vertices = points[indices]
Following Jaime's answer, but elaborating a bit more with an example:
import matplotlib as mpl
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as a3
import numpy as np
import scipy as sp
from scipy import spatial as sp_spatial
def icosahedron():
h = 0.5*(1+np.sqrt(5))
p1 = np.array([[0, 1, h], [0, 1, -h], [0, -1, h], [0, -1, -h]])
p2 = p1[:, [1, 2, 0]]
p3 = p1[:, [2, 0, 1]]
return np.vstack((p1, p2, p3))
def cube():
points = np.array([
[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1],
[1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1],
])
return points
points = icosahedron()
# points = cube()
hull = sp_spatial.ConvexHull(points)
indices = hull.simplices
faces = points[indices]
print('area: ', hull.area)
print('volume: ', hull.volume)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.dist = 30
ax.azim = -140
ax.set_xlim([0, 2])
ax.set_ylim([0, 2])
ax.set_zlim([0, 2])
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
for f in faces:
face = a3.art3d.Poly3DCollection([f])
face.set_color(mpl.colors.rgb2hex(sp.rand(3)))
face.set_edgecolor('k')
face.set_alpha(0.5)
ax.add_collection3d(face)
plt.show()
Which should depict the following figure: