| Hosted by CoCalc | Download
Kernel: SageMath 8.1

2-dimensional plots of functions with SageMath

%display latex

Plot of a symbolic function

A minimal plot:

plot(sin(x^2), (x, 0, 4))
Image in a Jupyter notebook

Adding some options:

plot(sin(x^2), (x,0,4), color='red', thickness=2, axes_labels=[r"$\xi$", r"$y$"])
Image in a Jupyter notebook

The list of options, along with some examples of use, is accessible via

plot?

It is also accessible online.

Storing the plot object in a Python variable:

g1 = plot(sin(x^2), (x,0,4), color='red', thickness=2, axes_labels=[r"$x$", r"$y$"])
type(g1)
[removed]\renewcommand{\Bold}[1]{\mathbf{#1}}\verb|[removed]|
print(g1)
Graphics object consisting of 1 graphics primitive
g1
Image in a Jupyter notebook

Plot objects can be added:

g2 = plot(cos(x^2), (x,0,4), color='green', linestyle='--', thickness=2)
show(g1 + g2)
Image in a Jupyter notebook

The command show can be used to display the object g1+g2 with extra options:

show(g1+g2, gridlines=True, aspect_ratio=1, title='A beautiful graphic')
Image in a Jupyter notebook

The documentation for all possible options of show is returned by

g1.show?

It is also accessible online here.

Saving the plot in a pdf file (with the same options as in show):

(g1+g2).save("plot_sinx2_cosx2.pdf", gridlines=True, aspect_ratio=1, title='A beautiful graphic')

Adding graphic objects in a Python loop:

chebyshev_T?
g = Graphics() # an empty graphic object for i in range(10): g += plot(chebyshev_T(i,x), (x,-1,1), color=hue(i/10), legend_label=r"$T_{}(x)$".format(i)) show(g, axes_labels=[r"$x$", r"$y$"], legend_loc='upper right')
Image in a Jupyter notebook

Side remark: in the above code, we have implicitely redefined the Python variable i as an integer denoting the loop index, while i was predefined as the imaginary number ii such that i2=1i^2=-1. Consequently, we have now

i
9\renewcommand{\Bold}[1]{\mathbf{#1}}9
e^(i*pi)
e(9π)\renewcommand{\Bold}[1]{\mathbf{#1}}e^{\left(9 \, \pi\right)}

To restore the use of the Python name i for the imaginary number, it suffices to run

restore('i')
e^(i*pi)
1\renewcommand{\Bold}[1]{\mathbf{#1}}-1

Symbolic functions versus Python functions

Let us consider a symbolic function:

f(x) = sin(x^2)
f
x  sin(x2)\renewcommand{\Bold}[1]{\mathbf{#1}}x \ {\mapsto}\ \sin\left(x^{2}\right)
f(x)
sin(x2)\renewcommand{\Bold}[1]{\mathbf{#1}}\sin\left(x^{2}\right)
f(3)
sin(9)\renewcommand{\Bold}[1]{\mathbf{#1}}\sin\left(9\right)

We can plot f(x) as we did above for sin(x^2):

plot(f(x), (x,0,4))
Image in a Jupyter notebook

It is also possible to pass the function f itself (not the symbolic expression f(x)), along with the lower and upper boundaries for the argument of f required in the plot, without having to specify any name for this argument:

plot(f, (0,4))
Image in a Jupyter notebook

This second way of plotting function is actually the one that must be used for the plot of Python functions:

def f1(x): if x<2: return sin(x) return cos(x)
f1
[removed]\renewcommand{\Bold}[1]{\mathbf{#1}}\verb|[removed]|
f1(1)
sin(1)\renewcommand{\Bold}[1]{\mathbf{#1}}\sin\left(1\right)
plot(f1, (0,4))
Image in a Jupyter notebook
f1(x)
cos(x)\renewcommand{\Bold}[1]{\mathbf{#1}}\cos\left(x\right)
# trace("f1(x)")
# diff(f1, x)

Actually, if we use the first method, we obtain a strange result:

plot(f1(x), (x,0,4))
Image in a Jupyter notebook

This occurs because the argument f1(x) of the function plot is evaluated prior to any loop on the values of x within the specified interval. Since for the symbolic variable x one has

bool(x<2)
False\renewcommand{\Bold}[1]{\mathbf{#1}}\mathrm{False}

the function f1 always returns cos(x), hence the plot.

What about plotting Python functions with more than one argument? For instance suppose we want to plot the following function for some fixed value of the argument a:

def f2(x, a): if x<a: return a*sin(x) return a*cos(x)
plot(f2, (0,4))
verbose 0 (3749: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 200 points. verbose 0 (3749: plot.py, generate_plot_points) Last error message: 'f2() takes exactly 2 arguments (1 given)'
Image in a Jupyter notebook

plot(f2, (0,4)) would return an error here. A first solution would be to wrap f2 into a single-argument Python function:

def f2_wrap(x): a = 1 return f2(x,a) plot(f2_wrap, (0,4))
Image in a Jupyter notebook

A better solution is to use create an anonymous function with the Python keyword lambda:

plot(lambda x: f2(x, 1), (0,4))
Image in a Jupyter notebook

In particular, it is very usefull in loops:

g = Graphics() for i in range(10): a = 4/9*i g+=plot(lambda x: f2(x, a), (0,4), color=hue(i/10)) g
Image in a Jupyter notebook

Plot from data

Let us consider a list of values, of the type (xi,yi)(x_i, y_i):

data = [(numerical_approx(i/10, digits=2), numerical_approx(sin((i/10)^2))) for i in range(1, 40)] data
[(0.10,0.00999983333416666),(0.20,0.0399893341866342),(0.30,0.0898785491980110),(0.40,0.159318206614246),(0.50,0.247403959254523),(0.60,0.352274233275090),(0.70,0.470625888171158),(0.80,0.597195441362392),(0.90,0.724287174370143),(1.0,0.841470984807897),(1.1,0.935616001553386),(1.2,0.991458348191686),(1.3,0.992903651094118),(1.4,0.925211520788168),(1.5,0.778073196887921),(1.6,0.549355436427127),(1.7,0.248946786673153),(1.8,0.0982485937451087),(1.9,0.451465752161423),(2.0,0.756802495307928),(2.1,0.954627771660216),(2.2,0.991868757310913),(2.3,0.837769480165098),(2.4,0.499641883116902),(2.5,0.0331792165475568),(2.6,0.458951486377690),(2.7,0.845133411657217),(2.8,0.999902258547975),(2.9,0.849363378505467),(3.0,0.412118485241757),(3.1,0.184164779400673),(3.2,0.727877870349737),(3.3,0.994432209303195),(3.4,0.844895943776026),(3.5,0.311119354981127),(3.6,0.383542755412610),(3.7,0.901675770066391),(3.8,0.954495430240921),(3.9,0.477637144914013)]\renewcommand{\Bold}[1]{\mathbf{#1}}\left[\left(0.10, 0.00999983333416666\right), \left(0.20, 0.0399893341866342\right), \left(0.30, 0.0898785491980110\right), \left(0.40, 0.159318206614246\right), \left(0.50, 0.247403959254523\right), \left(0.60, 0.352274233275090\right), \left(0.70, 0.470625888171158\right), \left(0.80, 0.597195441362392\right), \left(0.90, 0.724287174370143\right), \left(1.0, 0.841470984807897\right), \left(1.1, 0.935616001553386\right), \left(1.2, 0.991458348191686\right), \left(1.3, 0.992903651094118\right), \left(1.4, 0.925211520788168\right), \left(1.5, 0.778073196887921\right), \left(1.6, 0.549355436427127\right), \left(1.7, 0.248946786673153\right), \left(1.8, -0.0982485937451087\right), \left(1.9, -0.451465752161423\right), \left(2.0, -0.756802495307928\right), \left(2.1, -0.954627771660216\right), \left(2.2, -0.991868757310913\right), \left(2.3, -0.837769480165098\right), \left(2.4, -0.499641883116902\right), \left(2.5, -0.0331792165475568\right), \left(2.6, 0.458951486377690\right), \left(2.7, 0.845133411657217\right), \left(2.8, 0.999902258547975\right), \left(2.9, 0.849363378505467\right), \left(3.0, 0.412118485241757\right), \left(3.1, -0.184164779400673\right), \left(3.2, -0.727877870349737\right), \left(3.3, -0.994432209303195\right), \left(3.4, -0.844895943776026\right), \left(3.5, -0.311119354981127\right), \left(3.6, 0.383542755412610\right), \left(3.7, 0.901675770066391\right), \left(3.8, 0.954495430240921\right), \left(3.9, 0.477637144914013\right)\right]

We can plot it with list_plot:

g1 = list_plot(data) g1
Image in a Jupyter notebook
g1 = list_plot(data, marker='D', axes_labels=[r"$x$", r"$y$"]) g1
Image in a Jupyter notebook

An alternative is to use line:

g2 = line(data, color='red') g2
Image in a Jupyter notebook
g1+g2
Image in a Jupyter notebook

Plotting data from a file

fi = open("data.d", 'r') # open file in read-only mode ('r') fi.readline() # skip first line (comments) data = [] # empty list for line in fi: # loop on the file lines xs, ys = line.split(' ') # xs, ys = strings separated by ' ' data.append((float(xs), float(ys))) # conversion and add to the list fi.close() data
[(0.1,0.00999983),(0.2,0.0399893),(0.3,0.0898786),(0.4,0.159318),(0.5,0.247404),(0.6,0.352274),(0.7,0.470626),(0.8,0.597195),(0.9,0.724287),(1.0,0.841471),(1.1,0.935616),(1.2,0.991458),(1.3,0.992904),(1.4,0.925211),(1.5,0.778073),(1.6,0.549356),(1.7,0.248947),(1.8,0.0982486),(1.9,0.451466),(2.0,0.756802),(2.1,0.954628),(2.2,0.991869),(2.3,0.83777),(2.4,0.499642),(2.5,0.0331792),(2.6,0.458952),(2.7,0.845133),(2.8,0.999902),(2.9,0.849363),(3.0,0.412118),(3.1,0.184164),(3.2,0.727878),(3.3,0.994432),(3.4,0.844896),(3.5,0.311119),(3.6,0.383543),(3.7,0.901676),(3.8,0.954496),(3.9,0.477637)]\renewcommand{\Bold}[1]{\mathbf{#1}}\left[\left(0.1, 0.00999983\right), \left(0.2, 0.0399893\right), \left(0.3, 0.0898786\right), \left(0.4, 0.159318\right), \left(0.5, 0.247404\right), \left(0.6, 0.352274\right), \left(0.7, 0.470626\right), \left(0.8, 0.597195\right), \left(0.9, 0.724287\right), \left(1.0, 0.841471\right), \left(1.1, 0.935616\right), \left(1.2, 0.991458\right), \left(1.3, 0.992904\right), \left(1.4, 0.925211\right), \left(1.5, 0.778073\right), \left(1.6, 0.549356\right), \left(1.7, 0.248947\right), \left(1.8, -0.0982486\right), \left(1.9, -0.451466\right), \left(2.0, -0.756802\right), \left(2.1, -0.954628\right), \left(2.2, -0.991869\right), \left(2.3, -0.83777\right), \left(2.4, -0.499642\right), \left(2.5, -0.0331792\right), \left(2.6, 0.458952\right), \left(2.7, 0.845133\right), \left(2.8, 0.999902\right), \left(2.9, 0.849363\right), \left(3.0, 0.412118\right), \left(3.1, -0.184164\right), \left(3.2, -0.727878\right), \left(3.3, -0.994432\right), \left(3.4, -0.844896\right), \left(3.5, -0.311119\right), \left(3.6, 0.383543\right), \left(3.7, 0.901676\right), \left(3.8, 0.954496\right), \left(3.9, 0.477637\right)\right]
list_plot(data)
Image in a Jupyter notebook