Monday, October 19th, 2026¶
Last week, we discussed visualizing $2$D-arrays and $3$D-arrays where the third dimension stores RGB(A) values.
Let's get started working with tartans by generating vertical and horizontal stripes for the following pattern (see project page for details):
Pattern :
B14 K6 B6 K6 B6 K32 OG32
where the colors B, K, and OG are given by the RGB triples:
B : [52, 80, 100]
K : [16, 16, 16]
OG : [92, 100, 40]
To get started, we'll need to initialize an array with the correct shape. What is the total width of this pattern?
import numpy as np
import matplotlib.pyplot as plt
14 + 6 + 6 + 6 + 6 + 32 + 32
102
vertical_stripes = np.zeros((102, 102, 3)) # 3D array with the third dimension storing RGB values
vertical_stripes
array([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
...,
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
...,
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]])
plt.imshow(vertical_stripes)
<matplotlib.image.AxesImage at 0x20148cb8e10>
Right now, our array is a pure black picture. Let's add the first vertical stripe, which has color B = [52, 80, 100] and has width 14.
vertical_stripes[:, 0:14] = [50/255, 80/255, 100/255]
plt.imshow(vertical_stripes)
<matplotlib.image.AxesImage at 0x20149506c10>
Exercise: Add the remaining stripes from the sample pattern to the vertical_stripes array.
Pattern :
B14 K6 B6 K6 B6 K32 OG32
where the colors B, K, and OG are given by the RGB triples:
B : [52, 80, 100]
K : [16, 16, 16]
OG : [92, 100, 40]
vertical_stripes[:, 0:14] = [52/255, 80/255, 100/255]
vertical_stripes[:,14:20] = [16/255, 16/255, 16/255]
vertical_stripes[:,20:26] = [52/255, 80/255, 100/255]
vertical_stripes[:,26:32] = [16/255, 16/255, 16/255]
vertical_stripes[:,32:38] = [52/255, 80/255, 100/255]
vertical_stripes[:,38:70] = [16/255, 16/255, 16/255]
vertical_stripes[:,70:102] = [92/255, 100/255, 40/255]
plt.imshow(vertical_stripes)
<matplotlib.image.AxesImage at 0x201497c0690>
Some thoughts:
- We need a better way to generate this vertical stripes array. There was far too much manual typing/calculation to add each stripe. We'll come back and address this shortly.
- Now that we have an array of vertical stripes, we can easily generate an array of horizontal stripes. This can be done transposing our array (see below).
- Once we have vertical and horizontal stripes, we need to super-impose them somehow to generate the tartan pattern.
Array transposes¶
For a 2-dimensional matrix, the transpose flips rows and columns. That is, the first row becomes the first column, the second row becomes the second column, etc. In Python, we can use the .T method on a 2D array to get its transpose.
A = np.arange(50).reshape(5,10)
print(A)
[[ 0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32 33 34 35 36 37 38 39] [40 41 42 43 44 45 46 47 48 49]]
print(A.T)
[[ 0 10 20 30 40] [ 1 11 21 31 41] [ 2 12 22 32 42] [ 3 13 23 33 43] [ 4 14 24 34 44] [ 5 15 25 35 45] [ 6 16 26 36 46] [ 7 17 27 37 47] [ 8 18 28 38 48] [ 9 19 29 39 49]]
print(A.shape)
print(A.T.shape)
(5, 10) (10, 5)
We would like to take the transpose of our vertical_stripes array so that the columns of vertical_stripes become the rows of horizontal_stripes. In other words, the vertical stripes will become horizontal stripes.
Problem: The vertical_stripes array is a 3-dimensional array (rows, columns, color channels). What does vertical_stripes.T give us in this case?
vertical_stripes.shape
(102, 102, 3)
vertical_stripes.T.shape
(3, 102, 102)
#plt.imshow(vertical_stripes.T)
It turns out that the .T attribute reverses the order of the axes. That is, the first axis (rows) becomes the last axis, the second axis (columns) becomes the second-last axis, etc. In the case of the vertical_stripes array, the color channel axis became the row axis, the column axis remained as the column axis, and the row axis became the color channel axis. For our needs, this is not useful. Instead, we just want to swap the row and column axes.
We can use the np.transpose function to do more targeted transposing.
#help(np.transpose)
When calling np.transpose, we can optionally supply a keyword argument axes which gives a permutation of the axes of the array. In particular, using axes = [1, 0, 2] will give a transposed matrix where:
- the old axis
1(i.e. the columns) becomes the new axis0(i.e. the rows), - the old axis
0becomes the new axis1, and - the old axis
2(i.e. the color channel) remains as axis2.
Let's use this to define the horizontal_stripes array.
horizontal_stripes = np.transpose(vertical_stripes, axes=[1, 0, 2])
print(horizontal_stripes.shape)
(102, 102, 3)
plt.imshow(horizontal_stripes)
<matplotlib.image.AxesImage at 0x2014dc10050>
Creating a tartan from vertical and horizontal arrays¶
We now have vertical and horizontal stripes. How can we combine them to get a tartan pattern?
One simple idea is to take the average of the horizontal and vertical stripe arrays.
avg_tartan = (vertical_stripes + horizontal_stripes) / 2
plt.imshow(avg_tartan)
<matplotlib.image.AxesImage at 0x2014dda1e50>
This gives flat colors rather than an interleaved combination. Can we instead generate a checkerboard pattern to interleave these stripes? To do so, we want to go row by row, column by column, and alternatingly select a color from the vertical_stripes and horizontal_stripes arrays.
Exercise: Create a checkerboard_tartan array that combines the vertical_stripes and horizontal_stripes arrays in checkerboard pattern.
In-class exercise¶
checkerboard_tartan = np.zeros((102, 102, 3))
for row in range(102): # Iterate row by row
for col in range(102): # Iterate column by column
if ...:
if ...:
checkerboard_tartan[row,col] = vertical_stripes[row, col]
else:
checkerboard_tartan[row,col] = horizontal_stripes[row, col]
else:
if ...:
checkerboard_tartan[row,col] = vertical_stripes[row, col]
else:
checkerboard_tartan[row,col] = horizontal_stripes[row, col]
fig = plt.figure(figsize=(10,10), dpi=200)
<Figure size 2000x2000 with 0 Axes>
Where to go from here:
- We need a better way of generating the
vertical_stripesarray. - We need to generate the more authentic tartan pattern described in the project page.
- We need to pad our tartan pattern to be
500by500rows/columns.