Plotting with Sagetex

Sagetex let's you easily make quick 2D plots for inclusion in your documents. This simple code: SagetexPlot1 (.tex) produces a quick using the plotting power of the worlds most powerful open source CAS.

MyGraphBeing able to turn out graphs quickly and easily makes sagetex a useful package but if you're interested in creating a beautifully crafted document then Sage's plotting abilities aren't good enough. The TikZ 2.0 manual explains some of the problems with using plotting software on page 84-85; graphics and text can end up having

  • different line widths
  • different fonts
  • different size fonts
  • inconsistent colors

If you want the best possible graphics then designing graphics with Tikz (and Pgfplots) is more time consuming but the results are much better. It's true, but there's a problem that gets explained on page 223: "Often, you will want to plot points that are given via a function like f (x) = x sin x. Unfortunately, TEX does not really have enough computational power to generate the points on such a function efficiently (it is a text processing program, after all). However, if you allow it, TEX can try to call external programs that can easily produce the necessary points. Currently, TikZ knows how to call gnuplot.".

Sagetex can also be used to do the computational heavy lifting, it just won't be as convenient. This post explains the procedure: "To insert this code in a $latex \LaTeX$ document, all we have to do is wrap it in asagesilent environment (or sageblock if you want it displayed), and call \sagestr{output} inside of a tikzpicture environment". It took some playing around before I could get things to work but the results were worth the trouble.

Sagetex and the tkz-fct package

Start by looking at the beautiful graphics created with the packages from Altermundus. This example uses sagetex to create the graph from page 13 of the tkz-fct 1.6c manual; a graph which required Gnuplot to handle the plotting. Here it is running with sagetex calling Sage to handle the computations.

SagetexTkzfct1Here's the code:  SagetexTkzfct1 (.tex)

The work is inside a sagesilent block:
t = var('t')
x_coords = [t for t in srange(-5.0,5.0,.1)]
y_coords = [2*t^2/(t^2+1) for t in srange(-5.0,5.0,.1)]
output = ""
for i in range(0,len(x_coords)-1):
output += r"\draw[red, thick] (%f cm ,%f cm)--(%f cm ,%f cm);"%(x_coords[i],y_coords[i],x_coords[i+1],y_coords[i+1])

The x coordinates go from -5 to 5 with a step size of .1 (100 points) and the  y coordinates are calculated using Sage. The  points are put into a text string, output, which creates TikZ commands which draw line segments between consecutive points. After all the work is done, a \sagestr{output} inserts the text into the $latex \LaTeX$ document. Sagetex uses Sage to calculate a list of points and Tikz commands take care of making everything look beautiful. With the Sagemath Cloud, basic graphs like these are easy to create.

Plotting a function and its derivative

The problem with relying on the Altermundus packages for plotting is that a lot of the macros rely on calculations, directly or indirectly,  with Gnuplot. So as long as you don't rely on many too many features, you can get the look and feel of the tkz-fct package. This example is from page 69 of the tkz-fct 1.6c manual; and was modifed to rely on the sagetex package:

