2D Plotting

Sage provides extensive 2D plotting functionality. The underlying rendering is done using the matplotlib Python library.

The following graphics primitives are supported:

  • arrow() - an arrow from a min point to a max point.
  • circle() - a circle with given radius
  • disk() - a filled disk (i.e. a sector or wedge of a circle)
  • line() - a line determined by a sequence of points (this need not be straight!)
  • point() - a point
  • text() - some text
  • polygon() - a filled polygon

The following plotting functions are supported:

The following miscellaneous Graphics functions are included:

Type ? after each primitive in Sage for help and examples.

EXAMPLES: We construct a plot involving several graphics objects:

sage: G = plot(cos, -5, 5, thickness=5, rgbcolor=(0.5,1,0.5))
sage: P = polygon([[1,2], [5,6], [5,0]], rgbcolor=(1,0,0))
sage: P   # show it

We draw a circle and a curve:

sage: circle((1,1), 1) + plot(x^2, (0,5))

Notice that the above circle is not round, because the aspect ratio of the coordinate system is not 1:1. The aspect_ratio option to show allows us to fix this:

sage: show(circle((1,1), 1) + plot(x^2, (0,5)), aspect_ratio=1)

With an aspect ratio of 2 the circle is squashed half way down (it looks twice as wide as it does tall):

sage: show(circle((1,1), 1) + plot(x^2, (0,5)), aspect_ratio=2)

Use figsize to set the actual aspect ratio of the rendered image (i.e., of the frame). For example, this image is twice as many pixels wide as it is tall:

sage: show(circle((1,1), 1) + plot(x^2, (0,5)), figsize=[8,4])

Next we construct the reflection of the above polygon about the y-axis by iterating over the list of first-coordinates of the first graphic element of P (which is the actual Polygon; note that P is a Graphics object, which consists of a single polygon):

sage: Q = polygon([(-x,y) for x,y in P[0]], rgbcolor=(0,0,1))
sage: Q   # show it

We combine together different graphics objects using “+”:

sage: H = G + P + Q
sage: print H
Graphics object consisting of 3 graphics primitives
sage: type(H)
<class 'sage.plot.plot.Graphics'>
sage: H[1]
Polygon defined by 3 points
sage: list(H[1])
[(1.0, 2.0), (5.0, 6.0), (5.0, 0.0)]
sage: H       # show it

We can put text in a graph:

sage: L = [[cos(pi*i/100)^3,sin(pi*i/100)] for i in range(200)]
sage: p = line(L, rgbcolor=(1/4,1/8,3/4))
sage: t = text('A Bulb', (1.5, 0.25))
sage: x = text('x axis', (1.5,-0.2))
sage: y = text('y axis', (0.4,0.9))
sage: g = p+t+x+y
sage: g.show(xmin=-1.5, xmax=2, ymin=-1, ymax=1)

We plot the Riemann zeta function along the critical line and see the first few zeros:

sage: i = CDF.0      # define i this way for maximum speed.
sage: p1 = plot(lambda t: arg(zeta(0.5+t*i)), 1,27,rgbcolor=(0.8,0,0))
sage: p2 = plot(lambda t: abs(zeta(0.5+t*i)), 1,27,rgbcolor=hue(0.7))
sage: print p1 + p2
Graphics object consisting of 2 graphics primitives
sage: p1 + p2    # display it

Many concentric circles shrinking toward the origin:

sage: show(sum(circle((i,0), i, hue=sin(i/10)) for i in [10,9.9,..,0]), aspect_ratio=1)

Here is a pretty graph:

sage: g = Graphics()
sage: for i in range(60):
...    p = polygon([(i*cos(i),i*sin(i)), (0,i), (i,0)],\
...                rgbcolor=hue(i/40+0.4), alpha=0.2)
...    g = g + p
...
sage: g.show(dpi=200, axes=False)

Another graph:

sage: x = var('x')
sage: P = plot(sin(x)/x, -4,4, rgbcolor=(0,0,1)) + \
...       plot(x*cos(x), -4,4, rgbcolor=(1,0,0)) + \
...       plot(tan(x),-4,4,rgbcolor=(0,1,0))
...
sage: P.show(ymin=-pi,ymax=pi)

