trying to plot position vector within loop

139 Views Asked by At

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")
2

There are 2 best solutions below

0
Federico Pellegatta On

I found two issues in your code:

  1. the plt import is not correct. Instead use from matplotlib import pyplot as plt
  2. 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")
    
    enter image description here

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.

0
gboffi On

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