Ploting a point for each step i - python

I'm doing a free fall caluculations (really simple) and would like to plot each instance of height of the objects - that is the height of the object to be displayed as it 'falls' down. I tried running it throught a for loop, but i just get the end result plotted. What would i need to do to dislplay the object as it falls, for each individual - not just the end result.
Here is my code:
#Input parameters
y1 = 490 #starting position
y2 = 0 #ground
g = -9.81 #gravity
VY = 0 #starting speed
import math
import numpy as np
import matplotlib.pyplot as plt
sqrt_part = math.sqrt(VY**2-2*g*(y1-y2))
t1 = - VY - sqrt_part/g
t2 = - VY + sqrt_part/g
if t1 > 0:
t = t1
else:
t = t2
print('t = ' + str(t) + ' ' + 's')
t_space = np.linspace(0,t,50)
y_t = y1 + VY * t_space + 0.5 * g * t_space**2
v_t = abs(y_t[1:] - y_t[0:-1])/abs(t_space[0:-1] - t_space[1:])
plt.plot(t_space, y_t, 'go')
plt.plot(t_space[1:], v_t, 'r--')
for i in range(np.size(t_space)):
plt.plot(t_space[i], y_t[i], 'go')
The for loop displays the same as the plot above it, but i would like it to update and show the 'ro' as it moves thorught time. How would i do that?
On the left is what i get, on the right is what i want
enter image description here

Please, take a look at matplotlib animation api.
#Input parameters
y1 = 490 #starting position
y2 = 0 #ground
g = -9.81 #gravity
VY = 0 #starting speed
import math
import numpy as np
import matplotlib.pyplot as plt
sqrt_part = math.sqrt(VY**2-2*g*(y1-y2))
t1 = - VY - sqrt_part/g
t2 = - VY + sqrt_part/g
if t1 > 0:
t = t1
else:
t = t2
print('t = ' + str(t) + ' ' + 's')
t_space = np.linspace(0,t,50)
y_t = y1 + VY * t_space + 0.5 * g * t_space**2
v_t = np.abs((np.roll(y_t, -1) - y_t) / (np.roll(t_space, -1) - t_space))
v_t = np.roll(v_t, 1)
v_t[0] = 0
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
# create two empty lines
ln_y, = plt.plot([], [], 'go', label="y")
ln_v, = plt.plot([], [], 'r--', label="v")
def init():
ax.set_xlim(0, max(t_space))
ax.set_ylim(0, max(y_t))
ax.set_xlabel("t")
ax.legend()
return ln_y, ln_v
def update(i):
# i represents the index of the slice to use at the current frame
ln_y.set_data(t_space[:i], y_t[:i])
ln_v.set_data(t_space[:i], v_t[:i])
return ln_y, ln_v,
ani = FuncAnimation(fig, update, frames=range(len(v_t)),
init_func=init, blit=False, repeat=False)
plt.show()

Related

ValueError: setting an array element with a sequence rectifying error

