I've been trying to code projectile motion and everything has been working so far except the graphing portion, which i'm trying to iterate within the loop. I want to graph the x and y coordinate of the position vector, but i keep getting the error "module not callable"
import numpy as np
import math as m
import matplotlib as plt
g = np.array([0,-9.8,0])
r = np.array([0,1.2,0])
theta = 35 * m.pi / 180
v1 = 3.3
v = v1 * np.array([np.cos(theta),np.sin(theta),0])
a = g
t = 0
dt = .01
while r[1] > 0:
v = v a * dt
r = r v * dt
t = t dt
plt.plot(r)
print("r = ",r , "m")
print("t = ",t, "s")
print("v = ",v, "m/s")
CodePudding user response:
I found two issues in your code:
- the
plt
import is not correct. Instead usefrom matplotlib import pyplot as plt
plt.plot(r)
works but nothing is shown since you are trying to draw a single point of infinitesimal size for each canvas. Since is a scatterplot, you should assign a dimension to each point, e.g.plt.plot(r[0], r[1], marker="o", markersize=5, markeredgecolor="blue", markerfacecolor="blue")
If your goal is to generate an animation (as suggested by @3dSpatialUser), you need multiple pictures. Thus add plt.show()
(or plt.savefig()
) in the while loop.
CodePudding user response:
Here it is a bit of code, that corrects your mistakes and uses ① a little different looping scheme, that I find more flexible, ② a simple animation trick, as suggested in other answers and comments, and ③ an alternative algorithm that gives very similar results when you use a small time step, but is more accurate if you use a longer time step.
I include no graphic output because it's an animation, test it yourself, please.
import numpy as np
import matplotlib.pyplot as plt
# CONSTANTS
a = np.array([0.0, -9.8, 0.0])
theta = np.radians(35.0)
v1 = 3.3
# Initial conditions
t, dt = 0.0, 0.01
r = np.array([0.0, 1.2, 0.0])
v = v1 * np.array([np.cos(theta),np.sin(theta),0])
# set the limits of the plots, to avoid annoying resizing, and grid
plt.axis((-0.05, 2.05, -0.05, 1.45))
plt.grid()
# imo, it's better a never ending loop with a break condition
# placed where it is needed - also, it's better to plot
# also the first and the last points
while 1:
plt.scatter(r[0], r[1], color='red', s=3)
plt.pause(.00001)
if r[1] < 0: break
v = v a * dt
r = r v * dt
t = t dt
# reset the initial conditions
t, dt = 0.0, 0.01
r = np.array([0.0, 1.2, 0.0])
v = v1 * np.array([np.cos(theta),np.sin(theta),0])
# here a little improvement, instead of using the FINAL value
# of the velocity to compute the final displacement, let's
# use the MEAN value of the velocity during the time step
while 1:
plt.scatter(r[0], r[1], color='blue', s=3)
plt.pause(.00001)
if r[1] < 0: break
v0 = v
v = v a * dt
r = r (v0 v)/2 * dt
t = t dt