In [1]:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

from matplotlib.patches import Arc
from IPython.display import HTML

%matplotlib inline
In [2]:
# Visualize cosine similarity from 0 to 359

def compute_cosine_similarity(x: np.ndarray, y: np.ndarray) -> float:
    # Adjacency / Hypotenuse
    return np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))

x = np.array([1, 0])

theta_list = []
cosine_similarity_list = []
y_list = []

for degree in range(0, 360):
    
    theta = np.radians(degree)
    y = np.array([np.cos(theta), np.sin(theta)])
    cosine_similarity = compute_cosine_similarity(x, y)
    
    theta_list.append(degree)
    cosine_similarity_list.append(cosine_similarity)
    y_list.append(y)
    
fig, ax = plt.subplots()

def animate(frame):
    
    y = y_list[frame]
    
    ax.clear()
    ax.set_xlim(-2, 2)
    ax.set_ylim(-2, 2)
    ax.set_xticks([-2, -1, 0, 1, 2])
    ax.set_yticks([-2, -1, 0, 1, 2])
    ax.set_aspect("equal")
    ax.grid(True, alpha=0.3)
    ax.arrow(0, 0, x[0], x[1], head_width=0.05, color="blue")
    ax.arrow(0, 0, y[0], y[1], head_width=0.05, color="green")
    ax.add_patch(Arc((0, 0), 2.0, 2.0, angle=0, theta1=0, theta2=360, color="gray", linestyle="--", linewidth=0.3))
    ax.add_patch(Arc((0, 0), 0.4, 0.4, angle=0, theta1=0, theta2=frame, color="red", linestyle="dotted"))
    
    ax.text(
        x[0] + 0.1, 
        x[1] + 0.1, 
        s=f"({x[0]:.2f}, {x[1]:.2f})", 
        horizontalalignment="left", 
        verticalalignment="top", 
        color="blue"
    )
    
    ax.text(
        y[0] + 0.1, 
        y[1] + 0.1, 
        s=f"({y[0]:.2f}, {y[1]:.2f})", 
        horizontalalignment="left", 
        verticalalignment="top", 
        color="green"
    )
    
    ax.text(0, -1.3, s=r"$\theta$" + f"={frame}°", fontsize=10, horizontalalignment="center", color="red")
    ax.text(0, -1.5, s=f"similarity={cosine_similarity_list[frame]:.5f}", fontsize=10, horizontalalignment="center")
    
    return ()

anim = animation.FuncAnimation(fig, animate, frames=len(y_list), interval=50, blit=True, repeat=False)
plt.close(fig)
HTML(anim.to_jshtml())
Out[2]: