Search code examples
pythonnumpymatplotlibplotprojectile

Plotting projectile motion of 1 y-position values vs. 2 x-position values using matplotlib and numpy


Hi i'm trying to get a plot of the trajectory of a mass under projectile motion. One with a force acting on the horizontal axis and one without (basically 2 sets of x values plotted against a 1 set of y-values). Here's what i have so far.. I'm new to programming and i can't seem to figure out where this went wrong. Hope you guys can help me. Thank you!

import numpy as np
import matplotlib.pyplot as pl

def position(y0, v0, theta, g, t):
    y= y0 + v0*np.sin(theta)*t + (g*t**2)/2
    return y

def position2(x0, v0, theta, c, e, alpha, t):
    x1 = x0 + v0*(np.cos(theta))*t + c*(t*(e-1)+(2-2*e)/alpha)
    return x1

def position3(x0, v0, theta, t):
    x2 = x0 + v0*(np.cos(theta))*t
    return x2

t = np.linspace(0,10,1000)

#part1
m = 1
theta = 45
y0 = 2
x0 = 0
v0 = 3
k = 1
alpha = 0.5
g = -9.8
c = (-k/m)*(1/alpha**2)
e = -(np.e**(-alpha*t))

x1 = []
x2 = []
y = []

for a in t:
    x1_data = position2(x0, v0, theta, c, e, alpha, t)
    x1.append(x1_data)
    x2_data = position3(x0, v0, theta, t)
    x2.append(x2_data)    
    y_data =  position(y0, v0, theta, g, t)
    y.append(y_data)

print x1_data
print x2_data
print y_data

pl.title('Constant and Time-Dependent Forces')
pl.xlabel(b'x-position')
pl.ylabel(b'y-position')

x1label = 'projectile 1'
x2label = "'normal' projectile"
plot1 = pl.plot(x1_data, y, 'r')
plot2 = pl.plot(x2_data, y, 'b')

pl.legend()
pl.show()

Solution

  • I went through your code since i am new to matplotlib and wanted to play a bit with it. The only mistake i found is in the for loop where you do for a in t: but end up passing t to the functions instead of a.

    import numpy as np
    import matplotlib.pyplot as pl
    
    sin = np.sin
    cos = np.cos
    pi = np.pi
    
    
    def y_position(y0, v0, phi, g, t):
        y_t = y0 + v0 * sin(phi) * t + (g * t**2) / 2
        return y_t
    
    
    def x_position_force(x0, v0, phi, k, m, alpha, t):
        term1 = (-k / m) * (1 / alpha ** 2)
        term2 = -np.e ** (-alpha * t)
        x_t = x0 + v0 * cos(phi) * t + term1 * (t * (term2 - 1) + (2 - 2 * term2) / alpha)
        return x_t
    
    
    def x_position_no_force(x0, v0, phi, t):
        x_t = x0 + v0 * cos(phi) * t
        return x_t
    
    
    time = np.linspace(0, 10, 100)
    
    #-------------  I N P U T  -------------#
    x_init  = 0
    y_init  = 2
    v_init  = 3
    theta   = 45
    gravity = -9.8
    m = 1
    k = 1
    alpha = 0.5
    #-------------  I N P U T  -------------#
    x_with_force = []
    x_with_no_force = []
    y = []
    
    for time_i in time:
        x_with_force.append(x_position_force(x_init, v_init, theta, k, m, alpha, time_i))
        x_with_no_force.append(x_position_no_force(x_init, v_init, theta, time_i))
        y.append(y_position(y_init, v_init, theta, gravity, time_i))
    
    # print(x1_data)
    # print(x2_data)
    # print(y_data)
    
    pl.subplot(211)
    pl.title('Constant and Time-Dependent Forces')
    pl.xlabel('time')
    plot1 = pl.plot(time, x_with_force, 'r', label='x_coord_dynamicF')
    plot2 = pl.plot(time, x_with_no_force, 'g', label='x_coord_staticF')
    plot3 = pl.plot(time, y, 'b', label='y_coord')
    pl.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.)
    
    pl.subplot(212)
    pl.title('Trajectory (x,y)')
    pl.xlabel('X')
    pl.ylabel('Y')
    plot4 = pl.plot(x_with_force, y, 'r^')
    plot5 = pl.plot(x_with_no_force, y, 'b*')
    pl.show()
    

    I changed a number of things though to make the code inline with PEP8. In my opinion it is the use of bad variable names that lead you to the mistake you did. So i would recommend taking the time to type those few extra characters that ultimately help you and the people reading your code.