PYX EXAMPLES: These are some examples of plots similar to some of the plots in the PyX (http://pyx.sourceforge.net) documentation:

Symbolline:

sage: y(x) = x*sin(x^2)
sage: v = [(x, y(x)) for x in [-3,-2.95,..,3]]
sage: show(points(v, rgbcolor=(0.2,0.6, 0.1), pointsize=30) + plot(spline(v), -3.1, 3))

Cycliclink:

sage: x = var('x')
sage: g1 = plot(cos(20*x)*exp(-2*x), 0, 1)
sage: g2 = plot(2*exp(-30*x) - exp(-3*x), 0, 1)
sage: show(graphics_array([g1, g2], 2, 1), xmin=0)

Pi Axis: In the PyX manual, the point of this example is to show labeling the X-axis using rational multiples of Pi. Sage currently has no support for controlling how the ticks on the x and y axes are labeled, so this is really a bad example:

sage: g1 = plot(sin(x), 0, 2*pi)
sage: g2 = plot(cos(x), 0, 2*pi, linestyle = "--")
sage: g1 + g2    # show their sum

An illustration of integration:

sage: f(x) = (x-3)*(x-5)*(x-7)+40
sage: P = line([(2,0),(2,f(2))], rgbcolor=(0,0,0))
sage: P += line([(8,0),(8,f(8))], rgbcolor=(0,0,0))
sage: P += polygon([(2,0),(2,f(2))] + [(x, f(x)) for x in [2,2.1,..,8]] + [(8,0),(2,0)],  rgbcolor=(0.8,0.8,0.8))
sage: P += text("$\\int_{a}^b f(x) dx$", (5, 20), fontsize=16, rgbcolor=(0,0,0))
sage: P += plot(f, 1, 8.5, thickness=3)
sage: P    # show the result

NUMERICAL PLOTTING:

Sage also provides 2D plotting with an interface that is a likely very familiar to people doing numerical computation. For example,

sage: from pylab import *
sage: t = arange(0.0, 2.0, 0.01)
sage: s = sin(2*pi*t)
sage: P = plot(t, s, linewidth=1.0)
sage: xl = xlabel('time (s)')
sage: yl = ylabel('voltage (mV)')
sage: t = title('About as simple as it gets, folks')
sage: grid(True)
sage: savefig('sage.png')

Since the above overwrites many Sage plotting functions, we reset the state of Sage, so that the examples below work!

sage: reset()

See http://matplotlib.sourceforge.net for complete documentation about how to use Matplotlib.

TESTS: We test dumping and loading a plot.

sage: p = plot(sin(x), (x, 0,2*pi))
sage: Q = loads(dumps(p))

AUTHORS:

  • Alex Clemesha and William Stein (2006-04-10): initial version
  • David Joyner: examples
  • Alex Clemesha (2006-05-04) major update
  • William Stein (2006-05-29): fine tuning, bug fixes, better server integration
  • William Stein (2006-07-01): misc polish
  • Alex Clemesha (2006-09-29): added contour_plot, frame axes, misc polishing
  • Robert Miller (2006-10-30): tuning, NetworkX primitive
  • Alex Clemesha (2006-11-25): added plot_vector_field, matrix_plot, arrow, bar_chart, Axes class usage (see axes.py)
  • Bobby Moretti and William Stein (2008-01): Change plot to specify ranges using the (varname, min, max) notation.
  • William Stein (2008-01-19): raised the documentation coverage from a miserable 12 percent to a ‘wopping’ 35 percent, and fixed and clarified numerous small issues.
class sage.plot.plot.Graphics

The Graphics object is an empty list of graphics objects It is useful to use this object when initializing a for loop where different graphics object will be added to the empty object.

EXAMPLES:

sage: G = Graphics(); print G
Graphics object consisting of 0 graphics primitives
sage: c = circle((1,1), 1)
sage: G+=c; print G
Graphics object consisting of 1 graphics primitive

Here we make a graphic of embedded isosceles triangles, coloring each one with a different color as we go:

sage: h=10; c=0.4; p=0.1;
sage: G = Graphics()
sage: for x in srange(1,h+1):
...        l = [[0,x*sqrt(3)],[-x/2,-x*sqrt(3)/2],[x/2,-x*sqrt(3)/2],[0,x*sqrt(3)]]
...        G+=line(l,rgbcolor=hue(c + p*(x/h)))
sage: G.show(figsize=[5,5])
__add__(other)

If you have any Graphics object G1, you can always add any other amount of Graphics objects G2,G3,... to form a new Graphics object: G4 = G1 + G2 + G3.

The xmin, xmax, ymin, and ymax properties of the graphics objects are expanded to include all objects in both scenes. If the aspect ratio property of either or both objects are set, then the larger aspect ratio is chosen.

EXAMPLES:

sage: g1 = plot(abs(sqrt(x^3-1)), (x,1,5), frame=True)
sage: g2 = plot(-abs(sqrt(x^3-1)), (x,1,5), rgbcolor=(1,0,0))
sage: g1 + g2  # displays the plot

TESTS:

sage: (g1 + g2)._extra_kwds # extra keywords to show are propagated
{'frame': True}
__delitem__(i)

If G is of type Graphics, then del(G[i]) removes the ith distinct graphic primitive making up that object.

EXAMPLES:

sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
Graphics object consisting of 3 graphics primitives
sage: len(G)
3
sage: del(G[2])
sage: print G
Graphics object consisting of 2 graphics primitives
sage: len(G)
2
__getitem__(i)

Returns the ith graphics primitive object:

EXAMPLE:

sage: G = circle((1,1),2) + circle((2,2),5); print G
Graphics object consisting of 2 graphics primitives
sage: G[1]
Circle defined by (2.0,2.0) with r=5.0
__init__()

Create a new empty Graphics objects with all the defaults.

EXAMPLES:

sage: G = Graphics()
__len__()

If G is of type Graphics, then len(G) gives the number of distinct graphics primitives making up that object.

EXAMPLES:

sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
Graphics object consisting of 3 graphics primitives
sage: len(G)
3
__radd__(other)

Compute and return other + this graphics object.

This only works when other is a Python int equal to 0. In all other cases a TypeError is raised. The main reason for this function is to make summing a list of graphics objects easier.

EXAMPLES:

sage: S = circle((0,0), 2)
sage: print int(0) + S
Graphics object consisting of 1 graphics primitive
sage: print S + int(0)
Graphics object consisting of 1 graphics primitive

The following would fail were it not for this function:

sage: v = [circle((0,0), 2), circle((2,3), 1)]
sage: print sum(v)
Graphics object consisting of 2 graphics primitives
__setitem__(i, x)

You can replace a GraphicPrimitive (point, line, circle, etc...) in a Graphics object G with any other GraphicPrimitive

EXAMPLES:

sage: G = circle((1,1),1) + circle((1,2),1) + circle((1,2),5); print G
Graphics object consisting of 3 graphics primitives
sage: p = polygon([[1,3],[2,-2],[1,1],[1,3]]); print p
Graphics object consisting of 1 graphics primitive
sage: G[1] = p[0]
sage: G    # show the plot
__str__()

Return string representation of this plot.

EXAMPLES:

sage: S = circle((0,0), 2); S.__str__()
'Graphics object consisting of 1 graphics primitive'
sage: print S
Graphics object consisting of 1 graphics primitive

Warning

__str__ is not called when printing lists of graphics objects, which can be confusing, since they will all pop up. One workaround is to call show_default:

For example, below when we do print v two plots are displayed:

sage: v = [circle((0,0), 2), circle((2,3), 1)]
sage: print v
[, ]

However, if we call show_default then we see the text representations of the graphics:

sage: show_default(False)
sage: print v
[Graphics object consisting of 1 graphics primitive, Graphics object consisting of 1 graphics primitive]
sage: v
[Graphics object consisting of 1 graphics primitive,
 Graphics object consisting of 1 graphics primitive]
sage: show_default(True)
__weakref__
list of weak references to the object (if defined)
classmethod _extract_kwds_for_show(kwds, ignore=[])

Extract keywords relevant to show() from the provided dictionary.

EXAMPLES:

sage: kwds = {'f': lambda x: x, 'xmin': 0, 'figsize': [1,1], 'plot_points': (40, 40)}
sage: G_kwds = Graphics._extract_kwds_for_show(kwds, ignore='xmin')
sage: kwds # Note how this action modifies the passed dictionary
{'xmin': 0, 'plot_points': (40, 40), 'f': <function <lambda> at ...>}
sage: G_kwds
{'figsize': [1, 1]}

This method is intended to be used with _set_extra_kwds(). Here is an idiom to ensure the correct keywords will get passed on to show():

sage: options = {} # Usually this will come from an argument
sage: g = Graphics()
sage: g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
_get_axes_range_dict()

Returns the underlying dictionary used to store the user’s custom ranges for the axes on this object.

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: L._get_axes_range_dict()
{}
sage: L.set_axes_range(xmin=-1)
sage: L._get_axes_range_dict()
{'xmin': -1.0}
_repr_()

Show this graphics objects.

If the show_default function has been called with True (the default), then you’ll see this graphics object displayed. Otherwise you’ll see a text representation of it.

EXAMPLES: We create a plot and call _repr_ on it, which causes it to be displayed as a plot:

sage: P = plot(cos, (-1,1))
sage: P._repr_()
''

Just doing this also displays the plot:

sage: P

Note that printing P with the print statement does not display the plot:

sage: print P
Graphics object consisting of 1 graphics primitive

Now we turn off showing plots by default:

sage: show_default(False)

Now we just get a string. To show P you would have to do show(P).

sage: P._repr_()
'Graphics object consisting of 1 graphics primitive'
sage: P
Graphics object consisting of 1 graphics primitive

Finally, we turn show_default back on:

sage: show_default(True)
_set_extra_kwds(kwds)

Set a dictionary of keywords that will get passed on to show().

TESTS:

sage: g = Graphics()
sage: g._extra_kwds
{}
sage: g._set_extra_kwds({'figsize': [10,10]})
sage: g._extra_kwds
{'figsize': [10, 10]}
sage: g.show() # Now the (blank) plot will be extra large
add_primitive(primitive)
Adds a primitive to this graphics object.
aspect_ratio()

Get the current aspect ratio.

OUTPUT: either None if the aspect ratio hasn’t been set or a positive float

EXAMPLES:

sage: P = circle((1,1), 1)
sage: P.aspect_ratio() is None
True
sage: P.set_aspect_ratio(2)
sage: P.aspect_ratio()
2.0
axes(show=None)

Set whether or not the x and y axes are shown by default.

INPUT:

  • show - bool

If called with no input, return the current axes setting.

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])

By default the axes are displayed.

sage: L.axes()
True

But we turn them off, and verify that they are off

sage: L.axes(False)
sage: L.axes()
False

