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, color='green')
sage: P = polygon([[1,2], [5,6], [5,0]], color='red')
sage: G + P  # show it

We draw a circle and a curve:

sage: circle((1,1), 1) + plot(x^2, (x,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, (x,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, (x,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, (x,0,5)), figsize=[8,4])

Note that the axes will not cross if the data is not on both sides of both axes, even if it is quite close:

sage: plot(x^3,(x,1,10))

When the labels have quite different orders of magnitude or are very large, scientific notation (the e notation for powers of ten) is used:

sage: plot(x^2,(x,480,500))  # no scientific notation
sage: plot(x^2,(x,300,500))  # scientific notation on y-axis

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]], color='blue')
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,color=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)],\
...                color=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, color='blue') + \
...       plot(x*cos(x), -4,4, color='red') + \
...       plot(tan(x),-4,4, color='green')
...
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))], color='black')
sage: P += line([(8,0),(8,f(8))], color='black')
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, color='black')
sage: P += plot(f, (1, 8.5), thickness=3)
sage: P    # show the result

NUMERICAL PLOTTING:

Sage includes Matplotlib, which 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(os.path.join(SAGE_TMP, 'sage.png'))

We test that imshow works as well, verifying that Trac ticket 2900 is fixed in Matplotlib.

sage: imshow([[(0,0,0)]])
<matplotlib.image.AxesImage object at ...>
sage: savefig(os.path.join(SAGE_TMP, 'foo.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))

Verify that a clean sage startup does not import matplotlib:

sage: os.system("sage -c \"if 'matplotlib' in sys.modules: sys.exit(1)\"")
0

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.
  • Jason Grout (2009-09-05): shifted axes and grid functionality over to matplotlib; fixed a number of smaller issues.
class sage.plot.plot.Graphics

Bases: sage.structure.sage_object.SageObject

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,aspect_ratio=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.5;
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,color=hue(c + p*(x/h)))
sage: G.show(figsize=[5,5])

TESTS:

From trac #4604, ensure Graphics can handle 3d objects:

sage: g = Graphics()
sage: g += sphere((1, 1, 1), 2)
sage: g.show()
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

Notice that some may prefer axes labels which are not typeset:

sage: plot(sin(x), (x, 0, 10), axes_labels=['x','y'])
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)]
matplotlib(filename=None, xmin=None, xmax=None, ymin=None, ymax=None, figsize=None, figure=None, sub=None, axes=None, axes_labels=None, fontsize=None, frame=False, verify=True, aspect_ratio=None, gridlines=None, gridlinesstyle=None, vgridlinesstyle=None, hgridlinesstyle=None, axes_pad=0.02)

Return a matplotlib figure object representing the graphic

EXAMPLES:

sage: c = circle((1,1),1)
sage: print c.matplotlib()
Figure(480x296.656)

To obtain the first matplotlib axes object inside of the figure, you can do something like the following.

sage: p=plot(sin(x), (x, -2*pi, 2*pi))
sage: figure=p.matplotlib()
sage: axes=figure.axes[0]

For input parameters, see the documentation for the show() method (this function accepts all except the transparent argument).

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, dpi=100, savenow=True, *args, **kwds)

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,color='red')
sage: filename=os.path.join(SAGE_TMP, 'test.png')
sage: c.save(filename, xmin=-1,xmax=3,ymin=-1,ymax=3)

To correct the aspect ratio of certain graphics, you can set the aspect_ratio to 1:

sage: c.save(filename, aspect_ratio=1, xmin=-1, xmax=3, ymin=-1, ymax=3)

You could also just make the dimensions of the picture square using figsize:

sage: c.save(filename, figsize=[5,5], xmin=-1, xmax=3, ymin=-1, ymax=3)        
sage: point((-1,1),pointsize=30, color='red')

By default, the figure grows to include all of the graphics and text, so the final image may not be exactly the figure size you specified.

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.

  • transparent - (default: False) If True, make the background transparent.

  • axes_pad - (default: 0.02) The percentage of the axis range that is added to each end of each axis. This helps avoid problems like clipping lines because of line-width, etc. To get axes that are exactly the specified limits, set axes_pad to zero.

