Path: blob/master/src/sage/plot/plot3d/plot_field3d.py
8815 views
"""1Plotting 3D fields2"""3#*****************************************************************************4# Copyright (C) 2009 Jason Grout <[email protected]>5#6# Distributed under the terms of the GNU General Public License (GPL)7#8# This code is distributed in the hope that it will be useful,9# but WITHOUT ANY WARRANTY; without even the implied warranty of10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU11# General Public License for more details.12#13# The full text of the GPL is available at:14#15# http://www.gnu.org/licenses/16#*****************************************************************************1718from sage.misc.misc import srange19from sage.plot.misc import setup_for_eval_on_grid20from sage.modules.free_module_element import vector21from sage.plot.plot import plot2223def plot_vector_field3d(functions, xrange, yrange, zrange,24plot_points=5, colors='jet', center_arrows=False,**kwds):25r"""26Plot a 3d vector field2728INPUT:2930- ``functions`` - a list of three functions, representing the x-,31y-, and z-coordinates of a vector3233- ``xrange``, ``yrange``, and ``zrange`` - three tuples of the34form (var, start, stop), giving the variables and ranges for each axis3536- ``plot_points`` (default 5) - either a number or list of three37numbers, specifying how many points to plot for each axis3839- ``colors`` (default 'jet') - a color, list of colors (which are40interpolated between), or matplotlib colormap name, giving the coloring41of the arrows. If a list of colors or a colormap is given,42coloring is done as a function of length of the vector4344- ``center_arrows`` (default False) - If True, draw the arrows45centered on the points; otherwise, draw the arrows with the tail46at the point4748- any other keywords are passed on to the plot command for each arrow4950EXAMPLES::5152sage: x,y,z=var('x y z')53sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi))54sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),colors=['red','green','blue'])55sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),colors='red')56sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),plot_points=4)57sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),plot_points=[3,5,7])58sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),center_arrows=True)5960TESTS:6162This tests that :trac:`2100` is fixed in a way compatible with this command::6364sage: plot_vector_field3d((x*cos(z),-y*cos(z),sin(z)), (x,0,pi), (y,0,pi), (z,0,pi),center_arrows=True,aspect_ratio=(1,2,1))65"""66(ff,gg,hh), ranges = setup_for_eval_on_grid(functions, [xrange, yrange, zrange], plot_points)67xpoints, ypoints, zpoints = [srange(*r, include_endpoint=True) for r in ranges]68points = [vector((i,j,k)) for i in xpoints for j in ypoints for k in zpoints]69vectors = [vector((ff(*point), gg(*point), hh(*point))) for point in points]7071try:72from matplotlib.cm import get_cmap73cm = get_cmap(colors)74except (TypeError, ValueError):75cm = None76if cm is None:77if isinstance(colors, (list, tuple)):78from matplotlib.colors import LinearSegmentedColormap79cm = LinearSegmentedColormap.from_list('mymap',colors)80else:81cm = lambda x: colors8283max_len = max(v.norm() for v in vectors)84scaled_vectors = [v/max_len for v in vectors]8586if center_arrows:87return sum([plot(v,color=cm(v.norm()),**kwds).translate(p-v/2) for v,p in zip(scaled_vectors, points)])88else:89return sum([plot(v,color=cm(v.norm()),**kwds).translate(p) for v,p in zip(scaled_vectors, points)])90919293