from __future__ import division from matplotlib import patches fig, ax = subplots() fig.set_figheight(5) x = arange(6) y= matrix([[2], [3]]) ax.plot(x,x) ax.plot(*y,marker='s',color='r') ax.add_patch(patches.Circle(y,radius=.5,alpha=0.75,color='pink')) ax.annotate('Find point along\n line closest\n to red square', fontsize=12,xy=(2.5,2.5), xytext=(3,1.5), arrowprops={'facecolor':'blue'}) ax.axis(xmax=5,ymax=5) ax.set_aspect(1) ax.grid() fig, ax = subplots() fig.set_figheight(5) x = arange(6) y= matrix([[2], [3]]) ax.plot(x,x) ax.plot(*y,marker='o',color='r') ax.add_patch(patches.Circle(y,radius=1/sqrt(2.),alpha=0.75,color='pink')) v = matrix([[1],[1]]) Pv = v*v.T/ (v.T*v) # projection operator ax.plot(*(Pv*y),marker='s',color='g') ax.add_line( Line2D( (y[0,0], 2.5), (y[1,0],2.5) ,color='g',linestyle='--')) ax.add_line( Line2D( (y[0,0], 0), (y[1,0],0) ,color='r',linestyle='--')) ax.annotate( 'Closest point is\nperpedicular\nto line and tangent\nto circle', fontsize=12,xy=(2.6,2.5), xytext=(3,1.5), arrowprops={'facecolor':'blue'}) ax.text(.7,1.5,r'$\mathbf{y}$',fontsize=24,color='r') ax.set_aspect(1) ax.grid() theta = 120/180.*pi # rotation angle for ellipse v = matrix([[1],[1]]) # rotation matrix U = matrix([[ cos(theta), sin(theta)], [-sin(theta), cos(theta)]]) # diagonal weight matrix S = matrix([[5,0], # change diagonals to define axes of ellipse [0,1]]) Q = U.T*S*U Pv = (v)*v.T*(Q)/(v.T*(Q)*v) # projection operator err = sqrt((y-Pv*y).T*Q*(y-Pv*y)) # error length xhat = Pv*y # closest point on line fig, ax = subplots() fig.set_figheight(5) ax.plot(*y,marker='o',color='r') ax.plot(x,x) ax.plot(*(xhat),marker='s',color='r') ax.add_patch( patches.Ellipse(y,err*2/sqrt(S[0,0]),err*2/sqrt(S[1,1]), angle=theta/pi*180,color='pink', alpha=0.5)) ax.add_line( Line2D( (y[0,0], 0), (y[1,0],0) ,color='r',linestyle='--')) ax.add_line( Line2D( (y[0,0],xhat[0,0]), (y[1,0],xhat[1,0]) , color='g',linestyle='--')) ax.annotate( '''Closest point is tangent to the ellipse and "perpendicular" to the line in the sense of the weighted/rotated distance ''', fontsize=12,xy=(xhat[0,0],xhat[1,0]), xytext=(3.5,1.5), arrowprops={'facecolor':'blue'}) ax.axis(xmax=6,ymax=6) ax.set_aspect(1) ax.grid()