Plotting in python using matplotlib? - python
I have been trying to simulate the first order differential equation using the fourth order Runge-Kutta method, but I am having problems plotting it.
#simulation of ode using 4th order rk method dy/dx=-2y+1.3e^-x,y(0)=5,h=0.01 from sympy import*
import math
import numpy as np
import matplotlib.pyplot as plt
h=0.01;
ti=0;
x=0;
n=0;
y=5;
def f(x,y):
return 1.3*math.exp(-x)-2*y
while x < 10:
k1=f(x,5);
k2=f(x+h/2,y+(h/2)* k1);
k3=f(x+h/2,y+(h/2)* k2);
k4=f(x+h,y+h*k3);
y=y+h/6*(k1+2*(k2+k3)+k4);
x=x+h;
plt.plot(x,y);
I know that the problem is because of updating the x,y values every time the loop runs, but can somebody explain how to plot all the values of (x,y)?
As suggested in the comment, you can create two lists to store x and y values and plot it after the while loop:
import math
import numpy as np
import matplotlib.pyplot as plt
h=0.01;
ti=0;
x=0;
n=0;
y=5;
def f(x,y):
return 1.3*math.exp(-x)-2*y
xs = [x] # <<<
ys = [y] # <<<
while x < 10:
k1=f(x,5);
k2=f(x+h/2,y+(h/2)* k1);
k3=f(x+h/2,y+(h/2)* k2);
k4=f(x+h,y+h*k3);
y=y+h/6*(k1+2*(k2+k3)+k4);
x=x+h;
xs.append(x) # <<<
ys.append(y) # <<<
plt.plot(xs,ys);
Another source for wrong results is the first line in the RK4 loop. Instead of
k1=f(x,5);
use
k1=f(x,y);
since the value of y does not stay constant at the initial value.
Related
How to plot a 2-D graph for a induced velocity function in terms of two variables as shown here?
I am reading a technical paper and trying to reproduce a graph corresponding to the following function: K(x) and E(x) are Legendre's elliptical integrals of the first and second kind respectively. The plot of V_r looks like the following: I tried to plot this function in Python and here is my code: import numpy as np import scipy import matplotlib.pyplot as plt from scipy import special def x(r,z,R): return np.sqrt((-4*r*R)/((R-r)**2+z**2)) def V_z(Gamma,R,r,z): return (-Gamma/4*np.pi)*((2/np.sqrt((R-r)**2+z**2))*(special.ellipk(x(r,z,R))+\ (R**2-r**2-z**2)/((R+r)**2+z**2) * special.ellipe(x(r,z,R)))) def V_r(Gamma,R,r,z): return (-Gamma/4*np.pi)*((4*R*z*np.sqrt((R+r)**2+z**2)/((R+r)**4+z**2*(2*(R+r)**2+z**2)) \ * np.sqrt((R+r)**2+z**2)/((R-r)**2+z**2)))*special.ellipe(x(r,z,R)) r = np.linspace(-5,5,100); z = np.linspace(-5,5,100); V_z_list = [] for i in V_z(0.1,1,r,z): if np.isnan(i).any() == False: print(i) V_z_list.append(i) V_r_list = [] for i in V_r(0.1,1,r,z): if np.isnan(i).any() == False: print(i) V_r_list.append(i) plt.plot(V_z_list) However, I'm getting this graph as a result: Could someone help me fix my code?
Python: ValueError: setting an array element with a sequence. Error while solving simple ode
I have written a simple python code to simulate adaptive fuzzy sliding mode control. My problem is no matter what I do, I get this error. I tried converting list to arrays etc. But to no effect. Kindly help me iron out this issue. What I am trying to do, is, I have created a function that returns 53 elements and then the ode method of scipy integrates it. Here is my code. PFA- import numpy as np import matplotlib.pyplot as plt from scipy.integrate import ode from numpy import exp,sin,cos,concatenate,transpose,pi,tanh from mpl_toolkits.mplot3d import Axes3D c,eta,k,gamma1,gamma2,gamma3,gamma4,gamma5,gamma21,gamma22,gamma23,gamma24,gamma25=2,1.5,2,1,2,3,4,5,6,7,8,9,10 x=np.linspace(0,10,100) xdot=np.linspace(0,10,100) def member(x,z): return exp(-((x+z)/(pi/24))**2) m=[] b=[pi/6,pi/12,0,-pi/12,-pi/6] def f(t,Y): x1,x2,x3,eta1,eta2,eta3,eta4,eta5,eta6,eta7,eta8,eta9,eta10,eta11,eta12,eta13,eta14,eta15,eta16,eta17,eta18,eta19,eta20,eta21,eta22,eta23,eta24,eta25,geta1,geta2,geta3,geta4,geta5,geta6,geta7,geta8,geta9,geta10,geta11,geta12,geta13,geta14,geta15,geta16,geta17,geta18,geta19,geta20,geta21,geta22,geta23,geta24,geta25=Y eta=np.array([eta1,eta2,eta3,eta4,eta5,eta6,eta7,eta8,eta9,eta10,eta11,eta12,eta13,eta14,eta15,eta16,eta17,eta18,eta19,eta20,eta21,eta22,eta23,eta24,eta25]) geta=np.array([geta1,geta2,geta3,geta4,geta5,geta6,geta7,geta8,geta9,geta10,geta11,geta12,geta13,geta14,geta15,geta16,geta17,geta18,geta19,geta20,geta21,geta22,geta23,geta24,geta25]) m,z=[],[] for i in range(5): for j in range(5): m.append(member(x1,b[i])*member(x2,b[j])) for i in range(25): z.append(m[i]/sum(m)) z=np.array(z) e,de=x1-sin(t),x2-cos(t) s=de+c**2*x3+2*c*e f=np.dot(eta,z) g=np.dot(geta,z) u=(1./g)*(-f-c**2*e-2*c*de-sin(t)-eta*tanh(s)-k*s) x1dot=x2 x2dot=f+g*u x3dot=e eta1dot,eta2dot,eta3dot,eta4dot,eta5dot,eta6dot,eta7dot,eta8dot,eta9dot,eta10dot,eta11dot,eta12dot,eta13dot,eta14dot,eta15dot,eta16dot,eta17dot,eta18dot,eta19dot,eta20dot,eta21dot,eta22dot,eta23dot,eta24dot,eta25dot,geta1dot,geta2dot,geta3dot,geta4dot,geta5dot,geta6dot,geta7dot,geta8dot,geta9dot,geta10dot,geta11dot,geta12dot,geta13dot,geta14dot,geta15dot,geta16dot,geta17dot,geta18dot,geta19dot,geta20dot,geta21dot,geta22dot,geta23dot,geta24dot,geta25dot=-2*s*z[0],-2*s*z[1],-2*s*z[2],-2*s*z[3],-2*s*z[4],-2*s*z[5],-2*s*z[6],-2*s*z[7],-2*s*z[8],-2*s*z[9],-2*s*z[10],-2*s*z[11],-2*s*z[12],-2*s*z[13],-2*s*z[14],-2*s*z[15],-2*s*z[16],-2*s*z[17],-2*s*z[18],-2*s*z[19],-2*s*z[20],-2*s*z[21],-2*s*z[22],-2*s*z[23],-2*s*z[24],-3*s*z[0]*u,-3*s*z[1]*u,-3*s*z[2]*u,-3*s*z[3]*u,-3*s*z[4]*u,-3*s*z[5]*u,-3*s*z[6]*u,-3*s*z[7]*u,-3*s*z[8]*u,-3*s*z[9]*u,-3*s*z[10]*u,-3*s*z[11]*u,-3*s*z[12]*u,-3*s*z[13]*u,-3*s*z[14]*u,-3*s*z[15]*u,-3*s*z[16]*u,-3*s*z[17]*u,-3*s*z[18]*u,-3*s*z[19]*u,-3*s*z[20]*u,-3*s*z[21]*u,-3*s*z[22]*u,-3*s*z[23]*u,-3*s*z[24]*u return[x1dot,x2dot,x3dot,eta1dot,eta2dot,eta3dot,eta4dot,eta5dot,eta6dot,eta7dot,eta8dot,eta9dot,eta10dot,eta11dot,eta12dot,eta13dot,eta14dot,eta15dot,eta16dot,eta17dot,eta18dot,eta19dot,eta20dot,eta21dot,eta22dot,eta23dot,eta24dot,eta25dot,geta1dot,geta2dot,geta3dot,geta4dot,geta5dot,geta6dot,geta7dot,geta8dot,geta9dot,geta10dot,geta11dot,geta12dot,geta13dot,geta14dot,geta15dot,geta16dot,geta17dot,geta18dot,geta19dot,geta20dot,geta21dot,geta22dot,geta23dot,geta24dot,geta25dot] Y,t=[],[] for i in range(50): Y.append(0.1) #Y=np.array(Y) y0=[0,0,0] y0=y0+Y t0=0 def int_amar(): t1,dt=10,.01 x=[] for i in range(53): x.append([]) #import pdb; pdb.set_trace() odee=ode(f).set_integrator('dopri5',method='bdf',nsteps=1e6) odee.set_initial_value(y0,t0) while odee.successful() and odee.t<t1: odee.integrate(odee.t+dt) for i in range(53): x[i].append(odee.y[i]) t.append(odee.t) #for i in range(53): # x[i]=np.array(x[i]) print(x1.shape) return x def main(): fun=int_amar() Z,f,g,m=[[],[],[],[],[]],[],[],[] for i in range(5): for j in range(5): m.append(member(fun[0],b[i])*member(fun[1],b[j])) for i in range(25): Z[i].append(m[i]/sum(m)) zetta1,zetta2,zetta3,zetta4,zetta5,zetta6,zetta7,zetta8,zetta9,zetta10,zetta11,zetta12,zetta13,zetta14,zetta15,zetta16,zetta17,zetta18,zetta19,zetta20,zetta21,zetta22,zetta23,zetta24,zetta25=Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],Z[8],Z[9],Z[10],Z[11],Z[12],Z[13],Z[14],Z[15],Z[16],Z[17],Z[18],Z[19],Z[20],Z[21],Z[22],Z[23],Z[24],Z[25] e=fun[0]-sin(t) s=fun[1]+c**2*fun[2]+2*c*e for i in range(len(fun[2])): f.append(np.dot(np.array([[fun[3][i],fun[4][i],fun[5][i],fun[6][i],fun[7][i],fun[8][i],fun[9][i],fun[10][i],fun[11][i],fun[12][i],fun[13][i],fun[14][i],fun[15][i],fun[16][i],fun[17][i],fun[18][i],fun[19][i],fun[20][i],fun[21][i],fun[22][i],fun[23][i],fun[24][i],fun[25][i],fun[26][i],fun[27][i]]]),np.array([[zetta1[i]],[zetta2[i]],[zetta3[i]],[zetta4[i]],[zetta5[i]],[zetta6[i]],[zetta7[i]],[zetta8[i]],[zetta9[i]],[zetta10[i]],[zetta11[i]],[zetta12[i]],[zetta13[i]],[zetta14[i]],[zetta15[i]],[zetta16[i]],[zetta17[i]],[zetta18[i]],[zetta19[i]],[zetta20[i]],[zetta21[i]],[zetta22[i]],[zetta23[i]],[zetta24[i]],[zetta25[i]]]))) g.append(np.dot(np.array([[fun[28][i],fun[29][i],fun[30][i],fun[31][i],fun[32][i],fun[33][i],fun[34][i],fun[35][i],fun[36][i],fun[37][i],fun[38][i],fun[39][i],fun[40][i],fun[41][i],fun[42][i],fun[43][i],fun[44][i],fun[45][i],fun[46][i],fun[47][i],fun[48][i],fun[49][i],fun[50][i],fun[51][i],fun[52][i]]]),np.array([[zetta1[i]],[zetta2[i]],[zetta3[i]],[zetta4[i]],[zetta5[i]],[zetta6[i]],[zetta7[i]],[zetta8[i]],[zetta9[i]],[zetta10[i]],[zetta11[i]],[zetta12[i]],[zetta13[i]],[zetta14[i]],[zetta15[i]],[zetta16[i]],[zetta17[i]],[zetta18[i]],[zetta19[i]],[zetta20[i]],[zetta21[i]],[zetta22[i]],[zetta23[i]],[zetta24[i]],[zetta25[i]]]))) f,g=np.array(f),np.array(g) u=(1./g)*(-f-c*e-sin(t)-eta*tanh(s)-k*s) print(u.shape) for i in range(12): plt.subplot(3,4,i+1) plt.plot(t,fun[i]) #plt.figure(2) #plt.plot(t,u) plt.show() if __name__=='__main__': main()
The issue is on line 30: u=(1./g)*(-f-c**2*e-2*c*de-sin(t)-eta*tanh(s)-k*s) eta is an array but the rest of the terms are scalars. This causes u to be an array and the resulting return list has a mix of scalars and arrays. You probably mistyped the equation here.
My variable is coming up as not defined, when I think I have defined it
This is my code #project starts here import numpy as np import scipy.integrate import matplotlib.pyplot as plt from numpy import pi from scipy.integrate import odeint def deriv(cond,t): for q in range (0,N): i=6*q dydt[i]=cond[i+3] dydt[i+1]=cond[i+4] dydt[i+2]=cond[i+5] r=sqrt((cond[i])**2 +(cond[i+1])**2 +(cond[i+2])**2) dydt[i+3]=-G*M*cond[i]/(r**3) dydt[i+4]=-G*M*cond[i+1]/(r**3) dydt[i+5]=-G*M*cond[i+2]/(r**3) return dydt G=1 M=1 N=12 vmag=((G*M)/(2))**(0.5) theta = np.linspace(0,2*pi,N) x=2*np.cos(theta) y=2*np.sin(theta) vx=-vmag*np.sin(theta) vy=vmag*np.cos(theta) z=np.zeros(N) vz=np.zeros(N) t=np.linspace(0,30,100) cond=list(item for group in zip(x,y,z,vx,vy,vz) for item in group) sln=odeint(deriv, cond, t, args=(G,M)) I am getting an error message about dydt not being defined. I thought I had defined it within my derivatives function. My intention is for it to be a vector with the appropriate derivatives in it (hence the use of i) of the cond array. Why is my definition wrong?
"dydt" is not defined, you should define it before you can use indexes on it. Regarding your code, you could do something like this: i = 6*q dydt = list(range(i))
finding more than one root for a set of trigonometric equations: python
I am using python's fsolve to find roots of a set of equations using the script below: from scipy.optimize import fsolve from scipy.interpolate import spline import math import numpy as np #from mpldatacursor import datacursor %pylab from matplotlib import pyplot as plt import matplotlib.dates as mdates %matplotlib inline def equations(p): x,y,z = p f1 = (1 - 2*math.cos(math.radians(x)) + 2*math.cos(math.radians(y)) - 2*math.cos(math.radians(z)) + 0.8) f2 = (1 - 2*math.cos(math.radians(5*x)) + 2*math.cos(math.radians(5*y)) - 2*math.cos(math.radians(5*z))) f3 = (1 - 2*math.cos(math.radians(7*x)) + 2*math.cos(math.radians(7*y)) - 2*math.cos(math.radians(7*z))) return (f1,f2,f3) x,y,z = fsolve(equations,(0,0,0)) #print equations((x,y,z)) This works perfect with one small issue. This generates only one set of solution i.e., one value for each x, y, z to satisfy those equations, but since these are trigonometric there should be atleast 2 solutions. How can I use fsolve (or anything else) to find two solutions for x, y, z for a given starting point. Example: for x,y,z = fsolve(equations,(0,0,0)), is it possible to generate two values for x,y,z instead of one solution? Thanks for the help.
While loops for lists?
I'm pretty new to programming and I have a quick question. I am trying to make a Gaussian function for a range of stars. However i want the size of undercurve be at 100 for all the stars. I was thinking of doing a while loop saying that while the total length of undercurve be 100. However, I get an error and I'm guessing it has something to do with it being a list. I'm showing you guys my code to see if you can help me out here. Thanks! I get a syntax error: can't assign to call function import numpy import random import math import matplotlib.pyplot as plt import matplotlib.mlab as mlab import scipy from scipy import stats from math import sqrt from numpy import zeros from numpy import numarray variance = input("Input variance of the star:") mean = input("Input mean of the star:") space=numpy.linspace(-4,1,1000) sigma = sqrt(variance) Max = max(mlab.normpdf(space,mean,sigma)) normalized = (mlab.normpdf(space,mean,sigma))/Max def random_y_pt(): return random.uniform(0,1) def random_x_pt(): return random.uniform(-4,1) import random def undercurve(size): result = [] for i in range(0,size): y = random_y_pt() x = random_x_pt() if y < scipy.stats.norm(scale=variance,loc=mean).pdf(x): result.append((x)) return result size = 1 while len(undercurve(size)) < 100: undercurve(size) = undercurve(1)+undercurve(size) print undercurve(size) plt.hist(undercurve(size),bins=20) plt.show()
If your error is something like SyntaxError: can't assign to function call then that's because of your line undercurve(size) = undercurve(1)+undercurve(size) Which is trying to set the output of the right-hand side as the value of undercurve(size), which you cannot do. It sounds like you actually want to see just the first 100 items in the list returned by undercurve(size). For that, use undercurve(size)[:100]