Sharedplot_tour_2D.ipynbOpen in CoCalc

2-dimensional plots of functions with SageMath

%display latex

Plot of a symbolic function

A minimal plot:

plot(sin(x^2), (x, 0, 4))

Adding some options:

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

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)
<classx'sage.plot.graphics.Graphics'>\verb|<class|\phantom{\verb!x!}\verb|'sage.plot.graphics.Graphics'>|
print(g1)
Graphics object consisting of 1 graphics primitive
g1

Plot objects can be added:

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

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

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

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
99
e^(i*pi)
e(9π)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-1

Symbolic functions versus Python functions

Let us consider a symbolic function:

f(x) = sin(x^2)
f
x  sin(x2)x \ {\mapsto}\ \sin\left(x^{2}\right)
f(x)
sin(x2)\sin\left(x^{2}\right)
f(3)
sin(9)\sin\left(9\right)

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

plot(f(x), (x,0,4))

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

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
<functionxf1xatx0x7f7a473af938>\verb|<function|\phantom{\verb!x!}\verb|f1|\phantom{\verb!x!}\verb|at|\phantom{\verb!x!}\verb|0x7f7a473af938>|
f1(1)
sin(1)\sin\left(1\right)
plot(f1, (0,4))
f1(x)
cos(x)\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))

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

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

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

plot(lambda x: f2(x, 1), (0,4))

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

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)]\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
g1 = list_plot(data, marker='D', axes_labels=[r"$x$", r"$y$"])
g1

An alternative is to use line:

g2 = line(data, color='red')
g2
g1+g2

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