Sage Tutorial for Symbolics and Plotting

This Sage worksheet is one of the tutorials developed for the MAA PREP Workshop "Sage: Using Open-Source Mathematics Software with Undergraduates" (funding provided by NSF DUE 0817071).  It is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA).

This tutorial has the following sections:

It assumes that one is familiar with the absolute basics of functions and evaluation in Sage.  We provide a (very) brief refresher.

  1. Make sure the syntax below for defining a function and getting a value makes sense.
  2. Then evaluate the cell by clicking the "evaluate" link, or by pressing Shift-Enter (hold down Shift while pressing the Enter key).
{{{id=134| f(x)=x^3+1 f(2) /// 9 }}}

Symbolic Expressions

In the first tutorial, we defined functions using notation similar to that one would use in (say) a calculus course.

There is a useful variant on this - defining expressions involving variables.  This will give us the opportunity to point out several important, and sometimes subtle, things.

In the cell below, we define an expression $FV$ which is the future value of an investment of \$100, compounded continuously.  We then substitute in values for $r$ and $t$ which calculate the future value for $t=5$ years and $r=5\%$ nominal interest.

{{{id=152| var('r,t') FV=100*e^(r*t) /// }}} {{{id=56| FV(r=.05,t=5) /// 128.402541668774 }}}

The previous cells point out several things to remember when working with symbolic expressions.  Some are fairly standard.

However, two others may be unfamiliar, especially if you have not used much mathematical software before.

Notice that when we define a function, we don't need to specify which variable has which value.  In the function defined below, we have already specified an order.

{{{id=136| FV2(r,t)=100*e^(r*t) FV2(.05,5) /// 128.402541668774 }}}

In this case it is clear that $r$ is first and $t$ is second.

But with 'FV=100*e^(r*t)', there is no particular reason $r$ or $t$ should be first.

{{{id=4| FV(r=.05,t=5); FV(t=5,r=.05) /// 128.402541668774 128.402541668774 }}}

This is why we receive a deprecation error message when we try to do $FV$ without explicitly mentioning the variables.

{{{id=6| FV(5,.05) /// __main__:3: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) 128.402541668774 }}}

In this case, the outcome is the same, since $rt=tr$!  Of course, in most expressions, one would not be so lucky, as the following example indicates.

{{{id=8| var('y') G = x*y^2 G(1,2); G(2,1) /// __main__:5: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) 4 2 }}}

Also remember that when we don't use function notation, we'll need to define our variables.

 

One of the great things we can do with expressions is manipulate them.  Let's make a typical expression.

{{{id=58| z = (x+1)^3 /// }}}

In the cells below, you'll notice something new: the character "#".  In Sage (and in Python), anything on a single line after the number/pound sign (the octothorp) is ignored.  We say that "#" is a comment character.  We use it below to mention alternative ways to do the same thing.

{{{id=81| expand(z) # or z.expand() /// x^3 + 3*x^2 + 3*x + 1 }}} {{{id=82| y = expand(z) y.factor() # or factor(y) /// (x + 1)^3 }}}

In the previous cell, we assigned the expression which is the expansion of $z$ to the variable $y$ with the first line.  After that, anything we want to do to the expansion of $z$ can be done by doing it to $y$.

There are more commands like this as well.  Notice that $z$ will no longer be $(x+1)^3$ after this cell is evaluated, since we've assigned $z$ to a (much more complex) expression.

{{{id=84| z = ((x - 1)^(3/2) - (x + 1)*sqrt(x - 1))/sqrt((x - 1)*(x + 1)) z.simplify_full() /// -2/sqrt(x + 1) }}} {{{id=140| z.simplify_rational() # Just simplify the fraction part of the expression by combining it. /// -2*sqrt(x - 1)/sqrt(x^2 - 1) }}}

This is a good place for a few reminders of basic help.

{{{id=142| z.simplify /// }}}

Finally, recall that you can get nicely typeset versions of the output in several ways.  

{{{id=86| show(z.simplify_rational()) ///
\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{2 \, \sqrt{x - 1}}{\sqrt{x^{2} - 1}}
}}}

Another Sage command that is useful in this context is "solve". 

Here, we solve the simple equation $x^2=-1$. 

{{{id=87| solve(x^2==-1,x) # solve x^2==-1 for x /// [x == -I, x == I] }}}

It's also possible to solve more than one expression simultaneously.

{{{id=89| solve([x^2==1,x^3==1],x) /// [[x == 1]] }}}

Basic 2D Plotting

One of the other basic uses of mathematics software is easy plotting.  Here, we include a brief introduction to the sorts of plotting which will prepare us to use Sage in calculus.   (There will be a separate tutorial for more advanced plotting techniques.)

Recall that we can generate a plot using fairly simple syntax.  Here, we define a function of $x$ and plot it between $-1$ and $1$.

{{{id=135| f(x)=x^3+1 plot(f,(x,-1,1)) /// }}}

We can give the plot a name, so that if we want to do something with the plot later, we don't have to type out the entire plot command.  Remember, this is called assigning the plot to the name/variable.

In the next cell, we give the plot the name $P$.

{{{id=19| P=plot(f,(x,-1,1)) /// }}}

One plot is nice, but one might want to superimpose plots as well.   For instance, the tangent line to $f$ at $x=0$ is just the line $y=1$, and we might want to show this together with the plot.  

So let's plot this line in a different color, and with a different style for the line, but over the same interval.  

{{{id=23| Q=plot(1,(x,-1,1),color="red", linestyle="--") Q /// }}}

Because we put $Q$ in a line by itself at the end, it shows.  We were able to use just one cell to define $Q$ and show it, by putting each command in a separate line in the same input cell.

Now to show the plots superimposed on each other, we simply add them.

{{{id=27| P+Q /// }}}

Suppose we wanted to view a detail of this. 

{{{id=31| (P+Q).show(xmin=-.1,xmax=.1,ymin=.99,ymax=1.01) /// }}}

Since the axes no longer cross in the frame of reference, Sage shows a short gap between the horizontal and vertical axes. 

 

There are many options one can pass in for various purposes.  

Usually (though not always) quotes are required for option values which are words or strings of characters, and not required for numerical values.

 

Two of the most useful of these options help in labeling graphs.

{{{id=35| plot(f,(x,-1,1),axes_labels=['$x$','$y$'],legend_label='$f(x)$',show_legend=True) /// }}} {{{id=21| P1 = plot(f,(x,-1,1),axes_labels=['$x$','$y$'],legend_label='$f(x)$') P2 = plot(sin,(x,-1,1),axes_labels=['$x$','$y$'],legend_label='$\sin(x)$',color='red') P1+P2 /// }}}

One additional useful note is that plots of functions with vertical asymptotes may need their vertical viewing range set manually; otherwise the asymptote may really go to infinity!

{{{id=47| plot(1/x^2,(x,-10,10),ymax=10) /// }}}

Remember, you can use the command "plot?" to find out about most of the options demonstrated above.

 

Below, you can experiment with several of the plotting options.

{{{id=151| var('x') @interact def plot_example(f=sin(x^2),r=range_slider(-5,5,step_size=1/4,default=(-3,3)), color=color_selector(widget='colorpicker'), thickness=(3,(1..10)), adaptive_recursion=(5,(0..10)), adaptive_tolerance=(0.01,(0.001,1)), plot_points=(20,(1..100)), linestyle=['-','--','-.',':'], gridlines=False, fill=False, frame=False, axes=True ): show(plot(f, (x,r[0],r[1]), color=color, thickness=thickness, adaptive_recursion=adaptive_recursion, adaptive_tolerance=adaptive_tolerance, plot_points=plot_points, linestyle=linestyle, fill=fill if fill else None), gridlines=gridlines, frame=frame, axes=axes) /// }}}

Basic 3D Plotting

There are several mechanisms for viewing three-dimensional plots in Sage, but we will stick to the default option in the notebook interface, which is via Java applets from the program Jmol.

Plotting a 3D plot is similar to plotting a 2D plot, but we need to specify ranges for two variables instead of one.

{{{id=69| g(x,y)=sin(x^2+y^2) plot3d(g,(x,-5,5),(y,-5,5)) /// }}}

There is a lot you can do with the 3D plots.  

When using the "plot3d" command, the first variable range specified is plotted along the usual "x" axis, while the second range specified is plotted along the usual "y" axis.

The plot above is somewhat crude because the function is not sampled enough times - this is fairly rapidly changing function, after all.  We can make the plot smoother by telling Sage to sample the function using a grid of 300 by 300 points.  Sage then samples the function at 90,000 points!

{{{id=74| plot3d(g,(x,-5,5),(y,-5,5),plot_points=300) /// }}}

As with 2D plots, we can superimpose 3D plots by adding them together.  

Note that in this one, we do not define the functions, but only use expressions (see the first set of topics in this tutorial), so it is wisest to define the variables ahead of time.

{{{id=148| var('x,y') b = 2.2 P=plot3d(sin(x^2-y^2),(x,-b,b),(y,-b,b), opacity=.7) Q=plot3d(0, (x,-b,b), (y,-b,b), color='red') P+Q /// }}}

As usual, only the last command shows up in the notebook, though clearly all are evaluated.  This also demonstrates that many of the same options work for 3D plots as for 2D plots.

We close this tutorial with a cool plot that we define implicitly as a 3D contour plot. 

{{{id=145| var('x,y,z') T = golden_ratio p = 2 - (cos(x + T*y) + cos(x - T*y) + cos(y + T*z) + cos(y - T*z) + cos(z - T*x) + cos(z + T*x)) r = 4.78 implicit_plot3d(p, (x, -r, r), (y, -r, r), (z, -r, r), plot_points=50, color='yellow') /// }}}

The next tutorial will use all that you have learned about Sage basics, symbolics, and plotting in a specific mathematical venue - the calculus sequence!

{{{id=147| /// }}}