Using matplotlib for Matrix Transformation Demo

In this post, I will introduce my demonstration about matrix transformation using matplotlib. The purpose of this demo is give us a useful tool to explore how a matrix can transform a shape. The final result is given by below image:

Selection_153

What is transformation matrix?

In linear algreba 1, linear transformations can be represented by matrices. If T is a linear transformation mapping R^n to R^m and \vec x is a column vector with n entries, then

T( \vec x ) = \mathbf{A} \vec x

For some m \times n matrix A, called the transformation matrix of T.

Setup

In this part, I will discuss about important parts in my code.

We will transform a square represented by 4 points

origin_matrix = np.matrix([
[ui_ox.val, ui_oy.val],
[ui_ox.val + 1, ui_oy.val],
[ui_ox.val + 1, ui_oy.val+1],
[ui_ox.val, ui_oy.val + 1]])

Selection_148

User can change values of ui_ox.val and ui_oy.val (which represent original position of shape) through two sliders

# original controller
Button(plt.axes([0.1, 0.2, 0.8, 0.04]), "Original Position")
ax_ox = plt.axes([0.1, 0.16, 0.35, 0.02])
ui_ox = Slider(ax_ox, '', -2, 2, valinit=0)
ax_oy = plt.axes([0.55, 0.16, 0.35, 0.02])
ui_oy = Slider(ax_oy, '', -2, 2, valinit=0)

Selection_149

The transform matrix can be controlled through 4 sliders

# transformation controller
Button(plt.axes([0.1, 0.1, 0.8, 0.04]), "Transformation Matrix")
ax_t00 = plt.axes([0.1, 0.05, 0.35, 0.02])
ui_t00 = Slider(ax_t00, '', -5, 5, valinit=0)
ax_t01 = plt.axes([0.55, 0.05, 0.35, 0.02])
ui_t01 = Slider(ax_t01, '', -5, 5, valinit=-0)
ax_t10 = plt.axes([0.1, 0.01, 0.35, 0.02])
ui_t10 = Slider(ax_t10, '', -5, 5, valinit=0)
ax_t11 = plt.axes([0.55, 0.01, 0.35, 0.02])
ui_t11 = Slider(ax_t11, '', -5, 5, valinit=0)

Selection_151The transformed shape represented by result matrix

result_matrix = (transform_matrix * origin_matrix.transpose()).transpose()

Finally, We draw shapes by Polygon function

ax.add_patch(Polygon(origin_matrix, color='black'))
ax.add_patch(Polygon(result_matrix, color='red', alpha=0.4))

Selection_152

Experiment

The second part, we will use this tool to examize some basic transformations by a matrix.

Rotation

For rotation by an angle \theta clockwise about the origin 1 the functional form is x' = x \cos \theta + y \sin \theta and y' = -x \sin \theta + y \cos \theta. Written in matrix form, this becomes:

\begin{bmatrix}  x' \\  y'  \end{bmatrix}  = \begin{bmatrix}  cos \theta & sin \theta \\  - sin \theta & cos \theta  \end{bmatrix}  \begin{bmatrix}  x \\  y  \end{bmatrix}

Let \theta = \pi / 4 (45 degrees), we have a transformation matrix:

\begin{bmatrix}  \frac{\sqrt{2}}{2} & \frac{\sqrt{2}}{2} \\  - \frac{\sqrt{2}}{2} & \frac{\sqrt{2}}{2}  \end{bmatrix}  \sim \begin{bmatrix}  0.707 & 0.707 \\  - 0.707 & 0.707  \end{bmatrix}

Selection_154

Shearing

For shear mapping (visually similar to slanting), there are two possibilities.

A shear parallel to the x axis has x’ = x + ky and y’ = y. Written in matrix form, this becomes:

\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} 1 & k \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}

A shear parallel to the y axis has x’ = x and y’ = y + kx, which has matrix form:

\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ k & 1 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}

Let k = 3, we have two transformation matrices:

\begin{bmatrix}  1 & 3 \\  0 & 1  \end{bmatrix},  \begin{bmatrix}  1 & 0 \\  3 & 1  \end{bmatrix}

out

Reflection

To reflect a vector about a line that goes through the origin 1, let \scriptstyle \vec{l} = (l_x, l_y) be a vector in the direction of the line:

\mathbf{A} = \frac{1}{\lVert\vec{l}\rVert^2} \begin{bmatrix} l_x^2 - l_y^2 & 2 l_x l_y \\ 2 l_x l_y & l_y^2 - l_x^2 \end{bmatrix}

Let l_1 = (1, 0) (reflect through $Ox$) and l_2 = (1, -1) (reflect through y=-x), we have two transformation matrices:

\begin{bmatrix}   1 & 0 \\    0 & -1  \end{bmatrix},   \begin{bmatrix}   0 & -1 \\    -1 & 0  \end{bmatrix}

out

Complete Code

# __author__ = 'rain'

from pylab import *
import matplotlib.pyplot as plt
from matplotlib.widgets import Button, Slider

fig = plt.figure()
subplots_adjust(left=0.1, bottom=0.4)
ax = fig.add_subplot(111, xlim=(-6, 6), ylim=(-6, 6))
plt.grid()
ax.set_aspect('equal')


def draw(val):
    origin_matrix = np.matrix([[ui_ox.val, ui_oy.val],
                               [ui_ox.val + 1, ui_oy.val],
                               [ui_ox.val + 1, ui_oy.val+1],
                               [ui_ox.val, ui_oy.val + 1]])
    transform_matrix = np.matrix([[ui_t00.val, ui_t01.val], [ui_t10.val, ui_t11.val]])
    result_matrix = (transform_matrix * origin_matrix.transpose()).transpose()
    ax.clear()
    ax.grid()
    ax.add_patch(Polygon(origin_matrix, color='black'))
    ax.add_patch(Polygon(result_matrix, color='red', alpha=0.4))

# original controller
Button(plt.axes([0.1, 0.2, 0.8, 0.04]), "Original Position")
ax_ox = plt.axes([0.1, 0.16, 0.35, 0.02])
ui_ox = Slider(ax_ox, '', -2, 2, valinit=0)
ax_oy = plt.axes([0.55, 0.16, 0.35, 0.02])
ui_oy = Slider(ax_oy, '', -2, 2, valinit=0)

# transformation controller
Button(plt.axes([0.1, 0.1, 0.8, 0.04]), "Transformation Matrix")
ax_t00 = plt.axes([0.1, 0.05, 0.35, 0.02])
ui_t00 = Slider(ax_t00, '', -5, 5, valinit=0)
ax_t01 = plt.axes([0.55, 0.05, 0.35, 0.02])
ui_t01 = Slider(ax_t01, '', -5, 5, valinit=-2)
ax_t10 = plt.axes([0.1, 0.01, 0.35, 0.02])
ui_t10 = Slider(ax_t10, '', -5, 5, valinit=-2)
ax_t11 = plt.axes([0.55, 0.01, 0.35, 0.02])
ui_t11 = Slider(ax_t11, '', -5, 5, valinit=0)

ui_ox.on_changed(draw)
ui_oy.on_changed(draw)
ui_t00.on_changed(draw)
ui_t01.on_changed(draw)
ui_t10.on_changed(draw)
ui_t11.on_changed(draw)

draw(0)
plt.show()

  1.  http://en.wikipedia.org/wiki/Transformation_matrix 
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s