Displaying L now shows a triangle but no axes.

sage: L
axes_color(c=None)

Set the axes color.

If called with no input, return the current axes_color setting.

INPUT:

  • c - an RGB color 3-tuple, where each tuple entry is a float between 0 and 1

EXAMPLES: We create a line, which has like everything a default axes color of black.

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: L.axes_color()
(0, 0, 0)

We change the axes color to red and verify the change.

sage: L.axes_color((1,0,0))
sage: L.axes_color()
(1.0, 0.0, 0.0)

When we display the plot, we’ll see a blue triangle and bright red axes.

sage: L
axes_label_color(c=None)

Set the color of the axes labels.

The axes labels are placed at the edge of the x and y axes, and are not on by default (use the axes_labels command to set them; see the example below). This function just changes their color.

INPUT:

  • c - an RGB 3-tuple of numbers between 0 and 1

If called with no input, return the current axes_label_color setting.

EXAMPLES: We create a plot, which by default has axes label color black.

sage: p = plot(sin, (-1,1))
sage: p.axes_label_color()
(0, 0, 0)

We change the labels to be red, and confirm this:

sage: p.axes_label_color((1,0,0))
sage: p.axes_label_color()
(1.0, 0.0, 0.0)

We set labels, since otherwise we won’t see anything.

sage: p.axes_labels(['$x$ axis', '$y$ axis'])

In the plot below, notice that the labels are red:

sage: p
axes_labels(l=None)

Set the axes labels.

INPUT:

  • l - (default: None) a list of two strings or None

OUTPUT: a 2-tuple of strings

If l is None, returns the current axes_labels, which is itself by default None. The default labels are both empty.

EXAMPLES: We create a plot and put x and y axes labels on it.

sage: p = plot(sin(x), (x, 0, 10))
sage: p.axes_labels(['x','y'])
sage: p.axes_labels()
('x', 'y')

Now when you plot p, you see x and y axes labels:

sage: p
axes_range(xmin=None, xmax=None, ymin=None, ymax=None)

Set the ranges of the x and y axes.

INPUT:

  • xmin, xmax, ymin, ymax - floats

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: L.set_axes_range(-1, 20, 0, 2)
sage: d = L.get_axes_range()
sage: d['xmin'], d['xmax'], d['ymin'], d['ymax']
(-1.0, 20.0, 0.0, 2.0)
axes_width(w=None)

Set the axes width. Use this to draw a plot with really fat or really thin axes.

INPUT:

  • w - a float

If called with no input, return the current axes_width setting.

EXAMPLE: We create a plot, see the default axes width (with funny Python float rounding), then reset the width to 10 (very fat).

sage: p = plot(cos, (-3,3))
sage: p.axes_width()
0.80000000000000004
sage: p.axes_width(10)
sage: p.axes_width()
10.0

Finally we plot the result, which is a graph with very fat axes.

sage: p
fontsize(s=None)

Set the font size of axes labels and tick marks.

INPUT:

  • s - integer, a font size in points.

If called with no input, return the current fontsize.

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: L.fontsize()
10
sage: L.fontsize(20)
sage: L.fontsize()
20

All the numbers on the axes will be very large in this plot:

sage: L
get_axes_range()

Returns a dictionary of the range of the axes for this graphics object. This is fall back to the ranges in get_minmax_data() for any value which the user has not explicitly set.

Warning

Changing the dictionary returned by this function does not change the axes range for this object. To do that, use the set_axes_range() method.

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: list(sorted(L.get_axes_range().items()))
[('xmax', 3.0), ('xmin', 1.0), ('ymax', 5.0), ('ymin', -4.0)]
sage: L.set_axes_range(xmin=-1)
sage: list(sorted(L.get_axes_range().items()))
[('xmax', 3.0), ('xmin', -1.0), ('ymax', 5.0), ('ymin', -4.0)]
get_minmax_data()

Return a dictionary whose keys give the xmin, xmax, ymin, and ymax data for this graphic.

Warning

The returned dictionary is mutable, but changing it does not change the xmin/xmax/ymin/ymax data. The minmax data is a function of the primitives which make up this Graphics object. To change the range of the axes, call methods xmin(), xmax(), ymin(), ymax(), or set_axes_range().

EXAMPLES:

sage: g = line([(-1,1), (3,2)])
sage: list(sorted(g.get_minmax_data().items()))
[('xmax', 3.0), ('xmin', -1.0), ('ymax', 2.0), ('ymin', 1.0)]

Note that changing ymax doesn’t change the output of get_minmax_data:

sage: g.ymax(10)
sage: list(sorted(g.get_minmax_data().items()))
[('xmax', 3.0), ('xmin', -1.0), ('ymax', 2.0), ('ymin', 1.0)]
plot(*args, **kwds)

Draw a 2d plot this graphics object, which just returns this object since this is already a 2d graphics object.

EXAMPLES:

sage: S = circle((0,0), 2)
sage: S.plot() is S
True
plot3d(z=0, **kwds)

Returns an embedding of this 2D plot into the xy-plane of 3D space, as a 3D plot object. An optional parameter z can be given to specify the z-coordinate.

EXAMPLES:

sage: sum([plot(z*sin(x), 0, 10).plot3d(z) for z in range(6)]) #long
save(filename=None, xmin=None, xmax=None, ymin=None, ymax=None, figsize=(6, 3.7082039324993699), figure=None, sub=None, savenow=True, dpi=100, axes=None, axes_labels=None, fontsize=None, frame=False, verify=True, aspect_ratio=None, gridlines=None, gridlinesstyle=None, vgridlinesstyle=None, hgridlinesstyle=None)

Save the graphics to an image file of type: PNG, PS, EPS, SVG, SOBJ, depending on the file extension you give the filename. Extension types can be: .png, .ps, .eps, .svg, and .sobj (for a Sage object you can load later).

EXAMPLES:

sage: c = circle((1,1),1,rgbcolor=(1,0,0))
sage: c.show(xmin=-1,xmax=3,ymin=-1,ymax=3)

To correct the aspect ratio of certain graphics, it is necessary to show with a ‘figsize‘ of square dimensions.

sage: c.show(figsize=[5,5],xmin=-1,xmax=3,ymin=-1,ymax=3)
sage: point((-1,1),pointsize=30, rgbcolor=(1,0,0))
set_aspect_ratio(ratio)

Set the aspect ratio.

INPUT:

  • ratio - a positive real number

EXAMPLES: We create a plot of a circle, and it doesn’t look quite round:

sage: P = circle((1,1), 1); P

So we set the aspect ratio and now it is round:

sage: P.set_aspect_ratio(1)
sage: P

Note that the aspect ratio is inherited upon addition (which takes the max of aspect ratios of objects whose aspect ratio has been set):

sage: P + circle((0,0), 0.5)           # still square

In the following example, both plots produce a circle that looks twice as wide as tall:

sage: Q = circle((0,0), 0.5); Q.set_aspect_ratio(2)
sage: P + Q
sage: Q + P
set_axes_range(xmin=None, xmax=None, ymin=None, ymax=None)

Set the ranges of the x and y axes.

INPUT:

  • xmin, xmax, ymin, ymax - floats

EXAMPLES:

sage: L = line([(1,2), (3,-4), (2, 5), (1,2)])
sage: L.set_axes_range(-1, 20, 0, 2)
sage: d = L.get_axes_range()
sage: d['xmin'], d['xmax'], d['ymin'], d['ymax']
(-1.0, 20.0, 0.0, 2.0)
show(**kwds)

Show this graphics image with the default image viewer.