Alterm2Notice:

  1. Sage is used to calculate the derivative and the plot of each is just a sequence of points connected together.
  2. There's code that only prints points as long as a point and the point after it would be on the screen. Consequently you don't need to know the x-values of either function that will show up on the screen.
  3. The red curve has such a large derivative (in the negative sense that it appears prematurely chopped off.

To get around the problem of point 3, you can try making the step size even smaller (.001 instead of .01) but this runs into a problem on Sagemath cloud and even on my local tex installation: too many points have been sampled. I can fix this on my local system by increasing the buffer setting stored in the texmf.cnf file. For Linux you need to find the directory of the file on your computer, open up the terminal and cd (change directory) to that directory. You need administrator rights to change the file so

sudo gedit texmf.cnf

will open the file with gedit (make sure you have this installed on your computer). My file said

buff_size = 200000

which I changed to 1000000 and, after saving, closed the texmf.cnf file. Adjusting the step size to .002 for the red graph and I was able to get the graph to show all the way to the end of the screen.

Alt2I don't know of any way to modify Sagemath Cloud. Here is the code that runs in Sagemath Cloud: Altermund2 (.tex)

Well, thanks to some advice from Dr William Stein, the driving force behind Sage, Sage Cell Server, and Sagemath Cloud, we can change the buffer size for Sagemath Cloud, too. His comments are below, with a picture. It looks like the picture is stored in a temporary file so I'll put a screenshot below. Pressing the "Build" tab and typing in the command

buf_size=1000000 pdflatex -synctex=1 -interact=nonstopmode Altermund2.tex

into the box as he indicates will give Sagemath Cloud the ability to create the picture.

IncreaseBufferHere's the output:

IncreaseBufferBIf/when these LaTeX package writers use Sage as the computational engine Sagemath Cloud will be indispensable.

While I've managed to follow the advice to get Sage involved in TikZ plotting, I've been unable to insert the output string from sagetex into the tikzpicture environment for pgfplots. In order to get the code to compile properly, I've had to include \begin{tikzpicture} ... \end{tikzpicture} as part of the output string.

SageTikZHere's a copy of the code: SageTikZ (.tex)

Sagetex for 3D plotting in pgfplots

The basic procedure of using Tikz/Pgfplots ability to plot off of a set of points and of using sage and sagetex to create the points on the fly and put them into the tikzpicture code followed by inserting them as a sagestring extends to 3D plotting as well. Here's a proof of concept example:

ThreeDgraphingChange the step from 0.20 to 0.25 and observe how the mesh change. The calculation of the rows has been done for you with Sage. You can download the tex file for your own experimentation: ThreeDgraphing (.tex)

Polar equations

SagePolarSagetex can combine with pgfplots/TikZ to create polar plots: SagePolar  (.tex)

Sagetex and Implicit Plots

ImplicitPlotConnectedDownload file: ImplicitPlotConnected  (.tex)

Sagetex can plot implicitly. Whether it's the code above from the Sagemath website or the example (below) that you'll see in a typical Calculus book the power of Sage can be harnessed with a little extra code.

ImplicitPlot2ImplicitPlot2  (.tex)

The required code is:
P = p.matplotlib()
R = P.get_children()[1]
S = R.collections[0]
r = S.get_paths()[0]
v = r.vertices
xvals = v[:,0]
yvals = v[:,1]

The code is over my head but the important takeaway is that r = S.get_paths()[0] will contain the list of points because the graph is connected. If there's more than one piece, then there will be an  r = S.get_paths()[1] as well. The other part of the code that's important is size=0.17pt  as well. That makes the points about the size of the line that connects them which will make the graph look better if there are too few points plotted in a particular region.

If the implicit plot is not connected then the code needs to be revised. A for loop will get the points for piece j.

for j in range(0,len(R.collections)):
r = S.get_paths()[j]
v = r.vertices
xvals=v[:,0]
yvals=v[:,1]

ImplicitPlotDisconnectedDownload the file: ImplicitPlotDisconnected  (tex)

Here's a rotated hyperbola:

ImplicitPlottingDownload the code:  ImplicitPlotting (tex)

Sagetex and Python Plotting

Plotting with the sagetex package in your LaTeX documents gives you the option of plotting with Python. The most popular plotting option in Python is matplotlib.  More examples can be found at wiki.scipy.org; here's two.SagetexPythonDownload the code: SagetexPython  (.tex)

SagetexPython2Download the code: SagetexPython2  (.tex)

Sage Graphics

In addition to using sagetex to plot with tikz, pgfplots, and Python (using matplotlib) you can also create graphics with Sage.

SagePlotThis page has examples of graphics created with Sage. The one above is my favorite. Can you do that with Tikz? Here's the code: SagePlot  (tex)

sagetex with pgfplots template

Zeta

A bit of an improvement with this latest template: The minimum/maximum values of x and y along with the step size are the variables to control the picture. The IF-THEN-ELSE will check if a point is on the screen and (if it isn't) it will set the y value to infinity. If it is on the screen then the proper coordinate is created. Now adding the option "unbounded coords=jump" will jump over coordinates with a y value of infinity so the graph will be disconnected. This improves over adding two plots together.

Plot template: zeta (.tex)

Sagetex Plotting: scaled axes

GridSagetex

 

A quick summary: LaTeX is the best document preparation system. Sage is the best open source computer algebra system. (LaTeX package creators:) Sage can be the engine for plotting (it's better than gnuplot). Sage should be the engine for plotting; it's distributed under GPL but gnuplot has a more restrictive license. And Sage lets you take advantage of Python graphics and Sage graphics. Although sagetex can be the engine for computations, it wasn't designed to be. This is my wishful thinking for eliminating the math weakness in LaTeX calculations with the best open source software out there. So it shouldn't be a surprise that it doesn't always play nicely with other packages--- package developers should think about (PLEASE) designing packages to take advantage of Sage as the math engine (or at least offer support for using it as an engine).

Sagetex works best with pgfplots; it doesn't play as well with the Altermundus packages. I've also found that you avoid inserting a \sagestr command into the tikzpicture environment. Instead, \sagestr should be used to insert the entire tikzpicture environment into the LaTeX document. For best results use sagetex with pgfplots. A case in point is if you want to scale the axes. Trying to scale the axes with Altermundus packages leads to problems. The latest template combines the look and feel of the template here along with ability to scale the axes--see that post for a little more information about the plotting parameters. You can see in the screenshot that the y axis has been compressed to half its normal length. In this latest template I've used Sage to plot the function, calculate it's derivative at a point and use that derivative in plotting the tangent.

Download the file: GridSagetex (.tex)

Riemann Sums

Sage's calculating power makes it a logical choice for creating graphics illustrating Riemann sums. This version creates the rectangles using the left hand endpoint for the height. Since packages tend to be developed without thinking about using sagetex, creating the rectangles was a little awkward. I got around the problem creating a plot for each rectangle:

for i in range(0,NumRec):
output += r"\addplot+[opacity=.5,solid,color=Peach,fill=Peach!40!white, mark=none] coordinates {"
output += r"(%f,%f) (%f,%f)"%(a+i*delta,f(a+i*delta),(a+(i+1)*delta),f(a+i*delta))
output += r"}\closedcycle;"

Not very elegant but it works.

LeftHand

Download the file: LeftHand   (.tex)  RightHand  (.tex)  Midpoint  (.tex)  LowerRiemann  (.tex)  UpperRiemann  (.tex)

lapdf package

EllipseLaPdf

 

The lapdf package "...pro­vides the means to use PDF draw­ing prim­i­tives to pro­duce high qual­ity, col­ored graph­ics.". It covers a lot of basic precalculus/calculus mathematics and seems to "work" with sagetex. The documentation isn't particularly good but if you download the zip file there are lots of examples you can use as a starting point. One nice feature is the ability to graph ellipses based on the center, major and minor axes lengths, and the angle of rotation. I've combined it with the sagetex package to create ellipses, and label the center and axes. To avoid having to wade through the documentation, I've added a version with commentary.

Download template: Ellipse1  (.tex) with sagetex

Documentation plot explained: packageLapdf  (.tex)

Cantor Function

CantorFcn

Download file: CantorFunction  (.tex)

Sagetex Plotting Templates

There are 2 templates on the Handouts page which are good enough to handle most functions, especially at the high school level--they've got the added benefit that by not using sagetex they are easier to run when you don't have access to Sage. But when the functions get more complicated, such as the Cantor function above, I've found myself cobbling together code to get the look and feel of the templates. The two Sagetex templates add correspond to those on the Handouts page. Template 1 will look familiar:

SagetexPlottingTemplate

 

Template 1 is set up with 3 "simple" functions--functions that are easily written with Sage. I've also adjusted the thickness of the tick marks of the axes. The zeta function, which I'm calling "simple" because it has built in support from Sage has a circle around where where the function is changing so quickly that it stops before the page has ended. This situation, described in Plotting a function and its derivative can be handled, in some cases, by increasing the number of points plotted--but sometimes this leads to too many points to plot. Reader Lazza has suggested (in the comment posted at the bottom of the page) increasing the number of points plotted for just that small section. The code for template 1 includes Lazza's suggestions to show how it's done for the zeta function. Template 2 is the has the magnifying glass and I've worked it too include complicated functions plus a vertical line:

SagetexPlottingTemplateSPY

 

You can see that the zeta function is now graphed to the bottom of the page. The magnifying glass, along with complicated functions provides another application of Lazza's suggestion. Like the zeta function, I've increased the step size because if you don't the magnifying glass will reveal the defects. Here is what it looks like in the magnifying glass with the default step size of .01:

SagetexSPYorig

 

You can see the Weierstrass function isn't as chaotic and the Fourier series is sharp.

There's too much going on in these templates, so it pays to be aware of two important options illustrated below. To turn of the graph paper look "both" has been changed to "none" (circled in green below). I've added a # symbol to start the line which comments out the command for axes (in green rectangle), letting us see the graph in a frame.

STa

 

With just the graph paper turned off it looks like this:

STb

 

Since the coding of the functions is quite different between the templates it helps to have both. If you want simple functions with the magnifying glass, for example, then it's just a matter of copying the functions of Template 1 into Template 2.

Template 2 shows just how powerful combining sagetex and LaTeX can be.

DOWNLOAD THE TEMPLATES

Template 1 download: SagetexPlottingTemplate

SagetexPlottingTemplate

 

Template 2 download: SagetexPlottingTemplateSPY

SagetexPlottingTemplateSPY

 

Implicit Plots Revisited

Earlier I had looked into Implicit Plots and found a way to (see above) but there were two cases depending on whether the plots were connected or disconnected. Recently I found a way of determining the points that Sage is using to construct the plots. This eliminates the need for two cases BUT we have to take more care in plotting the graph. Here's an example to clarify the situation: The key code is

x,y = var('x,y')
gridDim = 250
xmin = -3
xmax = 3
deltax = (xmax-xmin)/(gridDim-1)
ymin = -3
ymax = 3
deltay = (ymax-ymin)/(gridDim-1)
xvals = []
yvals = []

f(x,y)= x^3-x-y^2
P1=implicit_plot(f,(x,-3,3),(y,-3,3),plot_points=gridDim)
C1 = P1._objects[0]
for i in range(0,gridDim):
for j in range(0,gridDim):
if abs(C1.xy_data_array[i][j])<.02:
xvals += [-2+j*(3.5/(gridDim-1))]
yvals += [-1+i*(2/(gridDim-1))]

Be aware that WordPress isn't keeping the proper (and necessary) formatting of the python code, so you'll need to look at the code from the file. The gridDim is the number of points on each side of the side of the grid. Since the plot is going from x=-3 to x=3 and y=-3 to y=3 there are (250)x(250) points that will be turned "on" if they are on the curve and "off" if they are not on the curve. That means the change in x is deltax = (xmax-xmin)/(gridDim-1). If that's confusing think of x=-1 to 1 with gridDim=3. The points would be on x=-1, x=0, and x=1., so the change in x is 1--which is (1-(-1))/(3-1)=1. Also  be aware that implicit plot is solving the equation f(x,y)=0. In order to have it plotted by the computer I chose to consider the point on the curve if it was "close" by making sure

if abs(C1.xy_data_array[i][j])<.02:

Here is the resulting plot.

Implicit1

 

Here is the code for the plotImplicit1  (.tex)

Changing .02 to ..03 would result in a thicker plot.Making it .01 would result in an even thinner plot. As is you can see the problem with plotting implicitly. Since most points are turned off, there aren't many points that are on the screen. The result is that we don't have a nice plot. And there is a problem if you keep increasing the dimension of gridDim. With gridDim=400 for example, there are 400x400=160,000 points and sagetex won't work.This problem can be solved by adopting Lazza's suggestion.Since most points in the grid are going to be off, we can divide up the region into pieces. Certainly points from x=-3 to x=-2 aren't on the curve so I broke the region up from x=-2 to 1.5 which will get the circle plus a bit of the second piece and then took the second piece and plotted the top half and the bottom half. The result of 3 implicit plots chained together looks like this:

Implicit2

Now the implicit plot looks more like we want.. Here is the file that created itImplicit2  (.tex).The first piece of code

:f(x,y)= x^3-x-y^2
P1=implicit_plot(f,(x,-2,1.5),(y,-1,1),plot_points=gridDim)
C1 = P1._objects[0]
for i in range(0,gridDim):
for j in range(0,gridDim):
if abs(C1.xy_data_array[i][j])<.02:
xvals += [-2+j*(3.5/(gridDim-1))]
yvals += [-1+i*(2/(gridDim-1))]

could of course be improved on even further: graph from x=--1.2 to 1.5. Or maybe just the circle to avoid wasted points in between the 2 pieces. But I think you get the idea: by breaking the implicit plot into pieces sagetex can handle implicit plots whether they are connected or not. 

Leave a Reply

Your email address will not be published. Required fields are marked *

AlphaOmega Captcha Classica  –  Enter Security Code