python 3.x - How to plot a sphere when we are given a central point and a radius size? -
i have got matrix [[1, 2, 2.23], [2, 3, 3.6],[-3, 4, 5], ...] , each row indicates point.
what wish this:
want create function given 2 parameters :
center [0,0,0] , matrix above.
calculates maximum distance of points center radius of sphere , draw sphere along points in matrix.
sphere transparent, if plot points, can see points inside sphere.
need differentiate point maximum distance in way. draw vector center point or draw different color. appreciated.
based on this answer:
import matplotlib.pyplot plt mpl_toolkits.mplot3d import axes3d matplotlib.patches import fancyarrowpatch mpl_toolkits.mplot3d import proj3d import numpy np # interactive mode off, can [normally] safely removed plt.ioff() # define arrow class: class arrow3d(fancyarrowpatch): def __init__(self, start=[0,0,0], end=[1,1,1], *args, **kwargs): if "arrowstyle" not in kwargs: kwargs["arrowstyle"] = "-|>" if "mutation_scale" not in kwargs: kwargs["mutation_scale"] = 20 if "color" not in kwargs: kwargs["color"] = "k" fancyarrowpatch.__init__(self, (0,0), (0,0), *args, **kwargs) xs = [start[0], end[0]] ys = [start[1], end[1]] zs = [start[2], end[2]] self._verts3d = xs, ys, zs def draw(self, renderer): xs3d, ys3d, zs3d = self._verts3d xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.m) self.set_positions((xs[0],ys[0]),(xs[1],ys[1])) fancyarrowpatch.draw(self, renderer) def wireframesphere(centre=[0.,0.,0.], radius=1., n_meridians=20, n_circles_latitude=none): """ create arrays of values plot wireframe of sphere. parameters ---------- centre: array point, defined iterable of 3 numerical values. radius: number radius of sphere. n_meridians: int number of meridians display (circles pass on both poles). n_circles_latitude: int number of horizontal circles (akin equator) display. notice includes 1 each pole, , defaults 4 or half of *n_meridians* if latter larger. returns ------- sphere_x, sphere_y, sphere_z: arrays arrays coordinates of points make wireframe. shape (n_meridians, n_circles_latitude). examples -------- >>> fig = plt.figure() >>> ax = fig.gca(projection='3d') >>> ax.set_aspect("equal") >>> sphere = ax.plot_wireframe(*wireframesphere(), color="r", alpha=0.5) >>> fig.show() >>> fig = plt.figure() >>> ax = fig.gca(projection='3d') >>> ax.set_aspect("equal") >>> frame_xs, frame_ys, frame_zs = wireframesphere() >>> sphere = ax.plot_wireframe(frame_xs, frame_ys, frame_zs, color="r", alpha=0.5) >>> fig.show() """ if n_circles_latitude none: n_circles_latitude = max(n_meridians/2, 4) u, v = np.mgrid[0:2*np.pi:n_meridians*1j, 0:np.pi:n_circles_latitude*1j] sphere_x = centre[0] + radius * np.cos(u) * np.sin(v) sphere_y = centre[1] + radius * np.sin(u) * np.sin(v) sphere_z = centre[2] + radius * np.cos(v) return sphere_x, sphere_y, sphere_z def find_most_distants(points, center=[0.,0.,0.], tol=1e-5): """ finds , returns list of points distante ones center. parameters ---------- points: list list of points (see center know point is) center: array point, defined iterable of 3 numerical values. """ # make central point array ease vector calculations center = np.asarray(center) # find distant points max_distance = 0 most_distant_points = [] point in points: distance = np.linalg.norm(center-point) if abs(distance - max_distance) <= tol: most_distant_points.append(point) elif distance > max_distance: most_distant_points = [point] max_distance = distance return max_distance, most_distant_points def list_of_points_to_lists_of_coordinates(list_of_points): """ converts list of points lists of coordinates of points. parameter --------- list_of_points: list list of points (each defined iterable of 3 numerical values) returns ------- points_x, points_y, points_z: array lists of coordinates """ points_x = [] points_y = [] points_z = [] point in list_of_points: points_x.append(point[0]) points_y.append(point[1]) points_z.append(point[2]) return points_x, points_y, points_z def function(central_point=[0.,0.,0.], other_points=[[1., 2., 2.23], [2., 3., 3.6], [-3., 4., 5.]],): """ draws wireframe sphere centered on central_point , containing points in other_points list. draws points inside sphere , marks distant ones arrow. parameters ---------- central_point: array point, defined iterable of 3 numerical values. other_points: list list of points (see central_point know point is) """ # find distant points max_distance, most_distant_points = find_most_distants(other_points, central_point) #prepare figure , 3d axis fig = plt.figure() ax = fig.gca(projection='3d') ax.set_aspect("equal") #draw sphere ax.plot_wireframe(*wireframesphere(central_point, max_distance), color="r", alpha=0.5) # draw points ax.scatter(*list_of_points_to_lists_of_coordinates(other_points)) # draw arrows distant points: extreme_point in most_distant_points: ax.add_artist(arrow3d(start=central_point, end=extreme_point)) fig.show() if __name__ == '__main__': function([0,0,0], 2*np.random.rand(50,3)-1) # make list equally distant point: repeated_max_list = 2*np.random.rand(10,3)-1 distance, points = find_most_distants(repeated_max_list) repeated_max_list = np.concatenate((repeated_max_list,points)) repeated_max_list[-1][0] = -repeated_max_list[-1][0] repeated_max_list[-1][1] = -repeated_max_list[-1][1] repeated_max_list[-1][2] = -repeated_max_list[-1][2] function([0,0,0], repeated_max_list)
Comments
Post a Comment