OPTIONAL INPUT:

  • filename - (default: None) string

  • dpi - dots per inch

  • figsize - [width, height]

  • aspect_ratio - the perceived width divided by the perceived height. If the aspect ratio is set to 1, circles will look round. If it is set to 2 they will look twice as wide as they are tall. This is the aspect_ratio of the image, not of the frame that contains it. If you want to set the aspect ratio of the frame, use figsize.

  • axes - (default: True)

  • axes_labels - (default: None) list (or tuple) of two strings; the first is used as the label for the horizontal axis, and the second for the vertical axis.

  • fontsize - (default: current setting – 10) positive integer; used for axes labels; if you make this very large, you may have to increase figsize to see all labels.

  • frame - (default: False) draw a frame around the image

  • gridlines - (default: None) can be any of the following:

    • None, False: do not add grid lines.
    • True, “automatic”, “major”: add grid lines at major ticks of the axes.
    • “minor”: add grid at major and minor ticks.
    • [xlist,ylist]: a tuple or list containing two elements, where xlist (or ylist) can be any of the following.
      • None, False: don’t add horizontal (or vertical) lines.
      • True, “automatic”, “major”: add horizontal (or vertical) grid lines at the major ticks of the axes.
      • “minor”: add horizontal (or vertical) grid lines at major and minor ticks of axes.
      • an iterable yielding numbers n or pairs (n,opts), where n is the coordinate of the line and opt is a dictionary of MATPLOTLIB options for rendering the line.
  • gridlinesstyle, hgridlinesstyle, vgridlinesstyle - (default: None) a dictionary of MATPLOTLIB options for the rendering of the grid lines, the horizontal grid lines or the vertical grid lines, respectively.

  • linkmode - (default: False) If True a string containing a link

    to the produced file is returned.

EXAMPLES:

sage: c = circle((1,1), 1, rgbcolor=(1,0,0))
sage: c.show(xmin=-1, xmax=3, ymin=-1, ymax=3)

To correct the aspect ratio of certain graphics, it is necessary to show with a ‘figsize‘ of square dimensions.

sage: c.show(figsize=[5,5], xmin=-1, xmax=3, ymin=-1, ymax=3)

You can turn off the drawing of the axes:

sage: show(plot(sin,-4,4), axes=False)

You can also label the axes:

sage: show(plot(sin,-4,4), axes_labels=('x','y'))

You can turn on the drawing of a frame around the plots:

sage: show(plot(sin,-4,4), frame=True)

Add grid lines at the major ticks of the axes.

sage: c = circle((0,0), 1)
sage: c.show(gridlines=True)
sage: c.show(gridlines="automatic")
sage: c.show(gridlines="major")

Add grid lines at the major and minor ticks of the axes.

sage: u,v = var('u v')
sage: f = exp(-(u^2+v^2))
sage: p = plot_vector_field(f.gradient(), (u,-2,2), (v,-2,2))
sage: p.show(gridlines="minor")

Add only horizontal or vertical grid lines.

sage: p = plot(sin,-10,20)
sage: p.show(gridlines=[None, "automatic"])
sage: p.show(gridlines=["minor", False])

Add grid lines at specific positions (using lists/tuples).

sage: x, y = var('x, y')
sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2,             ...             (x,-2,2), (y,-2,2), plot_points=1000)
sage: p.show(gridlines=[[1,0],[-1,0,1]])

Add grid lines at specific positions (using iterators).

sage: def maple_leaf(t):
...     return (100/(100+(t-pi/2)^8))*(2-sin(7*t)-cos(30*t)/2)
sage: p = polar_plot(maple_leaf, -pi/4, 3*pi/2, rgbcolor="red",plot_points=1000) #long
sage: p.show(gridlines=( [-3,-2.75,..,3], xrange(-1,5,2) )) #long

Add grid lines at specific positions (using functions).

sage: y = x^5 + 4*x^4 - 10*x^3 - 40*x^2 + 9*x + 36
sage: p = plot(y, -4.1, 1.1)
sage: xlines = lambda a,b: [z for z,m in y.roots()]
sage: p.show(gridlines=[xlines, [0]], frame=True, axes=False)

Change the style of all the grid lines.

sage: b = bar_chart([-3,5,-6,11], rgbcolor=(1,0,0))
sage: b.show(gridlines=([-1,-0.5,..,4],True),             ...     gridlinesstyle=dict(color="blue", linestyle=":"))

Change the style of the horizontal or vertical grid lines separately.

sage: p = polar_plot(2 + 2*cos(x), 0, 2*pi, rgbcolor=hue(0.3))
sage: p.show(gridlines=True,             ...     hgridlinesstyle=dict(color="orange", linewidth=1.0),             ...     vgridlinesstyle=dict(color="blue", linestyle=":"))

Change the style of each grid line individually.

sage: x, y = var('x, y')
sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2,             ...             (x,-2,2), (y,-2,2), plot_points=1000)
sage: p.show(gridlines=(
...    [
...     (1,{"color":"red","linestyle":":"}),
...     (0,{"color":"blue","linestyle":"--"})
...    ],
...    [
...     (-1,{"rgbcolor":"red","linestyle":":"}),
...     (0,{"color":"blue","linestyle":"--"}),
...     (1,{"rgbcolor":"red","linestyle":":"}),
...    ]
...    ),
...    gridlinesstyle=dict(marker='x',rgbcolor="black"))

Grid lines can be added to contour plots.

sage: f = sin(x^2 + y^2)*cos(x)*sin(y)
sage: c = contour_plot(f, (x, -4, 4), (y, -4, 4), plot_points=100)
sage: c.show(gridlines=True, gridlinesstyle={'linestyle':':','linewidth':1, 'rgbcolor':'red'})

Grid lines can be added to matrix plots.

sage: M = MatrixSpace(QQ,10).random_element()
sage: matrix_plot(M).show(gridlines=True)
tick_label_color(c=None)

Set the color of the axes tick labels.

INPUT:

  • c - an RGB 3-tuple of numbers between 0 and 1

If called with no input, return the current tick_label_color setting.

EXAMPLES:

sage: p = plot(cos, (-3,3))
sage: p.tick_label_color()
(0, 0, 0)
sage: p.tick_label_color((1,0,0))
sage: p.tick_label_color()
(1.0, 0.0, 0.0)
sage: p
xmax(xmax=None)

EXAMPLES:

sage: g = line([(-1,1), (3,2)])
sage: g.xmax()
3.0
sage: g.xmax(10)
sage: g.xmax()
10.0
xmin(xmin=None)

EXAMPLES:

sage: g = line([(-1,1), (3,2)])
sage: g.xmin()
-1.0
sage: g.xmin(-3)
sage: g.xmin()
-3.0
ymax(ymax=None)

EXAMPLES:

sage: g = line([(-1,1), (3,2)])
sage: g.ymax()
2.0
sage: g.ymax(10)
sage: g.ymax()
10.0
ymin(ymin=None)

EXAMPLES:

sage: g = line([(-1,1), (3,2)])
sage: g.ymin()
1.0
sage: g.ymin(-3)
sage: g.ymin()
-3.0
class sage.plot.plot.GraphicsArray(array)

GraphicsArray takes a (m x n) list of lists of graphics objects and plots them all on one canvas.