def nonuniform_poly_interpolation(a,b,p,n,x,f,produce_fig):
xhat = np.zeros(p+1)
for j in range(p+1):
xhat[j] = b - a + a * np.cos(np.pi * (((2*j)+1)/(2*(p+1))))
lagrange_matrix = lagrange_poly(p,xhat,n,x,1e-10)
nu_interpolant = np.empty(n)
for i in range(p+1):
nu_interpolant[i] = nu_interpolant[i] + (f(xhat[i]) * lagrange_matrix[i]);
fig = plt.figure()
plt.plot(x,f(x), label = "f(x)")
plt.plot(x,nu_interpolant, label = "Pp(x)")
plt.legend(loc = "upper left")
plt.xlabel("x")
plt.ylabel("Pp(x)")
plt.title("Nonuniform Polynomial Interpolation")
plt.show()
if produce_fig == True:
fig = fig
else:
fig = None
return nu_interpolant, fig
Not sure what "ValueError: setting an array element with a sequence" means and how I could fix this code? It is sensing an error on line 127 (for i in range(p+1):
nu_interpolant[i] = nu_interpolant[i] + (f(xhat[i]) * lagrange_matrix[i]);

offset a parallel line to a given line python

I want to draw parallel line to given X,Y coordinate below code helps to draw ,
import numpy as np
import matplotlib.pyplot as plt
x = [187, 879, 722, 322]
y = [341, 344, 112, 112]
newX = []
newY = []
def findIntesection(p1x, p1y, p2x, p2y, p3x,p3y, p4x, p4y):
dx12 = p2x - p1x
dy12 = p2y - p1y
dx34 = p4x - p3x
dy34 = p4y - p3y
denominator = (dy12*dx34-dx12*dy34)
t1 = ((p1x - p3x) * dy34 + (p3y - p1y) * dx34)/ denominator
t2 = ((p3x - p1x) * dy12 + (p1y - p3y) * dx12)/ -denominator;
intersectX = p1x + dx12 * t1
intersectY = p1y + dy12 * t1
if (t1 < 0): t1 = 0
elif (t1 > 1): t1 = 1
if (t2 < 0): t2 = 0
elif (t2 > 1): t2 = 1
return intersectX,intersectY
def normalizeVec(x,y):
distance = np.sqrt(x*x+y*y)
return x/distance, y/distance
def getEnlarged(oldX, oldY, offset):
num_points = len(oldX)
for j in range(num_points):
i = j - 1
if i < 0:
i += num_points
k = (j + 1) % num_points
vec1X = oldX[j] - oldX[i]
vec1Y = oldY[j] - oldY[i]
v1normX, v1normY = normalizeVec(vec1X,vec1Y)
v1normX *= offset
v1normY *= offset
n1X = -v1normY
n1Y = v1normX
pij1X = oldX[i] + n1X
pij1Y = oldY[i] + n1Y
pij2X = oldX[j] + n1X
pij2Y = oldY[j] + n1Y
vec2X = oldX[k] - oldX[j]
vec2Y = oldY[k] - oldY[j]
v2normX, v2normY = normalizeVec(vec2X,vec2Y)
v2normX *= offset
v2normY *= offset
n2X = -v2normY
n2Y = v2normX
pjk1X = oldX[j] + n2X
pjk1Y = oldY[j] + n2Y
pjk2X = oldX[k] + n2X
pjk2Y = oldY[k] + n2Y
intersectX,intersetY = findIntesection(pij1X,pij1Y,pij2X,pij2Y,pjk1X,pjk1Y,pjk2X,pjk2Y)
#print(intersectX,intersetY)
newX.append(intersectX)
newY.append(intersetY)
getEnlarged(x, y, 20)
plt.plot(x, y)
plt.plot(newX, newY)
plt.show()
This gives result as below
Here it is giving good result by drawing parallel line to each line of our trapezoidal shaped , but i want it to be a closed shape in place of open shape
i want to join the 1st and last coordinate so that it should form a closed shape. Any help will be appreciated .
Using approach from here
outer_ccw parameters combines vertex order and desired offset direction. For CCW order and outer polygon it is 1, for inner polygon it should be -1.
def makeOffsetPoly(oldX, oldY, offset, outer_ccw = 1):
num_points = len(oldX)
for curr in range(num_points):
prev = (curr + num_points - 1) % num_points
next = (curr + 1) % num_points
vnX = oldX[next] - oldX[curr]
vnY = oldY[next] - oldY[curr]
vnnX, vnnY = normalizeVec(vnX,vnY)
nnnX = vnnY
nnnY = -vnnX
vpX = oldX[curr] - oldX[prev]
vpY = oldY[curr] - oldY[prev]
vpnX, vpnY = normalizeVec(vpX,vpY)
npnX = vpnY * outer_ccw
npnY = -vpnX * outer_ccw
bisX = (nnnX + npnX) * outer_ccw
bisY = (nnnY + npnY) * outer_ccw
bisnX, bisnY = normalizeVec(bisX, bisY)
bislen = offset / np.sqrt((1 + nnnX*npnX + nnnY*npnY)/2)
newX.append(oldX[curr] + bislen * bisnX)
newY.append(oldY[curr] + bislen * bisnY)
x = [0, 100, 60, 40]
y = [0, 0, 50, 50]
makeOffsetPoly(x, y, 20)
print(newX, newY)
>>>[-29.424478775259594, 129.4244787752596, 66.79706177729007, 33.202938222709925]
[-14.14213562373095, -14.14213562373095, 64.14213562373095, 64.14213562373095]
Just append the first coordinates to the end of your lists.
x.append(x[0])
y.append(y[0])
newX.append(newX[0])
newY.append(newY[0])
Place this right before you plot. Here's my output

AttributeError: 'list' object has no attribute 'ndim'

I am trying to make a 3d plot using frames and an array. In this code you can see that I have a system of equations that needs to be solved in order to get the "Z" value for my points. Each time through the for loop, I call in 2 values that are needed to solve the system and those 2 values are ultimately my "X" and "Y" values. Upon solving the system I pull one of the values and use it to find my "Z" value.
Running the code gives me
AttributeError: 'list' object has no attribute 'ndim'
on line
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap = 'plasma')
What is the fix for this problem?
from pylab import *
from random import *
from mpl_toolkits import mplot3d
import pandas as pd
from scipy.optimize import fsolve
mdoth = 0.004916
Tinfhin = 334.75
cph = 1008
nsh = .598
hh= 86.68
Ash = .02
n=127
alpha = .00041427
rho = .002129
k=3.041
Le = .0025
Ae = .000001
re = rho * Le/Ae
Ke = k * Ae/Le
nsc = .674
hc = 87.68
Asc = .016
Tinfcin = 295.75
rL = re
mdotc = .004542
cpc = 1007
dframe = pd.read_csv("file name here")
plot(dframe['Sec'], dframe['TC (C)'], 'b-')
#annotate(xy=[818,72.25], s=&apos;First Entry&apos;)
xlabel('Time (s)')
ylabel('Temperature (C)')
title("Exhaust")
show()
plot(dframe['Sec'], dframe['Amb (C)'], 'r-')
xlabel('Time (s)')
ylabel('Temperature (C)')
title("Ambient")
show()
plot(dframe['Sec'], dframe['TC (C)'], 'b-', label = "Exhaust")
plot(dframe['Sec'], dframe['Amb (C)'], 'r-', label = "Ambient")
xlabel('Time (s)')
ylabel('Temperature (C)')
legend()
show()
Tinfhin = dframe['TC (C)']
Tinfcin = dframe['Amb (C)']
X, Y = meshgrid(Tinfhin,Tinfcin)
powerArray = []
for index, row in dframe.iterrows():
Tinfhin = row['TC (C)']
Tinfcin = row['Amb (C)']
def function(z):
II = z[0]
Qc = z[1]
Qh = z[2]
Tc = z[3]
Th = z[4]
Tinfcout = z[5]
Tinfhout = z[6]
F = np.empty((7))
F[0] = mdoth * cph * (Tinfhin - Tinfhout) - Qh
F[1] = nsh * hh * Ash * ((Tinfhin + Tinfhout)/2 - Th) - Qh
F[2] = n * (alpha * II * Th - 1/2 * (II**2) * re + (Ke * (Th-Tc))) - Qh
F[3] = n * (alpha * II * Tc + 1/2 * (II**2) * re + (Ke * (Th-Tc))) - Qc
F[4] = nsc * hc * Asc * (Tc - (Tinfcin + Tinfcout)/2) - Qc
F[5] = mdotc * cpc * (Tinfcin - Tinfcout) - Qc
F[6] = (alpha * (Th - Tc))/(rL/n + re) - II
return F
guess = np.array([1,1,1,1,1,1,1])
z = fsolve(function, guess)
power = n * z[0]**2 * rL
powerArray.append(power)
Z = powerArray
ax = axes(projection='3d')
ax.set_xlabel("TC")
ax.set_ylabel("Ambient")
ax.set_zlabel("Voltage")
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap = 'plasma')
ax.view_init(0, 180)

