# # Copyright (c) 2018 James Hume (www.jeh-tech.com). All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by James Hume (www.jeh-tech.com) # 4. Neither the name "James Hume" or website "www.jeh-tech.com" # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # import matplotlib.pyplot as pl import numpy as np import matplotlib.animation as animation import math import sys fig, ax = pl.subplots() ns_quiv = None psol_quiv = None ns_txt = None psol_txt = None ns_vec_scalar = 0 state = "up" def draw_quiv(o, v, c, z): return ax.plot([o[0], o[0] + v[0]], [o[1], o[1] + v[1]], color=c, zorder=z, lw=3)[0] #return ax.quiver(o[0], o[1], v[0], v[1], color=c, angles='xy', scale_units='xy', scale=1, zorder=z) def init(): global ns_quiv global ns_vec global psol_quiv global psol_vec global ns_txt global psol_txt global ns_vec_scalar z_vec = np.array([0., 0.]) ns_vec = np.array([2./3., 1.]) psol_vec = np.array([3., 0.]) # Quivers to draw the null space vector and the particular solution that we will # animate. ns_quiv = draw_quiv(z_vec, ns_vec, 'r', 2) psol_quiv = draw_quiv(ns_vec, psol_vec, 'cyan', 2) # Plot lines representing the null space, row space and solution set. # They go "off" the x/y axis limits to make them look infinite. ax.plot([-10, 10], [-15, 15], color='r', zorder=0, alpha=0.5) ax.plot([-10, 10], [20.0/3.0, -20.0/3.0], color='b', zorder=0, alpha=0.5) ax.plot([-7, 13], [-15, 15], color='g', zorder=0, alpha=0.5) # Draw grid and set limits so that the space lines look infinite ax.grid(); ax.set_xlim(-5, 5) ax.set_ylim(-5, 5) ns_txt = ax.text((ns_vec / 2.)[0], (ns_vec / 2.)[1], r'$\alpha \vec{n_o}\in \mathrm{N}(A)$') psol_txt = ax.text((psol_vec / 2 + ns_vec)[0], (psol_vec / 2 + ns_vec)[1], r'$[3, 0]$') ax.annotate( r'Solution set' , xy=(.75, -3.4) , xytext=(10, -40) , textcoords='offset points' , fontsize='medium' , arrowprops=dict(facecolor='green', shrink=0.05, connectionstyle="arc3,rad=0.1", fc="g", alpha=0.5) ) ax.annotate( r'$\mathrm{N}(A)$' , xy=(-2, -3) , xytext=(-10, 35) , textcoords='offset points' , fontsize='medium' , arrowprops=dict(facecolor='red', shrink=0.05, connectionstyle="arc3,rad=0.1", fc="r", alpha=0.5) ) ax.annotate( r'$\mathrm{C}(A^T)$' , xy=(-3, 2) , xytext=(-30, -40) , textcoords='offset points' , fontsize='medium' , arrowprops=dict(facecolor='blue', shrink=0.05, connectionstyle="arc3,rad=-0.1", fc="b", alpha=0.5) ) def animate(i): global ns_quiv global ns_vec global psol_quiv global psol_vec global ns_txt global psol_txt global ns_vec_scalar global state if state == "up": ns_vec_scalar += .1 if ns_vec_scalar > 3.: state = "down" else: ns_vec_scalar -= .1 if ns_vec_scalar < -4.9: state = "up" ns_scaled_vec = ns_vec * ns_vec_scalar ns_quiv.set_xdata([0, ns_scaled_vec[0]]) ns_quiv.set_ydata([0, ns_scaled_vec[1]]) psol_quiv.set_xdata([ns_scaled_vec[0], ns_scaled_vec[0] + psol_vec[0]]) psol_quiv.set_ydata([ns_scaled_vec[1], ns_scaled_vec[1] + psol_vec[1]]) ns_txt.set_x((ns_scaled_vec / 2.)[0]) ns_txt.set_y((ns_scaled_vec / 2.)[1]) psol_txt.set_x((psol_vec / 2 + ns_scaled_vec)[0]) psol_txt.set_y((psol_vec / 2 + ns_scaled_vec)[1]) return psol_quiv # init() # pl.show() Writer = animation.writers['ffmpeg'] writer = Writer(fps=15, metadata=dict(artist='James Hume @ www.jeh-tech.com'), bitrate=1800) ani = animation.FuncAnimation(fig, animate, frames= 30*2 + 49*2+2, init_func=init, interval=100, blit=False) ani.save('animation.mp4', writer=writer)