__getitem__(i)
__init__(array)
__len__()
__set_figsize__(list)
__setitem__(i, g)
__str__()
__weakref__
list of weak references to the object (if defined)
_render(filename, dpi=None, figsize=(6, 3.7082039324993699), axes=None, **args)
render loops over all graphics objects in the array and adds them to the subplot.
_repr_()
append(g)
ncols()
nrows()
save(filename=None, dpi=100, figsize=(6, 3.7082039324993699), axes=None, **args)
save the graphics_array to (for now) a png called ‘filename’.
show(filename=None, dpi=100, figsize=(6, 3.7082039324993699), axes=None, **args)

Show this graphics array using the default viewer.

OPTIONAL INPUT:

  • filename - (default: None) string
  • dpi - dots per inch
  • figsize - [width, height] (same for square aspect)
  • axes - (default: True)
  • fontsize - positive integer
  • frame - (default: False) draw a frame around the image

EXAMPLES: This draws a graphics array with four trig plots and no axes in any of the plots.

sage: G = graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]])
sage: G.show(axes=False)
sage.plot.plot._plot(funcs, xrange, parametric=False, polar=False, fill=None, label='', randomize=True, **options)
sage.plot.plot.adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, adaptive_recursion=5, level=0)

The adaptive refinement algorithm for plotting a function f. See the docstring for plot for a description of the algorithm.

INPUT:

  • f - a function of one variable
  • p1, p2 - two points to refine between
  • adaptive_recursion - (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement.
  • adaptive_tolerance - (default: 0.01) how large a relative difference should be before the adaptive refinement code considers it significant; see documentation for generate_plot_points for more information. See the documentation for plot() for more information on how the adaptive refinement algorithm works.

OUTPUT:

  • list - a list of points to insert between p1 and p2 to get a better linear approximation between them

TESTS:

sage: from sage.plot.plot import adaptive_refinement
sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01, adaptive_recursion=0)
[]
sage: adaptive_refinement(sin, (0,0), (pi,0), adaptive_tolerance=0.01)
[(0.125000000000000*pi, 0.38268343236508978), (0.187500000000000*pi, 0.55557023301960218), (0.250000000000000*pi, 0.70710678118654746), (0.312500000000000*pi, 0.83146961230254524), (0.375000000000000*pi, 0.92387953251128674), (0.437500000000000*pi, 0.98078528040323043), (0.500000000000000*pi, 1.0), (0.562500000000000*pi, 0.98078528040323043), (0.625000000000000*pi, 0.92387953251128674), (0.687500000000000*pi, 0.83146961230254546), (0.750000000000000*pi, 0.70710678118654757), (0.812500000000000*pi, 0.55557023301960218), (0.875000000000000*pi, 0.38268343236508989)]

This shows that lowering adaptive_tolerance and raising adaptive_recursion both increase the number of subdivision points, though which one creates more points is heavily dependent upon the function being plotted.

sage: x = var('x')
sage: f(x) = sin(1/x)
sage: n1 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.01)); n1
15
sage: n2 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_recursion=10, adaptive_tolerance=0.01)); n2
79
sage: n3 = len(adaptive_refinement(f, (0,0), (pi,0), adaptive_tolerance=0.001)); n3
26
sage.plot.plot.adjust_figsize_for_aspect_ratio(figsize, aspect_ratio, xmin, xmax, ymin, ymax)

Adjust the figsize in case the user also specifies an aspect ratio.

INPUTS: figsize - a sequence of two positive real numbers aspect_ratio - a positive real number xmin, xmax, ymin, ymax - real numbers

EXAMPLES: This function is used mainly internally by plotting code so we explicitly import it:

sage: from sage.plot.plot import adjust_figsize_for_aspect_ratio

This returns (5,5), since the requested aspect ratio is 1 and the x and y ranges are the same, so that’s the right size rendered image to produce a 1:1 ratio internally. 5 is used instead of 3 since the image size is always adjusted to the larger of the figsize dimensions.

sage: adjust_figsize_for_aspect_ratio([3,5], 1, 0, 2, 0, 2)
(5, 5)

Here we give a scalar figsize, which is automatically converted to the figsize (figsize, figsize/golden_ratio).

sage: adjust_figsize_for_aspect_ratio(3, 1, 0, 2, 0, 2)
(3, 3)

Here we omit the aspect ratio so the figsize is just returned.

sage: adjust_figsize_for_aspect_ratio([5,6], None, 0, 2, 0, 2)
[5, 6]

Here we have an aspect ratio of 2, and since the x and y ranges are the same the returned figsize is twice as wide as tall:

sage: adjust_figsize_for_aspect_ratio([3,5], 2, 0, 2, 0, 2)
(5, 5/2)

Here the x range is rather large, so to get an aspect ratio where circles look twice as wide as they are tall, we have to shrink the y size of the image.

sage: adjust_figsize_for_aspect_ratio([3,5], 2, 0, 10, 0, 2)
(5, 1/2)
sage.plot.plot.generate_plot_points(f, xrange, plot_points=5, adaptive_tolerance=0.01, adaptive_recursion=5, randomize=True)

Calculate plot points for a function f in the interval xrange. The adaptive refinement algorithm is also automatically invoked with a relative adaptive tolerance of adaptive_tolerance; see below.

