fig = plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
levels = np.linspace(np.min(Z), np.max(Z), 50)
plt.contour(X,Y,Z, levels);
plt.plot([0,0], [-3,3],':', color='gray')
plt.plot([-3,3],[0,0], ':', color='gray')
plt.plot(xs[0], xs[1], 'o', color='black')
plt.xlabel(r'$x_0$')
plt.ylabel(r'$x_1$')
plt.arrow(xs[0], xs[1], Q[0,0]/Λ[0,0]**0.5, Q[0,1]/Λ[0,0]**0.5, head_width=0.1, length_includes_head=True, color='blue')
plt.arrow(xs[0], xs[1], Q[1,0]/Λ[1,1]**0.5, Q[1,1]/Λ[1,1]**0.5, head_width=0.1, length_includes_head=True, color='orange');
plt.gca().set_aspect('equal', adjustable='box')
plt.subplot(1,2,2)
plt.contour(CX,CY,Z, levels);
plt.plot([0,0],[np.min(CX),np.max(CX)], color='gray', linestyle=':')
plt.plot([np.min(CX),np.max(CX)],[0,0], color='gray', linestyle=':')
cs = np.dot(np.dot(np.sqrt(Λ),np.transpose(Q)), xs)
plt.plot(cs[0], cs[1], 'o', color='black');
plt.xlim([np.min(CX), np.max(CX)])
plt.ylim([np.min(CY), np.max(CY)])
plt.xlabel(r'$\hat{v}_0=(\Lambda^{1/2}Q^Tx)_0$')
plt.ylabel(r'$\hat{v}_1=(\Lambda^{1/2}Q^Tx)_1$');
plt.gca().set_aspect('equal', adjustable='box')
v = np.dot(np.dot(np.sqrt(Λ),np.transpose(Q)), xs)
w = np.dot(np.dot(np.sqrt(Λ),np.transpose(Q)), Q[:,0]/Λ[0,0]**0.5)
plt.arrow(v[0], v[1], w[0], w[1], head_width=0.1, length_includes_head=True, color='blue')
v = np.dot(np.dot(np.sqrt(Λ),np.transpose(Q)), xs)
w = np.dot(np.dot(np.sqrt(Λ),np.transpose(Q)), Q[:,1]/Λ[1,1]**0.5)
plt.arrow(v[0], v[1], w[0], w[1], head_width=0.1, length_includes_head=True, color='orange');
plt.tight_layout()