# Create a Program to Implement Matrices and Plotting in Python Assignment Solution.

## Instructions

Objective
Write a program to implement matrices and plotting in python language.

## Requirements and Specifications

Source Code

# Assignment 5: Matrix as a Linear Transformation ## DTSC 680: Applied Machine Learning ## Name: The purpose of this assignment is for you to gain experience working with matrices and vectors, as well as to understand the idea that a matrix can be viewed as a ___linear transformation___. This requires us to think of a matrix $\mathbf{A}$ as an object that "acts" (or "operates") on a vector $\mathbf{x}$ by multiplication to produce a new vector called $\mathbf{Ax}$. The original vector is $\mathbf{x}$, and the transformed vector is $\mathbf{Ax}$. In this assignment you will transform an ensemble of vectors using several different matrices (i.e. several different transformations) and observe the results. Before you continue, take a look at this video from 3Blue1Brown: [Linear transformations and matrices](https://youtu.be/kYB8IZa5AuE) In Assignment 4, you computed matrix-vector multiplications by hand for just a single vector - that is, you computed $\mathbf{b}$ as $\mathbf{Ax} = \mathbf{b}$ manually. For instance, you might have computed the following by hand: $$\begin{bmatrix} 4 & -3 & 1 & 3 \\ 2 & 0 & 5 & 1 \end{bmatrix} \times \left[ \begin{array}{c} 1 \\ 1 \\ 1 \\ 1 \end{array} \right] = \left[ \begin{array}{c} 5 \\ 8 \end{array} \right]$$ $$\begin{bmatrix} 4 & -3 & 1 & 3 \\ 2 & 0 & 5 & 1 \end{bmatrix} \times \left[ \begin{array}{c} 1 \\ 4 \\ -1 \\ 3 \end{array} \right] = \left[ \begin{array}{c} 0 \\ 0 \end{array} \right]$$ These equations say that multiplication by the matrix $\mathbf{A}$ transforms the vector $\left[ \begin{array}{c} 1 & 1 & 1 & 1 \end{array} \right]^T$ into $\left[ \begin{array}{c} 5 & 8 \end{array} \right]^T$ and transforms the vector $\left[ \begin{array}{c} 1 & 4 & -1 & 3 \end{array} \right]^T$ into $\left[ \begin{array}{c} 0 & 0 \end{array} \right]^T$. (Note: The superscript T denotes the transpose, which essentially means "the rows become columns, and the columns become rows".) Suppose that we wanted to perform this transformation not for just one vector (i.e. one single data point), but for many vectors (i.e. many data points) at the same time. We could accomplish this by thinking of our vector now as a matrix of vectors, and we will apply the linear transformation to each of these vectors in the matrix. (So, now we will be performing matrix multiplication.) For example, to apply the linear transformation to the above two vectors at the same time, we would write: $$\begin{bmatrix} 4 & -3 & 1 & 3 \\ 2 & 0 & 5 & 1 \end{bmatrix} \times \left[ \begin{array}{c} 1 & 1\\ 1 & 4 \\ 1 & -1 \\ 1 & 3 \end{array} \right] = \left[ \begin{array}{c} 5 & 0 \\ 8 & 0 \end{array} \right]$$ So, what will we be doing in this assignment? You will plot a simple dataset of points, where each point can be thought of as an individual vector in 2D Cartesian space. You will then perform several different geometric linear transformations in real 2D space on this data (i.e. "do some matrix multiplication with a supplied matrix"). You will then plot the original data and the transformed data, and observe the transformation. At the end, you will be asked to correctly label each of the different linear transformation matrices with its name based on the transformation results. The data you will read in has the typical format for 2D spatial data (typicaly for our class, that is) - there are three columns for the x, y, and z coordinates. For example, the data you import will have the following form (Atually, this is not true! Your data will be in 2 dimensions, but I will show you 3 here.): $$\begin{bmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ x_3 & y_3 & z_3 \\ \vdots & \vdots & \vdots \\ x_n & y_n & z_n \end{bmatrix}$$ We can view each data point as a vector. So, the first vector would be $$\mathbf{v} = \left[ \begin{array}{c} x_1 \\ y_1 \\ z_1 \end{array} \right]$$ Do you see how we need a column vector for the matrix multiplication to work properly, but each vector appears as a row vector in the matrix? Well, in order for the matrix multiplcation to work properly, the dimensions of our matrices must agree. Accordingly, we must employ the [transpose](https://www.youtube.com/watch?v=TZrKrNVhbjI) when multiplying our matrix of vectors by our transformation matrix. What I am referring to is that, for matrix multiplication to work, the number of columns in the first matrix must be equal to the number of rows in the second matrix - this is spelled out in one of the lecture videos you watched for Assignment 4. A couple last notes: Use NumPy arrays to represent your matrices, so that matrix multiplication can be performed using the [dot()](https://numpy.org/doc/stable/reference/generated/numpy.dot.html) method. Also, you can get the transpose of a Numpy array by using its [T](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.T.html) attribute. # Preliminaries Let's import some common packages: import matplotlib.pyplot as plt import matplotlib as mpl from matplotlib import cm import numpy as np import pandas as pd %matplotlib inline mpl.rc('axes', labelsize=14) mpl.rc('xtick', labelsize=12) mpl.rc('ytick', labelsize=12) import os # Where to save the figures PROJECT_ROOT_DIR = "." FOLDER = "figures" IMAGES_PATH = os.path.join(PROJECT_ROOT_DIR, FOLDER) os.makedirs(IMAGES_PATH, exist_ok=True) def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300): path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension) print("Saving figure", fig_id) if tight_layout: plt.tight_layout() plt.savefig(path, format=fig_extension, dpi=resolution) # Write Plotting Function You must define a function called plotTransformedData(original_df, trans_df, colors, size, limits) that accepts two Pandas DataFrames (composed of 2 spatial coordinates each) called original_df and trans_df. The former is the original data that you will read in, and the latter is that data after you applied a linear transformation to it. You will plot both, side-by-side, to compare the before and after effects of the transformation. The function must use [scatter()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html) to plot the data. Additionally, the plotTransformedData function accepts three other parameters: colors, size, and limits. The colors parameter is passed to the scatter function through its c parameter. The colors parameter must be a $(n,3)$ NumPy array, where $n$ is the number of data points and each of the three columns corresponds to an RGB value in the range [0,1]. The size parameter is passed to the scatter function through its s parameter. The size parameter controls the size of the marker used to represent the data point, and must be a Numpy array of size $(n,)$. (This is not a mistake: the size should really be $(n,)$. You can use np.linspace() to create the array). Lastly, the limits parameter is a list that looks like this: limits = [xmin, xmax, ymin, ymax], where the values are the limits for the x and y axes. You must specify these limits values so that they are equal to mine (I used -2.25 and +2.25 for both x and y as my limits, do not hard-code these values in the function definition though!). You must place the definition of the plotTransformedData(original_df, trans_df, colors, size, limits) function in the following cell. Be sure to include titles for each of the subplots (i.e. "Original Data" and "Transformed Data"). Note: An example figure is shown below for the Identity Matrix transformation, and you should emulate this figure as closely as possible when creating your function. def plotTransformedData(original_df, trans_df, colors, size, limits): # Create figure fig, axes = plt.subplots(nrows = 1, ncols = 2) # Plot first dataset original_df.plot.scatter(x = original_df.columns[0], y = original_df.columns[1], c = colors, s = size, ax = axes[0]) trans_df.plot.scatter(x = original_df.columns[0], y = original_df.columns[1], c = colors, s = size, ax = axes[1]) # Set figure size axes[0].set_xlim(limits[:2]) axes[0].set_ylim(limits[2:]) axes[0].set_title('Original') axes[1].set_xlim(limits[:2]) axes[1].set_ylim(limits[2:]) axes[1].set_title('Transformed') plt.show() # Import Data Import data from the file called 2D_data.csv. Name the returned DataFrame data. data = pd.read_csv('2D_data.csv') data.head() # Plot Initial Data Begin by specifying the colors, sizes, and limits parameters for the plotTransformedData function. You will not call the plotTransformedData(original_df, trans_df, colors, size, limits) function in this section, but rather you'll invoke it below in the section called _Perform Linear Transformations and Plot Results_. However, you will plot the data DataFrame here, merely to inspect it, using the marker colors, marker sizes, and axis limits specified by the colors, sizes, and limits parameters. So, plot data here. You should emulate the marker colors and sizes shown below as best as you can. The marker sizes range from small to large, and the marker colors vary from black to red. # size of data n = len(data) # define colors colors = np.zeros((n,3)) colors[:,0] = np.linspace(0, 1, n) limits = [-2.25, 2.25, -2.25, 2.25] sizes = np.linspace(10, 50, n) plt.figure(figsize=(10,10)) data.plot.scatter(x='x', y='y', c =colors, s = sizes) plt.xlim(limits[:2]) plt.ylim(limits[2:]) plt.title('2D Data') # Define Data Matrix and Transformation Matrices Create a NumPy array called X from the data DataFrame above. Further, you must define the following transformation matrices. You must declare these matrices to be NumPy arrays, and name them A1, A2, ..., AN, as shown. # -------------------- Define X NumpPy Array -------------------- # # Data Matrix X = data.values n = len(X) colors = np.zeros((n,3)) colors[:,0] = np.linspace(0, 1, n) limits = [-2.25, 2.25, -2.25, 2.25] sizes = np.linspace(10, 50, n) # -------------------- Define 13 NumPy Arrays -------------------- # k = 0.5 m = 0.5 r = 0.5 c = 2.0 phi = np.pi/4 A1 = np.array([[-1, 0], [0, -1]]) A2 = np.array([[k, 0], [0, 1]]) A3 = np.array([[np.cos(phi), -np.sin(phi)], [np.sin(phi), np.cos(phi)]]) A4 = np.array([[-1, 0], [0, 1]]) A5 = np.array([[1, 0], [0, c]]) A6 = np.array([[1, 0], [r, 1]]) A7 = np.array([[1, m], [0, 1]]) A8 = np.array([[0, -1], [-1, 0]]) A9 = np.array([[1, 0], [0, 0]]) A10 = np.array([[0, 0], [0, 1]]) A11 = np.array([[1, 0], [0, -1]]) A12 = np.array([[0, 1], [1, 0]]) A13 = np.array([[1, 0], [0, 1]]) # Perform Linear Transformations and Plot Results In this section, you will perform the following: $$\mathbf{X}_{trans} = \mathbf{A} \mathbf{X}^T$$ where $\mathbf{X}$ is the data you read in from the file, $\mathbf{A}$ is any one of the thirteen transformation matrices, and $\mathbf{X}_{trans}$ is the transformed data. You should express the matrix multiplication in one line of code! ### Identity Matrix Any matrix $\mathbf{A}$ multiplied by the ___Identity Matrix___ $\mathbf{I}$ is equal to itself! That is, $\mathbf{AI} = \mathbf{A}$. The 2D identity matrix is given below. # Perform Matrix Multiplication Xtrans = np.dot(A13, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) For the rest of the following linear transformations, you can Google the definitions to learn more. ### Rotation Matrix # Perform Matrix Multiplication Xtrans = np.matmul(A3, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) ### Reflection Matrices # Perform Matrix Multiplication Xtrans = np.matmul(A1, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A4, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A8, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A11, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A12, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) ### Contraction and Expansion Matrices # Perform Matrix Multiplication Xtrans = np.matmul(A2, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A5, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) ### Shearing Matrices # Perform Matrix Multiplication Xtrans = np.matmul(A6, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A7, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) ### Projection Matrices # Perform Matrix Multiplication Xtrans = np.matmul(A9, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Perform Matrix Multiplication Xtrans = np.matmul(A10, X.T).T # Plot Transformation # Construct DataFrames again Xdf = pd.DataFrame(data = X, columns = ['x', 'y']) Xtransdf = pd.DataFrame(data = Xtrans, columns = ['x', 'y']) plotTransformedData(Xdf, Xtransdf, colors, sizes, limits) # Connect the Dots In this section, you must correctly label linear transformations their names. The pool of transformations is given below: - Identity Matrix - Rotation Matrix - Reflection through the x Axis Matrix - Reflection through the y Axis Matrix - Reflection through the Line y = x Matrix - Reflection through the Line y = -x Matrix - Reflection through the Origin Matrix - Horizontal Contraction/Expansion Matrix - Vertical Contraction/Expansion Matrix - Hortizontal Shear Matrix - Vertical Shear Matrix - Projection onto x Axis Matrix - Projection onto y Axis Matrix You must correctly label the following linear transformations with the above names. 1. A1: Reflection through the Origin Matrix 2. A2: Horizontal Contraction/Expansion Matrix 3. A3: Rotation Matrix 4. A4: Reflection through the y Axis Matrix 5. A5: Vertical Contraction/Expansion Matrix 6. A6: Vertical Shear Matrix 7. A7: Hortizontal Shear Matrix 8. A8: Reflection through the Line y = -x Matrix 9. A9: Projection onto x Axis Matrix 10. A10: Projection onto y Axis Matrix 11. A11: Reflection through the x Axis Matrix 12. A12: Reflection through the Line y = x Matrix 13. A13: Identity Matrix