Python matplotlib - set_data and set_3d_properties don't seem to be updating my plot

I am currently working on a Yee Solver script for uni, but when I try to animate my 3D graph, the graph is not what is expected. It works for a 2D plot, but I can't seem to translate that into 3D. From my understanding, set_data and set_3d_properties need a 1D array to work, which I am inputting.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib.widgets import Slider
# Program Variables
wv_lgth_num = 10
graph_type = '3d'
t = 0
# Physical Constants
c = 3e8
mu_r = 1
eps_r = 1
# Source Constants
f = 2e9
omega = 2*f*(np.pi)
amp = 1.0
wv_lgth = c/f
period = 1/f
# Step size
dz = wv_lgth/20
dt = ((c/f)/20)/c
#dt = ((1/f)/20)/1
# Axis Grids
z_grid = np.arange(0,wv_lgth_num*wv_lgth,dz)
t_grid = np.arange(0,10*period,dt)
# Number of steps
num_z = z_grid.size
num_t = t_grid.size
# Coefficients
coe_E = c*dt/(eps_r*dz)
coe_H = c*dt/(mu_r*dz)
# E and H Matricies
E_mat = np.zeros((num_z,num_t))
H_mat = np.zeros((num_z,num_t))
# Generating Values for E and H
for time in range(0,num_t-1):
for pos in range(0,num_z-1):
# Source Wave
if pos == 0:
H_mat[0,time] = amp*np.sin(omega*t_grid[time])
# All cases of Yee Solver
if pos == 1:
if time == 0:
H_mat[1,0] = 0
E_mat[0,0] = 0
else:
H_mat[1,time] = H_mat[1,time-1] + coe_H*(E_mat[1,time-1] - E_mat[0,time-1])
E_mat[0,time] = E_mat[0,time-1] + coe_E*(H_mat[1,time] - H_mat[0,time])
if pos > 1 and pos != num_z-1:
if time == 0:
H_mat[pos,0] = 0
E_mat[pos-1,0] = 0
if time > 0:
H_mat[pos,time] = H_mat[pos,time-1] + coe_H*(E_mat[pos,time-1] - E_mat[pos-1,time-1])
E_mat[pos-1,time] = E_mat[pos-1,time-1] + coe_E*(H_mat[pos,time] - H_mat[pos-1,time])
if pos == num_z-1:
if time == 0:
H_mat[num_z-1,0] = 0
E_mat[num_z-2,0] = 0
E_mat[num_z-1,0] = 0
if time > 0:
H_mat[num_z-1,time] = H_mat[num_z-1,time-1] + coe_H*(E_mat[num_z-1,time-1] - E_mat[num_z-2,time-1])
E_mat[num_z-2,time] = E_mat[num_z-2,time-1] + coe_E*(H_mat[num_z-1,time] - H_mat[num_z-2,time])
E_mat[num_z-1,time] = E_mat[num_z-2,time]
def update(val):
t = slider_time.val
if graph_type == '2d':
a.set_ydata(E_mat[:,t])
b.set_ydata(H_mat[:,t])
if graph_type == '3d':
a.set_3d_properties(E_mat[:,t])
a.set_data(z_grid,np.zeros((num_z,num_t))[:,t])
b.set_3d_properties(np.zeros((num_z,num_t))[:,t])
b.set_data(z_grid,H_mat[:t])
fig.canvas.draw_idle()
print(H_mat)
print(H_mat[:,t].size)
print(z_grid)
print(np.zeros((num_z,num_t))[:,t].size)
# Creating plot
if graph_type == '3d':
fig, ax = plt.subplots()
ax = plt.axes(projection='3d')
b, = ax.plot3D(z_grid,H_mat[:,t],np.zeros((num_z,num_t))[:,t], label='H')
a, = ax.plot3D(z_grid,np.zeros((num_z,num_t))[:,t],E_mat[:,t], label='E')
plt.title('Light Wave')
ax.set_xlabel('z')
ax.set_ylabel('x')
ax.set_zlabel('y')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
if graph_type == '2d':
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
a, = plt.plot(z_grid,E_mat[:,t], label='E (yz plane)')
b, = plt.plot(z_grid,H_mat[:,t], label='H (xz plane)')
plt.title('Light Wave')
plt.xlabel('z')
plt.ylabel('x')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
Any help would be appreciated. The middle for loop is just generating my functions, using the Yee Method.

