def _parametric_plot3d_surface(f, urange, vrange, plot_points, boundary_style, **kwds): r""" This function is used internally by the ``parametric_plot3d`` command. """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange,vrange], plot_points) urange = srange(*ranges[0], include_endpoint=True) vrange = srange(*ranges[1], include_endpoint=True) G = ParametricSurface(g, (urange, vrange), **kwds) if boundary_style is not None: for u in (urange[0], urange[-1]): G += line3d([(g[0](u,v), g[1](u,v), g[2](u,v)) for v in vrange], **boundary_style) for v in (vrange[0], vrange[-1]): G += line3d([(g[0](u,v), g[1](u,v), g[2](u,v)) for u in urange], **boundary_style) return G
def _parametric_plot3d_curve(f, urange, plot_points, **kwds): r""" This function is used internally by the ``parametric_plot3d`` command. """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange], plot_points) f_x,f_y,f_z = g w = [(f_x(u), f_y(u), f_z(u)) for u in xsrange(*ranges[0], include_endpoint=True)] return line3d(w, **kwds)
def _parametric_plot3d_surface(f, urange, vrange, plot_points, boundary_style, **kwds): r""" This function is used internally by the ``parametric_plot3d`` command. """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange, vrange], plot_points) urange = srange(*ranges[0], include_endpoint=True) vrange = srange(*ranges[1], include_endpoint=True) G = ParametricSurface(g, (urange, vrange), **kwds) if boundary_style is not None: for u in (urange[0], urange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for v in vrange], **boundary_style) for v in (vrange[0], vrange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for u in urange], **boundary_style) return G
def _parametric_plot3d_curve(f, urange, plot_points, **kwds): r""" This function is used internally by the ``parametric_plot3d`` command. """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange], plot_points) f_x, f_y, f_z = g w = [(f_x(u), f_y(u), f_z(u)) for u in xsrange(*ranges[0], include_endpoint=True)] return line3d(w, **kwds)
def _parametric_plot3d_curve(f, urange, plot_points, **kwds): r""" Return a parametric three-dimensional space curve. This function is used internally by the :func:`parametric_plot3d` command. There are two ways this function is invoked by :func:`parametric_plot3d`. - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max))``: `f_x, f_y, f_z` are three functions and `u_{\min}` and `u_{\max}` are real numbers - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min, u_max))``: `f_x, f_y, f_z` can be viewed as functions of `u` INPUT: - ``f`` - a 3-tuple of functions or expressions, or vector of size 3 - ``urange`` - a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - ``plot_points`` - (default: "automatic", which is 75) initial number of sample points in each parameter; an integer. EXAMPLES: We demonstrate each of the two ways of calling this. See :func:`parametric_plot3d` for many more examples. We do the first one with a lambda function, which creates a callable Python function that sends `u` to `u/10`:: sage: parametric_plot3d( (sin, cos, lambda u: u/10), (0, 20)) # indirect doctest Graphics3d Object Now we do the same thing with symbolic expressions:: sage: u = var('u') sage: parametric_plot3d( (sin(u), cos(u), u/10), (u, 0, 20)) Graphics3d Object """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange], plot_points) f_x, f_y, f_z = g w = [(f_x(u), f_y(u), f_z(u)) for u in xsrange(*ranges[0], include_endpoint=True)] return line3d(w, **kwds)
def list_plot3d(v, interpolation_type='default', texture="automatic", point_list=None, **kwds): r""" A 3-dimensional plot of a surface defined by the list `v` of points in 3-dimensional space. INPUT: - ``v`` - something that defines a set of points in 3 space, for example: - a matrix - a list of 3-tuples - a list of lists (all of the same length) - this is treated the same as a matrix. - ``texture`` - (default: "automatic", a solid light blue) OPTIONAL KEYWORDS: - ``interpolation_type`` - 'linear', 'nn' (natural neighbor), 'spline' 'linear' will perform linear interpolation The option 'nn' An interpolation method for multivariate data in a Delaunay triangulation. The value for an interpolation point is estimated using weighted values of the closest surrounding points in the triangulation. These points, the natural neighbors, are the ones the interpolation point would connect to if inserted into the triangulation. The option 'spline' interpolates using a bivariate B-spline. When v is a matrix the default is to use linear interpolation, when v is a list of points the default is nearest neighbor. - ``degree`` - an integer between 1 and 5, controls the degree of spline used for spline interpolation. For data that is highly oscillatory use higher values - ``point_list`` - If point_list=True is passed, then if the array is a list of lists of length three, it will be treated as an array of points rather than a 3xn array. - ``num_points`` - Number of points to sample interpolating function in each direction, when ``interpolation_type`` is not ``default``. By default for an `n\times n` array this is `n`. - ``**kwds`` - all other arguments are passed to the surface function OUTPUT: a 3d plot EXAMPLES: We plot a matrix that illustrates summation modulo `n`. :: sage: n = 5; list_plot3d(matrix(RDF, n, [(i+j)%n for i in [1..n] for j in [1..n]])) Graphics3d Object We plot a matrix of values of sin. :: sage: pi = float(pi) sage: m = matrix(RDF, 6, [sin(i^2 + j^2) for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]]) sage: list_plot3d(m, texture='yellow', frame_aspect_ratio=[1, 1, 1/3]) Graphics3d Object Though it doesn't change the shape of the graph, increasing num_points can increase the clarity of the graph. :: sage: list_plot3d(m, texture='yellow', frame_aspect_ratio=[1, 1, 1/3], num_points=40) Graphics3d Object We can change the interpolation type. :: sage: import warnings sage: warnings.simplefilter('ignore', UserWarning) sage: list_plot3d(m, texture='yellow', interpolation_type='nn', frame_aspect_ratio=[1, 1, 1/3]) Graphics3d Object We can make this look better by increasing the number of samples. :: sage: list_plot3d(m, texture='yellow', interpolation_type='nn', frame_aspect_ratio=[1, 1, 1/3], num_points=40) Graphics3d Object Let's try a spline. :: sage: list_plot3d(m, texture='yellow', interpolation_type='spline', frame_aspect_ratio=[1, 1, 1/3]) Graphics3d Object That spline doesn't capture the oscillation very well; let's try a higher degree spline. :: sage: list_plot3d(m, texture='yellow', interpolation_type='spline', degree=5, frame_aspect_ratio=[1, 1, 1/3]) Graphics3d Object We plot a list of lists:: sage: show(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]])) We plot a list of points. As a first example we can extract the (x,y,z) coordinates from the above example and make a list plot out of it. By default we do linear interpolation. :: sage: l = [] sage: for i in range(6): ... for j in range(6): ... l.append((float(i*pi/5), float(j*pi/5), m[i, j])) sage: list_plot3d(l, texture='yellow') Graphics3d Object Note that the points do not have to be regularly sampled. For example:: sage: l = [] sage: for i in range(-5, 5): ... for j in range(-5, 5): ... l.append((normalvariate(0, 1), normalvariate(0, 1), normalvariate(0, 1))) sage: list_plot3d(l, interpolation_type='nn', texture='yellow', num_points=100) Graphics3d Object TESTS: We plot 0, 1, and 2 points:: sage: list_plot3d([]) Graphics3d Object :: sage: list_plot3d([(2, 3, 4)]) Graphics3d Object :: sage: list_plot3d([(0, 0, 1), (2, 3, 4)]) Graphics3d Object However, if two points are given with the same x,y coordinates but different z coordinates, an exception will be raised:: sage: pts =[(-4/5, -2/5, -2/5), (-4/5, -2/5, 2/5), (-4/5, 2/5, -2/5), (-4/5, 2/5, 2/5), (-2/5, -4/5, -2/5), (-2/5, -4/5, 2/5), (-2/5, -2/5, -4/5), (-2/5, -2/5, 4/5), (-2/5, 2/5, -4/5), (-2/5, 2/5, 4/5), (-2/5, 4/5, -2/5), (-2/5, 4/5, 2/5), (2/5, -4/5, -2/5), (2/5, -4/5, 2/5), (2/5, -2/5, -4/5), (2/5, -2/5, 4/5), (2/5, 2/5, -4/5), (2/5, 2/5, 4/5), (2/5, 4/5, -2/5), (2/5, 4/5, 2/5), (4/5, -2/5, -2/5), (4/5, -2/5, 2/5), (4/5, 2/5, -2/5), (4/5, 2/5, 2/5)] sage: show(list_plot3d(pts, interpolation_type='nn')) Traceback (most recent call last): ... ValueError: Two points with same x,y coordinates and different z coordinates were given. Interpolation cannot handle this. Additionally we need at least 3 points to do the interpolation:: sage: mat = matrix(RDF, 1, 2, [3.2, 1.550]) sage: show(list_plot3d(mat, interpolation_type='nn')) Traceback (most recent call last): ... ValueError: We need at least 3 points to perform the interpolation """ import numpy if texture == "automatic": texture = "lightblue" if is_Matrix(v): if interpolation_type == 'default' or interpolation_type == 'linear' and 'num_points' not in kwds: return list_plot3d_matrix(v, texture=texture, **kwds) else: l = [] for i in xrange(v.nrows()): for j in xrange(v.ncols()): l.append((i, j, v[i, j])) return list_plot3d_tuples(l, interpolation_type, texture, **kwds) if isinstance(v, numpy.ndarray): return list_plot3d(matrix(v), interpolation_type, texture, **kwds) if isinstance(v, list): if len(v) == 0: # return empty 3d graphic from base import Graphics3d return Graphics3d() elif len(v) == 1: # return a point from shapes2 import point3d return point3d(v[0], **kwds) elif len(v) == 2: # return a line from shapes2 import line3d return line3d(v, **kwds) elif isinstance(v[0], tuple) or point_list == True and len(v[0]) == 3: return list_plot3d_tuples(v, interpolation_type, texture=texture, **kwds) else: return list_plot3d_array_of_arrays(v, interpolation_type, texture, **kwds) raise TypeError("v must be a matrix or list")
def _parametric_plot3d_surface(f, urange, vrange, plot_points, boundary_style, **kwds): r""" Return a parametric three-dimensional space surface. This function is used internally by the :func:`parametric_plot3d` command. There are two ways this function is invoked by :func:`parametric_plot3d`. - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max), (v_min, v_max))``: `f_x, f_y, f_z` are each functions of two variables - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min, u_max), (v, v_min, v_max))``: `f_x, f_y, f_z` can be viewed as functions of `u` and `v` INPUT: - ``f`` - a 3-tuple of functions or expressions, or vector of size 3 - ``urange`` - a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - ``vrange`` - a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max) - ``plot_points`` - (default: "automatic", which is [40,40] for surfaces) initial number of sample points in each parameter; a pair of integers. - ``boundary_style`` - (default: None, no boundary) a dict that describes how to draw the boundaries of regions by giving options that are passed to the line3d command. EXAMPLES: We demonstrate each of the two ways of calling this. See :func:`parametric_plot3d` for many more examples. We do the first one with lambda functions:: sage: f = (lambda u,v: cos(u), lambda u,v: sin(u)+cos(v), lambda u,v: sin(v)) sage: parametric_plot3d(f, (0, 2*pi), (-pi, pi)) # indirect doctest Graphics3d Object Now we do the same thing with symbolic expressions:: sage: u, v = var('u,v') sage: parametric_plot3d((cos(u), sin(u) + cos(v), sin(v)), (u, 0, 2*pi), (v, -pi, pi), mesh=True) Graphics3d Object """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange, vrange], plot_points) urange = srange(*ranges[0], include_endpoint=True) vrange = srange(*ranges[1], include_endpoint=True) G = ParametricSurface(g, (urange, vrange), **kwds) if boundary_style is not None: for u in (urange[0], urange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for v in vrange], **boundary_style) for v in (vrange[0], vrange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for u in urange], **boundary_style) return G
def _parametric_plot3d_surface(f, urange, vrange, plot_points, boundary_style, **kwds): r""" Return a parametric three-dimensional space surface. This function is used internally by the :func:`parametric_plot3d` command. There are two ways this function is invoked by :func:`parametric_plot3d`. - ``parametric_plot3d([f_x, f_y, f_z], (u_min, u_max), (v_min, v_max))``: `f_x, f_y, f_z` are each functions of two variables - ``parametric_plot3d([f_x, f_y, f_z], (u, u_min, u_max), (v, v_min, v_max))``: `f_x, f_y, f_z` can be viewed as functions of `u` and `v` INPUT: - ``f`` - a 3-tuple of functions or expressions, or vector of size 3 - ``urange`` - a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) - ``vrange`` - a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max) - ``plot_points`` - (default: "automatic", which is [40,40] for surfaces) initial number of sample points in each parameter; a pair of integers. - ``boundary_style`` - (default: None, no boundary) a dict that describes how to draw the boundaries of regions by giving options that are passed to the line3d command. EXAMPLES: We demonstrate each of the two ways of calling this. See :func:`parametric_plot3d` for many more examples. We do the first one with lambda functions:: sage: f = (lambda u,v: cos(u), lambda u,v: sin(u)+cos(v), lambda u,v: sin(v)) sage: parametric_plot3d(f, (0, 2*pi), (-pi, pi)) # indirect doctest Now we do the same thing with symbolic expressions:: sage: u, v = var('u,v') sage: parametric_plot3d((cos(u), sin(u) + cos(v), sin(v)), (u, 0, 2*pi), (v, -pi, pi), mesh=True) """ from sage.plot.misc import setup_for_eval_on_grid g, ranges = setup_for_eval_on_grid(f, [urange, vrange], plot_points) urange = srange(*ranges[0], include_endpoint=True) vrange = srange(*ranges[1], include_endpoint=True) G = ParametricSurface(g, (urange, vrange), **kwds) if boundary_style is not None: for u in (urange[0], urange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for v in vrange], **boundary_style) for v in (vrange[0], vrange[-1]): G += line3d([(g[0](u, v), g[1](u, v), g[2](u, v)) for u in urange], **boundary_style) return G