Plotting utilities#
- class sage.plot.misc.FastCallablePlotWrapper(ff, imag_tol)[source]#
Bases:
FastCallableFloatWrapper
A fast-callable wrapper for plotting that returns
nan
instead of raising an error whenever the imaginary tolerance is exceeded.A detailed rationale for this can be found in the superclass documentation.
EXAMPLES:
The
float
incarnation of “not a number” is returned instead of an error being thrown if the answer is complex:sage: from sage.plot.misc import FastCallablePlotWrapper sage: f = sqrt(x) sage: ff = fast_callable(f, vars=[x], domain=CDF) sage: fff = FastCallablePlotWrapper(ff, imag_tol=1e-8) sage: fff(1) 1.0 sage: fff(-1) nan
>>> from sage.all import * >>> from sage.plot.misc import FastCallablePlotWrapper >>> f = sqrt(x) >>> ff = fast_callable(f, vars=[x], domain=CDF) >>> fff = FastCallablePlotWrapper(ff, imag_tol=RealNumber('1e-8')) >>> fff(Integer(1)) 1.0 >>> fff(-Integer(1)) nan
- sage.plot.misc.get_matplotlib_linestyle(linestyle, return_type)[source]#
Function which translates between matplotlib linestyle in short notation (i.e. ‘-’, ‘–’, ‘:’, ‘-.’) and long notation (i.e. ‘solid’, ‘dashed’, ‘dotted’, ‘dashdot’ ).
If linestyle is none of these allowed options, the function raises a ValueError.
INPUT:
linestyle
– The style of the line, which is one of"-"
or"solid"
"--"
or"dashed"
"-."
or"dash dot"
":"
or"dotted"
"None"
or" "
or""
(nothing)
The linestyle can also be prefixed with a drawing style (e.g.,
"steps--"
)"default"
(connect the points with straight lines)"steps"
or"steps-pre"
(step function; horizontal line is to the left of point)"steps-mid"
(step function; points are in the middle of horizontal lines)"steps-post"
(step function; horizontal line is to the right of point)
If
linestyle
isNone
(of type NoneType), then we return it back unmodified.
return_type
– The type of linestyle that should be output. This argument takes only two values -"long"
or"short"
.
EXAMPLES:
Here is an example how to call this function:
sage: from sage.plot.misc import get_matplotlib_linestyle sage: get_matplotlib_linestyle(':', return_type='short') ':' sage: get_matplotlib_linestyle(':', return_type='long') 'dotted'
>>> from sage.all import * >>> from sage.plot.misc import get_matplotlib_linestyle >>> get_matplotlib_linestyle(':', return_type='short') ':' >>> get_matplotlib_linestyle(':', return_type='long') 'dotted'
- sage.plot.misc.setup_for_eval_on_grid(funcs, ranges, plot_points=None, return_vars=False, imaginary_tolerance=1e-08)[source]#
Calculate the necessary parameters to construct a list of points, and make the functions fast_callable.
INPUT:
funcs
– a function, or a list, tuple, or vector of functionsranges
– a list of ranges. A range can be a 2-tuple of numbers specifying the minimum and maximum, or a 3-tuple giving the variable explicitly.plot_points
– a tuple of integers specifying the number of plot points for each range. If a single number is specified, it will be the value for all ranges. This defaults to 2.return_vars
– (defaultFalse
) IfTrue
, return the variables, in order.imaginary_tolerance
– (default:1e-8
); if an imaginary number arises (due, for example, to numerical issues), this tolerance specifies how large it has to be in magnitude before we raise an error. In other words, imaginary parts smaller than this are ignored in your plot points.
OUTPUT:
fast_funcs
– if only one function passed, then a fast callable function. If funcs is a list or tuple, then a tuple of fast callable functions is returned.range_specs
– a list of range_specs: for each range, a tuple is returned of the form (range_min, range_max, range_step) such thatsrange(range_min, range_max, range_step, include_endpoint=True)
gives the correct points for evaluation.
EXAMPLES:
sage: x,y,z=var('x,y,z') sage: f(x,y)=x+y-z sage: g(x,y)=x+y sage: h(y)=-y sage: sage.plot.misc.setup_for_eval_on_grid(f, [(0, 2),(1,3),(-4,1)], plot_points=5) (<sage...>, [(0.0, 2.0, 0.5), (1.0, 3.0, 0.5), (-4.0, 1.0, 1.25)]) sage: sage.plot.misc.setup_for_eval_on_grid([g,h], [(0, 2),(-1,1)], plot_points=5) ((<sage...>, <sage...>), [(0.0, 2.0, 0.5), (-1.0, 1.0, 0.5)]) sage: sage.plot.misc.setup_for_eval_on_grid([sin,cos], [(-1,1)], plot_points=9) ((<sage...>, <sage...>), [(-1.0, 1.0, 0.25)]) sage: sage.plot.misc.setup_for_eval_on_grid([lambda x: x^2,cos], [(-1,1)], plot_points=9) ((<function <lambda> ...>, <sage...>), [(-1.0, 1.0, 0.25)]) sage: sage.plot.misc.setup_for_eval_on_grid([x+y], [(x,-1,1),(y,-2,2)]) ((<sage...>,), [(-1.0, 1.0, 2.0), (-2.0, 2.0, 4.0)]) sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,-1,1),(y,-1,1)], plot_points=[4,9]) (<sage...>, [(-1.0, 1.0, 0.6666666666666666), (-1.0, 1.0, 0.25)]) sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,-1,1),(y,-1,1)], plot_points=[4,9,10]) Traceback (most recent call last): ... ValueError: plot_points must be either an integer or a list of integers, one for each range sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(1,-1),(y,-1,1)], plot_points=[4,9,10]) Traceback (most recent call last): ... ValueError: Some variable ranges specify variables while others do not
>>> from sage.all import * >>> x,y,z=var('x,y,z') >>> __tmp__=var("x,y"); f = symbolic_expression(x+y-z).function(x,y) >>> __tmp__=var("x,y"); g = symbolic_expression(x+y).function(x,y) >>> __tmp__=var("y"); h = symbolic_expression(-y).function(y) >>> sage.plot.misc.setup_for_eval_on_grid(f, [(Integer(0), Integer(2)),(Integer(1),Integer(3)),(-Integer(4),Integer(1))], plot_points=Integer(5)) (<sage...>, [(0.0, 2.0, 0.5), (1.0, 3.0, 0.5), (-4.0, 1.0, 1.25)]) >>> sage.plot.misc.setup_for_eval_on_grid([g,h], [(Integer(0), Integer(2)),(-Integer(1),Integer(1))], plot_points=Integer(5)) ((<sage...>, <sage...>), [(0.0, 2.0, 0.5), (-1.0, 1.0, 0.5)]) >>> sage.plot.misc.setup_for_eval_on_grid([sin,cos], [(-Integer(1),Integer(1))], plot_points=Integer(9)) ((<sage...>, <sage...>), [(-1.0, 1.0, 0.25)]) >>> sage.plot.misc.setup_for_eval_on_grid([lambda x: x**Integer(2),cos], [(-Integer(1),Integer(1))], plot_points=Integer(9)) ((<function <lambda> ...>, <sage...>), [(-1.0, 1.0, 0.25)]) >>> sage.plot.misc.setup_for_eval_on_grid([x+y], [(x,-Integer(1),Integer(1)),(y,-Integer(2),Integer(2))]) ((<sage...>,), [(-1.0, 1.0, 2.0), (-2.0, 2.0, 4.0)]) >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,-Integer(1),Integer(1)),(y,-Integer(1),Integer(1))], plot_points=[Integer(4),Integer(9)]) (<sage...>, [(-1.0, 1.0, 0.6666666666666666), (-1.0, 1.0, 0.25)]) >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,-Integer(1),Integer(1)),(y,-Integer(1),Integer(1))], plot_points=[Integer(4),Integer(9),Integer(10)]) Traceback (most recent call last): ... ValueError: plot_points must be either an integer or a list of integers, one for each range >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(Integer(1),-Integer(1)),(y,-Integer(1),Integer(1))], plot_points=[Integer(4),Integer(9),Integer(10)]) Traceback (most recent call last): ... ValueError: Some variable ranges specify variables while others do not
Beware typos: a comma which should be a period, for instance:
sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x, 1, 2), (y, 0,1, 0.2)], plot_points=[4,9,10]) Traceback (most recent call last): ... ValueError: At least one variable range has more than 3 entries: each should either have 2 or 3 entries, with one of the forms (xmin, xmax) or (x, xmin, xmax) sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(y,1,-1),(x,-1,1)], plot_points=5) (<sage...>, [(-1.0, 1.0, 0.5), (-1.0, 1.0, 0.5)]) sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,1,-1),(x,-1,1)], plot_points=5) Traceback (most recent call last): ... ValueError: range variables should be distinct, but there are duplicates sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,1,1),(y,-1,1)]) Traceback (most recent call last): ... ValueError: plot start point and end point must be different sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,1,-1),(y,-1,1)], return_vars=True) (<sage...>, [(-1.0, 1.0, 2.0), (-1.0, 1.0, 2.0)], [x, y]) sage: sage.plot.misc.setup_for_eval_on_grid(x+y, [(y,1,-1),(x,-1,1)], return_vars=True) (<sage...>, [(-1.0, 1.0, 2.0), (-1.0, 1.0, 2.0)], [y, x])
>>> from sage.all import * >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x, Integer(1), Integer(2)), (y, Integer(0),Integer(1), RealNumber('0.2'))], plot_points=[Integer(4),Integer(9),Integer(10)]) Traceback (most recent call last): ... ValueError: At least one variable range has more than 3 entries: each should either have 2 or 3 entries, with one of the forms (xmin, xmax) or (x, xmin, xmax) >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(y,Integer(1),-Integer(1)),(x,-Integer(1),Integer(1))], plot_points=Integer(5)) (<sage...>, [(-1.0, 1.0, 0.5), (-1.0, 1.0, 0.5)]) >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,Integer(1),-Integer(1)),(x,-Integer(1),Integer(1))], plot_points=Integer(5)) Traceback (most recent call last): ... ValueError: range variables should be distinct, but there are duplicates >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,Integer(1),Integer(1)),(y,-Integer(1),Integer(1))]) Traceback (most recent call last): ... ValueError: plot start point and end point must be different >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(x,Integer(1),-Integer(1)),(y,-Integer(1),Integer(1))], return_vars=True) (<sage...>, [(-1.0, 1.0, 2.0), (-1.0, 1.0, 2.0)], [x, y]) >>> sage.plot.misc.setup_for_eval_on_grid(x+y, [(y,Integer(1),-Integer(1)),(x,-Integer(1),Integer(1))], return_vars=True) (<sage...>, [(-1.0, 1.0, 2.0), (-1.0, 1.0, 2.0)], [y, x])
- sage.plot.misc.unify_arguments(funcs)[source]#
Return a tuple of variables of the functions, as well as the number of “free” variables (i.e., variables that defined in a callable function).
INPUT:
funcs
– a list of functions; these can be symbolic expressions, polynomials, etc
OUTPUT: functions, expected arguments
A tuple of variables in the functions
A tuple of variables that were “free” in the functions
EXAMPLES:
sage: x,y,z=var('x,y,z') sage: f(x,y)=x+y-z sage: g(x,y)=x+y sage: h(y)=-y sage: sage.plot.misc.unify_arguments((f,g,h)) ((x, y, z), (z,)) sage: sage.plot.misc.unify_arguments((g,h)) ((x, y), ()) sage: sage.plot.misc.unify_arguments((f,z)) ((x, y, z), (z,)) sage: sage.plot.misc.unify_arguments((h,z)) ((y, z), (z,)) sage: sage.plot.misc.unify_arguments((x+y,x-y)) ((x, y), (x, y))
>>> from sage.all import * >>> x,y,z=var('x,y,z') >>> __tmp__=var("x,y"); f = symbolic_expression(x+y-z).function(x,y) >>> __tmp__=var("x,y"); g = symbolic_expression(x+y).function(x,y) >>> __tmp__=var("y"); h = symbolic_expression(-y).function(y) >>> sage.plot.misc.unify_arguments((f,g,h)) ((x, y, z), (z,)) >>> sage.plot.misc.unify_arguments((g,h)) ((x, y), ()) >>> sage.plot.misc.unify_arguments((f,z)) ((x, y, z), (z,)) >>> sage.plot.misc.unify_arguments((h,z)) ((y, z), (z,)) >>> sage.plot.misc.unify_arguments((x+y,x-y)) ((x, y), (x, y))