EXAMPLES:

sage: c = circle((1,1), 1, color='red')
sage: c.show(xmin=-1, xmax=3, ymin=-1, ymax=3)

To correct the aspect ratio of certain graphics, you can set the aspect_ratio to 1

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

You could also just make the dimensions of the picture square using figsize

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. Putting something in dollar signs formats it as a mathematical expression:

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)

You can make the background transparent:

sage: plot(sin(x), (x, -4, 4), transparent=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, color="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], color='red')
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, color=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,{"color":"red","linestyle":":"}),
...     (0,{"color":"blue","linestyle":"--"}),
...     (1,{"color":"red","linestyle":":"}),
...    ]
...    ),
...    gridlinesstyle=dict(marker='x',color="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, 'color':'red'})

Grid lines can be added to matrix plots.

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

By default, Sage increases the horizontal and vertical axes limits by a certain percentage in all directions. This is controlled by the axes_pad parameter. Increasing the range of the axes helps avoid problems with lines and dots being clipped because the linewidth extends beyond the axes. To get axes limits that are exactly what is specified, set axes_pad to zero. Compare the following two examples

sage: plot(sin(x), (x, -pi, pi),thickness=2)+point((pi, -1), pointsize=15)
sage: plot(sin(x), (x, -pi, pi),thickness=2,axes_pad=0)+point((pi, -1), pointsize=15)
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)

Bases: sage.structure.sage_object.SageObject

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

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.SelectiveFormatter(formatter, skip_values)

This matplotlib formatter selectively omits some tick values and passes the rest on to a specified formatter.

EXAMPLES:

This example is almost straight from a matplotlib example.

sage: from sage.plot.plot import SelectiveFormatter
sage: import matplotlib.pyplot as plt
sage: import numpy
sage: fig=plt.figure()
sage: ax=fig.add_subplot(111)
sage: t = numpy.arange(0.0, 2.0, 0.01)
sage: s = numpy.sin(2*numpy.pi*t)
sage: line=ax.plot(t, s)
sage: formatter=SelectiveFormatter(ax.xaxis.get_major_formatter(),skip_values=[0,1])
sage: ax.xaxis.set_major_formatter(formatter)
sage: fig.savefig(os.path.join(SAGE_TMP, 'test.png'))
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.125*pi, 0.38268343236508978), (0.1875*pi, 0.55557023301960218), (0.25*pi, 0.70710678118654746), (0.3125*pi, 0.83146961230254524), (0.375*pi, 0.92387953251128674), (0.4375*pi, 0.98078528040323043), (0.5*pi, 1.0), (0.5625*pi, 0.98078528040323043), (0.625*pi, 0.92387953251128674), (0.6875*pi, 0.83146961230254546), (0.75*pi, 0.70710678118654757), (0.8125*pi, 0.55557023301960218), (0.875*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, initial_points=None)

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.
  • initial_points - (default: None) a list of points that should be evaluated.

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: from sage.plot.plot import generate_plot_points
sage: generate_plot_points(lambda x: x^2, (0, 6), plot_points=2, adaptive_recursion=0, initial_points = [1,2,3])
[(0.0, 0.0), (1.0, 1.0), (2.0, 4.0), (3.0, 9.0), (6.0, 36.0)]

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),color=hue(0.5))
sage: p2 = plot(g,(-2*pi,2*pi),color=hue(0.9))
sage: p3 = parametric_plot((f,g),(0,2*pi),color=hue(0.6))
sage: p4 = parametric_plot((f,h),(0,2*pi),color=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,color='red')

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

sage: list_plot(r, plotjoined=True, color='purple')

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, or a vector of dimension 2 or 3.
  • 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), color=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)], (x,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))

sage: t=var('t')
sage: parametric_plot( vector((sin(t), sin(2*t))), (t, 0, 2*pi), color='green')
sage: parametric_plot( vector([t, t+1, t^2]), (t, 0, 1)) 