How to Animate a 3D graph on Python

I'm looking to animate my graph (below) and I'm not sure where or how to start since I have no experience animating. I'm not sure how it works or what the structure of the code should be, so if someone can offer a pseudo-code or an algorithm, I would greatly appreciate it. I have provided the code I used to graph the plot below, too.
enter code here
from scipy.integrate import odeint
import scipy as sci
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as ani
# Universal Gravitational Const.
G = 6.674e-11
# Defining Mass
m1 = 2
m2 = 3.5
m3 = 2.3
# Init positions in graph (array)
pos1 = [-5,0,1]
pos2 = [5,0,10]
pos3 = [0,1,3]
p01 = np.array(pos1)
p02 = np.array(pos2)
p03 = np.array(pos3)
# Init velocities (array)
vi1 = [1,0.01,0]
vi2 = [-5,0,1]
vi3 = [0,-1,0]
v01 = np.array(vi1)
v02 = np.array(vi2)
v03 = np.array(vi3)
#Function
def derivs_func(y,t,G,m1,m2,m3):
d1 = y[:3]
d2 = y[3:6]
d3 = y[6:9]
v1 = y[9:12]
v2 = y[12:15]
v3 = y[15:18]
dist12 = np.sqrt((pos2[0]-pos1[0])**2 + (pos2[1]-pos1[1])**2 + (pos2[2]-pos1[2])**2)
dist13 = np.sqrt((pos3[0]-pos1[0])**2 + (pos3[1]-pos1[1])**2 + (pos3[2]-pos1[2])**2)
dist23 = np.sqrt((pos3[0]-pos2[0])**2 + (pos3[1]-pos2[1])**2 + (pos3[2]-pos2[2])**2)
dv1dt = m2 * (d2-d1)/dist12**3 + m3 * (d3-d1)/dist13**3
dv2dt = m1 * (d1-d2)/dist12**3 + m3 * (d3-d2)/dist23**3
dv3dt = m1 * (d1-d3)/dist13**3 + m2 * (d2-d3)/dist23**3
dd1dt = v1
dd2dt = v2
dd3dt = v3
derivs = np.array([dd1dt,dd2dt,dd3dt,dv1dt,dv2dt,dv3dt])
derivs3 = derivs.flatten()
return derivs3
yo = np.array([p01, p02, p03, v01, v02, v03])
y0 = yo.flatten()
time = np.linspace(0,200,500)
sol = odeint(derivs_func, y0, time, args = (G,m1,m2,m3))
x1 = sol[:,:3]
x2 = sol[:,3:6]
x3 = sol[:,6:9]
fig = plt.figure(figsize = (15,15))
ax = fig.add_subplot(111,projection = '3d')
ax.plot(x1[:,0],x1[:,1],x1[:,2],color = 'b')
ax.plot(x2[:,0],x2[:,1],x2[:,2],color = 'm')
ax.plot(x3[:,0],x3[:,1],x3[:,2],color = 'g')
ax.scatter(x1[-1,0],x1[-1,1],x1[-1,2],color = 'b', marker = 'o', s=30, label = 'Mass 1')
ax.scatter(x2[-1,0],x2[-1,1],x2[-1,2],color = 'm', marker = 'o',s=90, label = 'Mass 2')
ax.scatter(x3[-1,0],x3[-1,1],x3[-1,2],color = 'g', marker = 'o',s=60, label = 'Mass 3')
ax.legend()

Categories