INPUT:

  • f - a function of one variable
  • p1, p2 - two points to refine between
  • plot_points - (default: 5) the minimal number of plot points. (Note however that in any actual plot a number is passed to this, with default value 200.)
  • adaptive_recursion - (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement.
  • adaptive_tolerance - (default: 0.01) how large the relative difference should be before the adaptive refinement code considers it significant. If the actual difference is greater than adaptive_tolerance*delta, where delta is the initial subinterval size for the given xrange and plot_points, then the algorithm will consider it significant.

OUTPUT:

  • a list of points (x, f(x)) in the interval xrange, which approximate the function f.

TESTS:

sage: from sage.plot.plot import generate_plot_points
sage: generate_plot_points(sin, (0, pi), plot_points=2, adaptive_recursion=0)
[(0.0, 0.0), (3.1415926535897931, 1.2246...e-16)]

sage: generate_plot_points(sin(x).function(x), (-pi, pi), randomize=False)
[(-3.1415926535897931, -1.2246...e-16), (-2.748893571891069,
-0.3826834323650898...), (-2.3561944901923448, -0.707106781186547...),
(-2.1598449493429825, -0.831469612302545...), (-1.9634954084936207,
-0.92387953251128674), (-1.7671458676442586, -0.98078528040323043),
(-1.5707963267948966, -1.0), (-1.3744467859455345,
-0.98078528040323043), (-1.1780972450961724, -0.92387953251128674),
(-0.98174770424681035, -0.831469612302545...), (-0.78539816339744828,
-0.707106781186547...), (-0.39269908169872414, -0.38268343236508978),
(0.0, 0.0), (0.39269908169872414, 0.38268343236508978),
(0.78539816339744828, 0.707106781186547...), (0.98174770424681035,
0.831469612302545...), (1.1780972450961724, 0.92387953251128674),
(1.3744467859455345, 0.98078528040323043), (1.5707963267948966, 1.0),
(1.7671458676442586, 0.98078528040323043), (1.9634954084936207,
0.92387953251128674), (2.1598449493429825, 0.831469612302545...),
(2.3561944901923448, 0.707106781186547...), (2.748893571891069,
0.3826834323650898...), (3.1415926535897931, 1.2246...e-16)]

This shows that lowering adaptive_tolerance and raising adaptive_recursion both increase the number of subdivision points. (Note that which creates more points is heavily dependent on the particular function plotted.)

sage: x = var('x')
sage: f(x) = sin(1/x)
sage: [len(generate_plot_points(f, (-pi, pi), plot_points=16, adaptive_tolerance=i, randomize=False)) for i in [0.01, 0.001, 0.0001]]
[97, 161, 275]

sage: [len(generate_plot_points(f, (-pi, pi), plot_points=16, adaptive_recursion=i, randomize=False)) for i in [5, 10, 15]]
[97, 499, 2681]
sage.plot.plot.graphics_array(array, n=None, m=None)

graphics_array take a list of lists (or tuples) of graphics objects and plots them all on one canvas (single plot).

INPUT:

  • array - a list of lists or tuples
  • n, m - (optional) integers - if n and m are given then the input array is flattened and turned into an n x m array, with blank graphics objects padded at the end, if necessary.

EXAMPLE: Make some plots of \sin functions:

sage: f(x) = sin(x)
sage: g(x) = sin(2*x)
sage: h(x) = sin(4*x)
sage: p1 = plot(f,-2*pi,2*pi,rgbcolor=hue(0.5))
sage: p2 = plot(g,-2*pi,2*pi,rgbcolor=hue(0.9))
sage: p3 = parametric_plot((f,g),0,2*pi,rgbcolor=hue(0.6))
sage: p4 = parametric_plot((f,h),0,2*pi,rgbcolor=hue(1.0))

Now make a graphics array out of the plots; then you can type either: ga.show() or ga.save().

sage: graphics_array(((p1,p2),(p3,p4)))

Here we give only one row:

sage: p1 = plot(sin,-4,4)
sage: p2 = plot(cos,-4,4)
sage: g = graphics_array([p1, p2]); print g
Graphics Array of size 1 x 2
sage: g.show()
sage.plot.plot.is_Graphics(x)

Return True if x is a Graphics object.

EXAMPLES:

sage: from sage.plot.plot import is_Graphics
sage: is_Graphics(1)
False
sage: is_Graphics(disk((0.0, 0.0), 1, (0, pi/2)))
True
sage.plot.plot.list_plot(data, plotjoined=False, **kwargs)

list_plot takes a single list of data, in which case it forms a list of tuples (i,di) where i goes from 0 to {\rm len}(data)-1 and di is the i^{th} data value, and puts points at those tuple values.

list_plot also takes a list of tuples (dxi, dyi) where dxi is the i^{th} data representing the x-value, and dyi is the i^{th} y-value. If plotjoined=True , then a line spanning all the data is drawn instead.

EXAMPLES:

sage: list_plot([i^2 for i in range(5)])

Here are a bunch of random red points:

sage: r = [(random(),random()) for _ in range(20)]
sage: list_plot(r,rgbcolor=(1,0,0))

This gives all the random points joined in a purple line:

sage: list_plot(r, plotjoined=True, rgbcolor=(1,0,1))

If you have separate lists of x values and y values which you want to plot against each other, use the zip command to make a single list whose entries are pairs of (x,y) values, and feed the result into list_plot:

sage: x_coords = [cos(t)^3 for t in srange(0, 2*pi, 0.02)]
sage: y_coords = [sin(t)^3 for t in srange(0, 2*pi, 0.02)]
sage: list_plot(zip(x_coords, y_coords))

If instead you try to pass the two lists as separate arguments, you will get an error message:

sage: list_plot(x_coords, y_coords)
...
TypeError: The second argument 'plotjoined' should be boolean (True or False).  If you meant to plot two lists 'x' and 'y' against each other, use 'list_plot(zip(x,y))'.

TESTS: We check to see that the x/y min/max data are set correctly.

sage: d = list_plot([(100,100), (120, 120)]).get_minmax_data()
sage: d['xmin']
100.0
sage: d['ymin']
100.0
sage.plot.plot.minmax_data(xdata, ydata, dict=False)

Returns the minimums and maximums of xdata and ydata.

If dict is False, then minmax_data returns the tuple (xmin, xmax, ymin, ymax); otherwise, it returns a dictionary whose keys are ‘xmin’, ‘xmax’, ‘ymin’, and ‘ymax’ and whose values are the corresponding values.

EXAMPLES:

sage: from sage.plot.plot import minmax_data
sage: minmax_data([], [])
(-1, 1, -1, 1)
sage: minmax_data([-1, 2], [4, -3])
(-1, 2, -3, 4)
sage: d = minmax_data([-1, 2], [4, -3], dict=True)
sage: list(sorted(d.items()))
[('xmax', 2), ('xmin', -1), ('ymax', 4), ('ymin', -3)]
sage.plot.plot.parametric_plot(funcs, *args, **kwargs)

parametric_plot takes two or three functions as a list or a tuple and makes a plot with the first function giving the x coordinates, the second function giving the y coordinates, and the third function (if present) giving the z coordinates.

In the 2d case, parametric_plot is equivalent to the plot command with the option parametric=True. In the 3d case, parametric_plot is equivalent to parametric_plot3d. See each of these functions for more help and examples.

INPUT:

  • funcs - 2 or 3-tuple of functions
  • other options - passed to plot or parametric_plot3d

EXAMPLES: We draw some 2d parametric plots:

sage: t = var('t')
sage: parametric_plot( (sin(t), sin(2*t)), (t, 0, 2*pi), rgbcolor=hue(0.6) )
sage: parametric_plot((1, t), (t, 0, 4))

Note that in parametric_plot, there is only fill or no fill.

sage: parametric_plot((t, t^2), (t, -4, 4), fill = True)

A filled Hypotrochoid:

sage: parametric_plot([cos(x) + 2 * cos(x/4), sin(x) - 2 * sin(x/4)], 0, 8*pi, fill = True)

sage: parametric_plot( (5*cos(x), 5*sin(x), x), (x,-12, 12), plot_points=150, color="red")

sage: y=var('y')
sage: parametric_plot( (5*cos(x), x*y, cos(x*y)), (x, -4,4), (y,-4,4))

TESTS:

sage: parametric_plot((x, t^2), (x, -4, 4))
...
ValueError: the number of functions and the number of free variables is not a possible combination for 2d or 3d parametric plots

sage: parametric_plot((1, x+t), (x, -4, 4))
...
ValueError: the number of functions and the number of free variables is not a possible combination for 2d or 3d parametric plots

sage: parametric_plot((-t, x+t), (x, -4, 4))
...
ValueError: the number of functions and the number of free variables is not a possible combination for 2d or 3d parametric plots

sage: parametric_plot((1, x+t, y), (x, -4, 4), (t, -4, 4))
...
ValueError: the number of functions and the number of free variables is not a possible combination for 2d or 3d parametric plots
sage.plot.plot.plot(*args, **kwds)

Use plot by writing

plot(X, ...)

where X is a Sage object (or list of Sage objects) that either is callable and returns numbers that can be coerced to floats, or has a plot method that returns a GraphicPrimitive object.

There are many other specialized 2D plot commands available in Sage, such as plot_slope_field, as well as various graphics primitives like Arrow; type sage.plot.plot? for a current list.

Type plot.options for a dictionary of the default options for plots. You can change this to change the defaults for all future plots. Use plot.reset() to reset to the default options.

PLOT OPTIONS:

  • plot_points - (default: 200) the minimal number of plot points.
  • adaptive_recursion - (default: 5) how many levels of recursion to go before giving up when doing adaptive refinement. Setting this to 0 disables adaptive refinement.
  • adaptive_tolerance - (default: 0.01) how large a difference should be before the adaptive refinement code considers it significant. See the documentation further below for more information, starting at “the algorithm used to insert”.
  • xmin - starting x value
  • xmax - ending x value
  • color - an RGB tuple (r,g,b) with each of r,g,b between 0 and 1, or a color name as a string (e.g., ‘purple’), or an HTML color such as ‘#aaff0b’.
  • detect_poles - (Default: False) If set to True poles are detected. If set to “show” vertical asymptotes are drawn.

APPEARANCE OPTIONS:

The following options affect the appearance of the line through the points on the graph of X (these are the same as for the line function):

INPUT:

  • alpha - How transparent the line is
  • thickness - How thick the line is
  • rgbcolor - The color as an RGB tuple
  • hue - The color given as a hue

Any MATPLOTLIB line option may also be passed in. E.g.,

  • linestyle - The style of the line, which is one of ‘–’ (dashed), ‘-.’ (dash dot), ‘-‘ (solid), ‘steps’, ‘:’ (dotted)
  • marker - “‘0’ (tickleft), ‘1’ (tickright), ‘2’ (tickup), ‘3’ (tickdown), ‘’ (nothing), ‘ ‘ (nothing), ‘+’ (plus), ‘,’ (pixel), ‘.’ (point), ‘1’ (tri_down), ‘3’ (tri_left), ‘2’ (tri_up), ‘4’ (tri_right), ‘<’ (triangle_left), ‘>’ (triangle_right), ‘None’ (nothing), ‘D’ (diamond), ‘H’ (hexagon2), ‘_’ (hline), ‘^’ (triangle_up), ‘d’ (thin_diamond), ‘h’ (hexagon1), ‘o’ (circle), ‘p’ (pentagon), ‘s’ (square), ‘v’ (triangle_down), ‘x’ (x), ‘|’ (vline)”
  • markersize - the size of the marker in points
  • markeredgecolor - the markerfacecolor can be any color arg
  • markeredgewidth - the size of the marker edge in points

FILLING OPTIONS: INPUT:

  • fill - (Default: None) One of:
    • “axis” or True: Fill the area between the function and the x-axis.
    • “min”: Fill the area between the function and its minimal value.
    • “max”: Fill the area between the function and its maximal value.
    • a number c: Fill the area between the function and the horizontal line y = c.
    • a function g: Fill the area between the function that is plotted and g.
    • a dictionary d (only if a list of functions are plotted): The keys of the dictionary should be integers. The value of d[i] specifies the fill options for the i-th function in the list. If d[i] == [j]: Fill the area between the i-th and the j-th function in the list. (But if d[i] == j: Fill the area between the i-th function in the list and the horizontal line y = j.)
  • fillcolor - (default: ‘automatic’) The color of the fill. Either ‘automatic’ or a color.
  • fillalpha - (default: 0.5) How transparent the fill is. A number between 0 and 1.

Note that this function does NOT simply sample equally spaced points between xmin and xmax. Instead it computes equally spaced points and add small perturbations to them. This reduces the possibility of, e.g., sampling sin only at multiples of 2\pi, which would yield a very misleading graph.

EXAMPLES: We plot the sin function:

sage: P = plot(sin, (0,10)); print P
Graphics object consisting of 1 graphics primitive
sage: len(P)     # number of graphics primitives
1
sage: len(P[0])  # how many points were computed (random)
225
sage: P          # render
sage: P = plot(sin, (0,10), plot_points=10); print P
Graphics object consisting of 1 graphics primitive
sage: len(P[0])  # random output
32
sage: P          # render

We plot with randomize=False, which makes the initial sample points evenly spaced (hence always the same). Adaptive plotting might insert other points, however, unless adaptive_recursion=0.

sage: p=plot(1, (x,0,3), plot_points=4, randomize=False, adaptive_recursion=0)
sage: list(p[0])
[(0.0, 1.0), (1.0, 1.0), (2.0, 1.0), (3.0, 1.0)]

Some colored functions:

sage: plot(sin, 0, 10, rgbcolor='#ff00ff')
sage: plot(sin, 0, 10, rgbcolor='purple')

We plot several functions together by passing a list of functions as input:

sage: plot([sin(n*x) for n in [1..4]], (0, pi))

The function \sin(1/x) wiggles wildly near 0. Sage adapts to this and plots extra points near the origin.

sage: plot(sin(1/x), (x, -1, 1))

Note that the independent variable may be omitted if there is no ambiguity:

sage: plot(sin(1/x), (-1, 1))

The algorithm used to insert extra points is actually pretty simple. On the picture drawn by the lines below:

sage: p = plot(x^2, (-0.5, 1.4)) + line([(0,0), (1,1)], rgbcolor='green')
sage: p += line([(0.5, 0.5), (0.5, 0.5^2)], rgbcolor='purple')
sage: p += point(((0, 0), (0.5, 0.5), (0.5, 0.5^2), (1, 1)), rgbcolor='red', pointsize=20)
sage: p += text('A', (-0.05, 0.1), rgbcolor='red')
sage: p += text('B', (1.01, 1.1), rgbcolor='red')
sage: p += text('C', (0.48, 0.57), rgbcolor='red')
sage: p += text('D', (0.53, 0.18), rgbcolor='red')
sage: p.show(axes=False, xmin=-0.5, xmax=1.4, ymin=0, ymax=2)

You have the function (in blue) and its approximation (in green) passing through the points A and B. The algorithm finds the midpoint C of AB and computes the distance between C and D. If that distance exceeds the adaptive_tolerance threshold (relative to the size of the initial plot subintervals), the point D is added to the curve. If D is added to the curve, then the algorithm is applied recursively to the points A and D, and D and B. It is repeated adaptive_recursion times (5, by default).

The actual sample points are slightly randomized, so the above plots may look slightly different each time you draw them.

We draw the graph of an elliptic curve as the union of graphs of 2 functions.

sage: def h1(x): return abs(sqrt(x^3  - 1))
sage: def h2(x): return -abs(sqrt(x^3  - 1))
sage: P = plot([h1, h2], 1,4)
sage: P          # show the result

We can also directly plot the elliptic curve:

sage: E = EllipticCurve([0,-1])
sage: plot(E, (1, 4), rgbcolor=hue(0.6))

We can change the line style to one of '--' (two hyphens, yielding dashed), '-.' (dash dot), '-' (solid), 'steps', ':' (dotted):

sage: plot(sin(x), 0, 10, linestyle='-.')

Sage currently ignores points that cannot be evaluated

sage: set_verbose(-1)
sage: plot(-x*log(x), (x,0,1))  # this works fine since the failed endpoint is just skipped.
sage: set_verbose(0)

This prints out a warning and plots where it can (we turn off the warning by setting the verbose mode temporarily to -1.)

sage: set_verbose(-1)
sage: plot(x^(1/3), (x,-1,1))
sage: set_verbose(0)

To plot the negative real cube root, use something like the following:

sage: plot(lambda x : RR(x).nth_root(3), (x,-1, 1))

We can detect the poles of a function:

sage: plot(gamma, (-3, 4), detect_poles = True).show(ymin = -5, ymax = 5)

We draw the Gamma-Function with its poles highlighted:

sage: plot(gamma, (-3, 4), detect_poles = 'show').show(ymin = -5, ymax = 5)

The basic options for filling a plot:

sage: p1 = plot(sin(x), -pi, pi, fill = 'axis')
sage: p2 = plot(sin(x), -pi, pi, fill = 'min')
sage: p3 = plot(sin(x), -pi, pi, fill = 'max')
sage: p4 = plot(sin(x), -pi, pi, fill = 0.5)
sage: graphics_array([[p1, p2], [p3, p4]]).show(frame=True, axes=False)

sage: plot([sin(x), cos(2*x)*sin(4*x)], -pi, pi, fill = {0: 1}, fillcolor = 'red', fillalpha = 1)

A example about the growth of prime numbers:

sage: plot(1.13*log(x), 1, 100, fill = lambda x: nth_prime(x)/floor(x), fillcolor = 'red')

Fill the area between a function and its asymptote:

sage: f = (2*x^3+2*x-1)/((x-2)*(x+1))
sage: plot([f, 2*x+2], -7,7, fill = {0: [1]}, fillcolor='#ccc').show(ymin=-20, ymax=20)

Fill the area between a list of functions and the x-axis:

sage: def b(n): return lambda x: bessel_J(n, x)
sage: plot([b(n) for n in [1..5]], 0, 20, fill = 'axis')

Note that to fill between the ith and jth functions, you must use dictionary key-value pairs i:[j]; key-value pairs like i:j will fill between the ith function and the line y=j:

sage: def b(n): return lambda x: bessel_J(n, x) + 0.5*(n-1)
sage: plot([b(c) for c in [1..5]], 0, 40, fill = dict([(i, [i+1]) for i in [0..3]]))
sage: plot([b(c) for c in [1..5]], 0, 40, fill = dict([(i, i+1) for i in [0..3]]))

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

sage: plot(sin(x^2), (x, -3, 3), figsize=[8,2])
sage: plot(sin(x^2), (x, -3, 3)).show(figsize=[8,2]) # These are equivalent

TESTS:

We do not randomize the endpoints:

sage: p = plot(x, (x,-1,1))
sage: p[0].xdata[0] == -1
True
sage: p[0].xdata[-1] == 1
True

We check to make sure that the x/y min/max data get set correctly when there are multiple functions.

sage: d = plot([sin(x), cos(x)], 100, 120).get_minmax_data()
sage: d['xmin']
100.0
sage: d['xmax']
120.0   

We check various combinations of tuples and functions, ending with tests that lambda functions work properly with explicit variable declaration, without a tuple.

sage: p = plot(lambda x: x,(x,-1,1))
sage: p = plot(lambda x: x,-1,1)
sage: p = plot(x,x,-1,1)
sage: p = plot(x,-1,1)
sage: p = plot(x^2,x,-1,1)
sage: p = plot(x^2,xmin=-1,xmax=2)
sage: p = plot(lambda x: x,x,-1,1)
sage: p = plot(lambda x: x^2,x,-1,1)
sage: p = plot(lambda x: 1/x,x,-1,1)
sage: f(x) = sin(x+3)-.1*x^3
sage: p = plot(lambda x: f(x),x,-1,1)

We check to handle cases where the function gets evaluated at a point which causes an ‘inf’ or ‘-inf’ result to be produced.

sage: p = plot(1/x, 0, 1)
sage: p = plot(-1/x, 0, 1)

Bad options now give better errors:

sage: P = plot(sin(1/x), (x,-1,3), foo=10)
...
RuntimeError: Error in line(): option 'foo' not valid.
sage.plot.plot.polar_plot(funcs, *args, **kwds)

polar_plot takes a single function or a list or tuple of functions and plots them with polar coordinates in the given domain.

This function is equivalent to the plot command with the option polar=True. For more help on options, see the documentation for plot.

INPUT:

  • funcs - a function
  • other options are passed to plot

EXAMPLES:

Here is a blue 8-leaved petal:

sage: polar_plot(sin(5*x)^2, (x, 0, 2*pi), color='blue')

A red figure-8:

sage: polar_plot(abs(sqrt(1 - sin(x)^2)), (x, 0, 2*pi), color='red')

A green limacon of Pascal:

sage: polar_plot(2 + 2*cos(x), (x, 0, 2*pi), rgbcolor=hue(0.3))

Several polar plots:

sage: polar_plot([2*sin(x), 2*cos(x)], (x, 0, 2*pi))

A filled spiral:

sage: polar_plot(sqrt, 0, 2 * pi, fill = True)

Fill the area between two functions:

sage: polar_plot(cos(4*x) + 1.5, 0, 2*pi, fill=0.5 * cos(4*x) + 2.5, fillcolor='orange').show(aspect_ratio=1)

Fill the area between several spirals:

sage: polar_plot([(1.2+k*0.2)*log(x) for k in range(6)], 1, 3 * pi, fill = {0: [1], 2: [3], 4: [5]})
sage.plot.plot.reshape(v, n, m)
sage.plot.plot.setup_for_eval_on_grid(v, xrange, yrange, plot_points)

INPUT:

  • v - a list of functions
  • xrange - 2 or 3 tuple (if 3, first is a variable)
  • yrange - 2 or 3 tuple
  • plot_points - a positive integer

OUTPUT:

  • g - tuple of fast callable functions
  • xstep - step size in xdirection
  • ystep - step size in ydirection
  • xrange - tuple of 2 floats
  • yrange - tuple of 2 floats

EXAMPLES:

sage: x,y = var('x,y')
sage: sage.plot.plot.setup_for_eval_on_grid([x^2 + y^2], (x,0,5), (y,0,pi), 11)
([<sage.ext... object at ...>],
 0.5,
 0.31415926535897931,
 (0.0, 5.0),
 (0.0, 3.1415926535897931))

We always plot at least two points; one at the beginning and one at the end of the ranges.

sage: sage.plot.plot.setup_for_eval_on_grid([x^2+y^2], (x,0,1), (y,-1,1), 1)
([<sage.ext... object at ...>],
1.0,
2.0,
(0.0, 1.0),
(-1.0, 1.0))
sage.plot.plot.show_default(default=None)

Set the default for showing plots using any plot commands. If called with no arguments, returns the current default.

If this is True (the default) then any plot object when displayed will be displayed as an actual plot instead of text, i.e., the show command is not needed.

EXAMPLES: The default starts out as True:

sage: show_default()
True

We set it to False.

sage: show_default(False)

We see that it is False.

sage: show_default()
False

Now plot commands will not display their plots by default.

Turn back on default display.

sage: show_default(True)
sage.plot.plot.to_float_list(v)

Given a list or tuple or iterable v, coerce each element of v to a float and make a list out of the result.

EXAMPLES:

sage: from sage.plot.plot import to_float_list
sage: to_float_list([1,1/2,3])
[1.0, 0.5, 3.0]
sage.plot.plot.var_and_list_of_values(v, plot_points)

INPUT:

  • v - (v0, v1) or (var, v0, v1); if the former return the range of values between v0 and v1 taking plot_points steps; if var is given, also return var.
  • plot_points - integer = 2 (the endpoints)

OUTPUT:

  • var - a variable or None
  • list - a list of floats

EXAMPLES:

sage: from sage.plot.plot import var_and_list_of_values
sage: var_and_list_of_values((var('theta'), 2, 5),  5)
(theta, [2.0, 2.75, 3.5, 4.25, 5.0])
sage: var_and_list_of_values((2, 5),  5)
(None, [2.0, 2.75, 3.5, 4.25, 5.0])
sage: var_and_list_of_values((var('theta'), 2, 5),  2)
(theta, [2.0, 5.0])
sage: var_and_list_of_values((2, 5),  2)
(None, [2.0, 5.0])
sage.plot.plot.xydata_from_point_list(points)

Returns two lists (xdata, ydata), each coerced to a list of floats, which correspond to the x-coordinates and the y-coordinates of the points.

The points parameter can be a list of 2-tuples or some object that yields a list of one or two numbers.

This function can potentially be very slow for large point sets.

Previous topic

2D Graphics

Next topic

Animated plots

This Page