TESTS:

sage: parametric_plot((x, t^2), (x, -4, 4))
...
ValueError: there are more variables than variable ranges

sage: parametric_plot((1, x+t), (x, -4, 4))
...
ValueError: there are more variables than variable ranges

sage: parametric_plot((-t, x+t), (x, -4, 4))
...
ValueError: there are more variables than variable ranges

sage: parametric_plot((1, x+t, y), (x, -4, 4), (t, -4, 4))
...
ValueError: there are more variables than variable ranges

sage: parametric_plot((1, x, y), 0, 4)
...
ValueError: there are more variables than variable ranges
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
  • exclude - (Default: None) values which are excluded from the plot range. Either a list of real numbers, or an equation in one variable.

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, color='purple')
sage: plot(sin, 0, 10, color='#ff00ff')

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))

Via the matplotlib library, Sage makes it easy to tell whether a graph is on both sides of both axes, as the axes only cross if the origin is actually part of the viewing area:

sage: plot(x^3,(x,0,2))  # this one has the origin
sage: plot(x^3,(x,1,2))  # this one does not

Another thing to be aware of with axis labeling is that when the labels have quite different orders of magnitude or are very large, scientific notation (the e notation for powers of ten) is used:

sage: plot(x^2,(x,480,500))  # this one has no scientific notation
sage: plot(x^2,(x,300,500))  # this one has scientific notation on y-axis

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)], color='green')
sage: p += line([(0.5, 0.5), (0.5, 0.5^2)], color='purple')
sage: p += point(((0, 0), (0.5, 0.5), (0.5, 0.5^2), (1, 1)), color='red', pointsize=20)
sage: p += text('A', (-0.05, 0.1), color='red')
sage: p += text('B', (1.01, 1.1), color='red')
sage: p += text('C', (0.48, 0.57), color='red')
sage: p += text('D', (0.53, 0.18), color='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), color=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), axes_labels=['$x$','$y$']) # These labels will be nicely typeset
sage: plot(sin(x^2), (x, -3, 3), axes_labels=['x','y']) # These will not
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

A example with excluded values:

sage: plot(floor(x), (x, 1, 10), exclude = [1..10])

We exclude all points where prime_pi makes a jump:

sage: jumps = [n for n in [1..100] if prime_pi(n) != prime_pi(n-1)]
sage: plot(lambda x: prime_pi(x), (x, 1, 100), exclude = jumps)

Excluded points can also be given by an equation:

sage: g(x) = x^2-2*x-2
sage: plot(1/g(x), (x, -3, 4), exclude = g(x) == 0, ymin = -5, ymax = 5)
exclude and detect_poles can be used together::
sage: f(x) = (floor(x)+0.5) / (1-(x-0.5)^2) sage: plot(f, (x, -3.5, 3.5), detect_poles = ‘show’, exclude = [-3..3], ymin = -5, ymax = 5)

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), color=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]})

Exclude points at discontinuities:

sage: polar_plot(log(floor(x)), (x, 1, 4*pi), aspect_ratio = 1, exclude = [1..12])
sage.plot.plot.reshape(v, n, m)
sage.plot.plot.setup_for_eval_on_grid(v, xrange, yrange, plot_points)

This function is deprecated. Please use sage.plot.misc.setup_for_eval_on_grid instead. Please note that that function has slightly different calling and return conventions which make it more generally applicable.

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)
doctest:...: DeprecationWarning: sage.plot.plot.setup_for_eval_on_grid is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable
([<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)
doctest:...: DeprecationWarning: var_and_list_of_values is deprecated.  Please use sage.plot.misc.setup_for_eval_on_grid; note that that function has slightly different calling and return conventions which make it more generally applicable
(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.

TESTS:

sage: from sage.plot.plot import xydata_from_point_list
sage: xydata_from_point_list([CC(0), CC(1)])   # ticket 8082
([0.0, 1.0], [0.0, 0.0])

Previous topic

2D Graphics

Next topic

Animated plots

This Page