My Coding > Programming language > Python > Python libraries and packages > Python SymPy > Parametric curves with SymPy

Parametric curves with SymPy

Parametric curves, are curves where coordinates are given as a functions of some parameters. Very common, physical time is used as a parameter. These curves are very popular in many physical problems, where it is easier to define coordinates or other independent physical properties, as a parameters of some independent value.

Very often, these curves are not functions, because they can have many Y values for the given X.

For more details, please watch video about Parametric equations with Python, SymPy and Matplotlib Slider

Spiral

Spiral is a very simple example of parametric curve. It can be described by the following equations: x = t * cos(t); y = t * sin(t); It is very easy to plot this parametric curve with parametric function from SymPy. Learn more about 2D spiral.


from sympy import *    
from sympy.plotting import plot_parametric
t = symbols('t')

x = t*cos(t)
y = t*sin(t)
plot_parametric(x, y, (t, 0, 10*pi))

3D spiral

3D parametric curve is the same things, but in the 3D space. It can be described by equations: x = t * cos(t); y = t * sin(t); z = t. To plot this curve, it is necessary to use plot3d_parametric_line


from sympy import *    
from sympy.plotting import plot3d_parametric_line
t = symbols('t')

x = t * cos(t)
y = t * sin(t)
z = t

plot3d_parametric_line(x, y, z, (t, 0, 10*pi))

Plotting few parametric curves

Sometimes you need to plot few different parametric curves on the same graph. It is possible to do with parametric function, but the syntax will be slightly different.

Let’s draw the trajectory of a thrown stone for few different angles. From mechanics we can write simple equations. If the stone will thrown with initial speed V and angle α, then we can calculate: x = Vx * t = V * cos(α) * t; y = Vy * t – g*t2/2 = V * sin(α) * t – g*t2/2;

We will plot few curves for different angles, 60, 45, and 30 degree. To do this, it is necessary to use plot_parametric differently.

All curves should be supplied to one plot_parametric as a tuples of X, Y ans parameter range. Such parameters as a color, label etc. for each curve should be modified later. Also, if it is necessary to modify some parameters later, you need to prohibit to display it immediately with how=False parameter.

For more explanations, check this part of video about plotting few parametric curves.


from sympy import *
from sympy.plotting import plot_parametric

t = symbols('t')

def rad(a):
    return a*2*pi/360

def X(a, v):
    return cos(rad(a))*v*t

def Y(a, v):
    g = 9.8
    return sin(rad(a))*v*t - 0.5*g*t**2

V = 20.0

p = plot_parametric((X(60, V), Y(60, V), (t, 0, 3.5)),
                    (X(45, V), Y(45, V), (t, 0, 3.0)),
                    (X(30, V), Y(30, V), (t, 0, 2.5)),
                    show=False, legend=True)
p[0].line_color = 'red'
p[0].label = '60 degree'
p[1].line_color = 'blue'
p[1].label = '45 degree'
p[2].line_color = 'green'
p[2].label = '30 degree'

p.show()

Butterfly curve

One of the beautiful example of the parametric curve, is a butterfly curve, which given by following equations: x = sin(t)*(ecos(t) – 2cos(4t) – sin5(t/12)); y = cos(t)*(ecos(t) – 2cos(4t) – sin5(t/12))

In this example, I will make a script to make a video of the process, how this butterfly is plotting. Actually, this script will only make few images of an intermediate state of butterfly plotting, and these images can be linked to video later on.

This plot will consist of two elements – butterfly curve itself and big nice red dot at the pint of plotting. Butterfly curve will be plotted traditionally with plot_parametric, but to add red dot, we it will be necessary to use backend matplotlib structure of this plot. And later this plot will be made for different angles with small step.

We will plot butterfly for different completeness step and save every result to a graphical file, and steps will be increased with small value.

Red dot will be plotted on the axeview of the image, and axeview will be selected with MatplotlibBackend() function.

Also, to calculate value of sympy function, one can use function subs(). To calculate exponent evalue in sympy, use E**value

For example, if you want to calculate x = et, when t = 0, you can use:


from sympy import *
t = symbols('t')
x = E**t
print(x.subs(t, 0)) # 1

Then the standard routine to plot image is to create plot and save it


def sympy_subplot(plot):
    backend = MatplotlibBackend(plot)
    backend.process_series()
    backend.fig.tight_layout()
    return backend.ax[0], backend
ax, backend = sympy_subplot(p)
ax.plot([x.subs(t, angle)], [y.subs(t,angle)], 'o', c='r')
ax.figure.savefig(f'buterfly_{idx:04d}.png', dpi=200)

After each image savings, it is necessary to close backend, otherwise they will be kept in memory.

To see more details, please watch this tutorial.


from sympy import *
from sympy.plotting import plot_parametric
from sympy.plotting.plot import MatplotlibBackend
import matplotlib.pyplot as plt

def sympy_subplot(plot):
    backend = MatplotlibBackend(plot)
    backend.process_series()
    backend.fig.tight_layout()
    return backend.ax[0], backend

t = symbols('t')

x = sin(t)*(E**cos(t) - 2*cos(4*t) - sin(t/12)**5)
y = cos(t)*(E**cos(t) - 2*cos(4*t) - sin(t/12)**5)

for idx in range(1, int(12*pi/0.01)):
    angle = idx * 0.01
    p = plot_parametric(x, y, (t, 0, angle), xlim=(-4,4), ylim=(-4,4),
                        line_color='blue', show=False)
    ax, backend = sympy_subplot(p)
    # add additional plots
    ax.plot([x.subs(t, angle)], [y.subs(t,angle)], 'o', c='r')
    ax.figure.savefig(f'buterfly_{idx:04d}.png', dpi=200)
    backend.close()

It is possible to see, that SymPy, is very easy to use for simple task, but when the task stat to be more complicated, it started to be very inconvenient, because it is necessary to use Matplotlib bckground. Therefore, it is a good tool for basic samples for learning of some symbolic equations, but not really suitable for big projects.


Published: 2022-09-11 03:07:21
Updated: 2022-09-30 21:58:26

Last 10 artitles


9 popular artitles

© 2020 MyCoding.uk -My blog about coding and further learning. This blog was writen with pure Perl and front-end output was performed with TemplateToolkit.