Streamline plots

class sage.plot.streamline_plot.StreamlinePlot(xpos_array, ypos_array, xvec_array, yvec_array, options)[source]

Bases: GraphicPrimitive

Primitive class that initializes the StreamlinePlot graphics type

get_minmax_data()[source]

Return a dictionary with the bounding box data.

EXAMPLES:

sage: x, y = var('x y')
sage: import numpy  # to ensure numpy 2.0 compatibility
sage: if int(numpy.version.short_version[0]) > 1:
....:     numpy.set_printoptions(legacy="1.25")
sage: d = streamline_plot((.01*x, x+y), (x,10,20), (y,10,20))[0].get_minmax_data()
sage: d['xmin']
10.0
sage: d['ymin']
10.0
>>> from sage.all import *
>>> x, y = var('x y')
>>> import numpy  # to ensure numpy 2.0 compatibility
>>> if int(numpy.version.short_version[Integer(0)]) > Integer(1):
...     numpy.set_printoptions(legacy="1.25")
>>> d = streamline_plot((RealNumber('.01')*x, x+y), (x,Integer(10),Integer(20)), (y,Integer(10),Integer(20)))[Integer(0)].get_minmax_data()
>>> d['xmin']
10.0
>>> d['ymin']
10.0
sage.plot.streamline_plot.streamline_plot(f_g, xrange, yrange, plot_points=20, density=1.0, frame=True, **options)[source]

Return a streamline plot in a vector field.

streamline_plot can take either one or two functions. Consider two variables \(x\) and \(y\).

If given two functions \((f(x,y), g(x,y))\), then this function plots streamlines in the vector field over the specified ranges with xrange being of \(x\), denoted by xvar below, between xmin and xmax, and yrange similarly (see below).

streamline_plot((f, g), (xvar, xmin, xmax), (yvar, ymin, ymax))

Similarly, if given one function \(f(x, y)\), then this function plots streamlines in the slope field \(dy/dx = f(x,y)\) over the specified ranges as given above.

PLOT OPTIONS:

  • plot_points – (default: 200) the minimal number of plot points

  • density – float (default: 1.); controls the closeness of streamlines

  • start_points – (optional) list of coordinates of starting points for the streamlines; coordinate pairs can be tuples or lists

EXAMPLES:

Plot some vector fields involving \(\sin\) and \(\cos\):

sage: x, y = var('x y')
sage: streamline_plot((sin(x), cos(y)), (x,-3,3), (y,-3,3))
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> x, y = var('x y')
>>> streamline_plot((sin(x), cos(y)), (x,-Integer(3),Integer(3)), (y,-Integer(3),Integer(3)))
Graphics object consisting of 1 graphics primitive
../../_images/streamline_plot-1.svg
sage: streamline_plot((y, (cos(x)-2) * sin(x)), (x,-pi,pi), (y,-pi,pi))
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> streamline_plot((y, (cos(x)-Integer(2)) * sin(x)), (x,-pi,pi), (y,-pi,pi))
Graphics object consisting of 1 graphics primitive
../../_images/streamline_plot-2.svg

We increase the density of the plot:

sage: streamline_plot((y, (cos(x)-2) * sin(x)),
....:                 (x,-pi,pi), (y,-pi,pi), density=2)
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> streamline_plot((y, (cos(x)-Integer(2)) * sin(x)),
...                 (x,-pi,pi), (y,-pi,pi), density=Integer(2))
Graphics object consisting of 1 graphics primitive
../../_images/streamline_plot-3.svg

We ignore function values that are infinite or NaN:

sage: x, y = var('x y')
sage: streamline_plot((-x/sqrt(x^2+y^2), -y/sqrt(x^2+y^2)),
....:                 (x,-10,10), (y,-10,10))
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> x, y = var('x y')
>>> streamline_plot((-x/sqrt(x**Integer(2)+y**Integer(2)), -y/sqrt(x**Integer(2)+y**Integer(2))),
...                 (x,-Integer(10),Integer(10)), (y,-Integer(10),Integer(10)))
Graphics object consisting of 1 graphics primitive
../../_images/streamline_plot-4.svg

Extra options will get passed on to show(), as long as they are valid:

sage: streamline_plot((x, y), (x,-2,2), (y,-2,2), xmax=10)
Graphics object consisting of 1 graphics primitive
sage: streamline_plot((x, y), (x,-2,2), (y,-2,2)).show(xmax=10)  # These are equivalent
>>> from sage.all import *
>>> streamline_plot((x, y), (x,-Integer(2),Integer(2)), (y,-Integer(2),Integer(2)), xmax=Integer(10))
Graphics object consisting of 1 graphics primitive
>>> streamline_plot((x, y), (x,-Integer(2),Integer(2)), (y,-Integer(2),Integer(2))).show(xmax=Integer(10))  # These are equivalent
../../_images/streamline_plot-5.svg

We can also construct streamlines in a slope field:

sage: x, y = var('x y')
sage: streamline_plot((x + y) / sqrt(x^2 + y^2), (x,-3,3), (y,-3,3))
Graphics object consisting of 1 graphics primitive
>>> from sage.all import *
>>> x, y = var('x y')
>>> streamline_plot((x + y) / sqrt(x**Integer(2) + y**Integer(2)), (x,-Integer(3),Integer(3)), (y,-Integer(3),Integer(3)))
Graphics object consisting of 1 graphics primitive
../../_images/streamline_plot-6.svg

We choose some particular points the streamlines pass through:

sage: pts = [[1, 1], [-2, 2], [1, -3/2]]
sage: g = streamline_plot((x + y) / sqrt(x^2 + y^2),
....:                     (x,-3,3), (y,-3,3), start_points=pts)
sage: g += point(pts, color='red')
sage: g
Graphics object consisting of 2 graphics primitives
>>> from sage.all import *
>>> pts = [[Integer(1), Integer(1)], [-Integer(2), Integer(2)], [Integer(1), -Integer(3)/Integer(2)]]
>>> g = streamline_plot((x + y) / sqrt(x**Integer(2) + y**Integer(2)),
...                     (x,-Integer(3),Integer(3)), (y,-Integer(3),Integer(3)), start_points=pts)
>>> g += point(pts, color='red')
>>> g
Graphics object consisting of 2 graphics primitives
../../_images/streamline_plot-7.svg

Note

Streamlines currently pass close to start_points but do not necessarily pass directly through them. That is part of the behavior of matplotlib, not an error on your part.