Plot multiple graph using same graph - python

I have written one code where I want to plot multiple graphs in a same plot. When I run this, I do not get any result or any error. I am trying to take each value of a and plot graph using the program. So i suppose to have 4 graph as a have 4 elements. Most importantly all graphs shall be in a same figure. Though I am not getting any error or any result I am a bit confuse whether the for loop is working or not. When I use a fixed alpha value and, without using for loop, my code works perfectly. Any idea how to perform that? If my question is not clear please let me know.
import numpy as np
import matplotlib.pyplot as plt
r=10**-6
a=np.array([10,30,60,90])
E=[]
B=[]
gamma_sa=58.6*10**-3
gamma_sw=25*10**-3
gamma_pa=153*10**-3
gamma_pw=110*10**-3
gamma_aw=72.5*10**-3
kt= 1.38*10**-23*290
i=0
for n in a:
alpha=n*(np.pi/180)
while i<360:
beta=(90-i)*(np.pi/180)
if i>=alpha*180/np.pi and i<=180-alpha*180/np.pi:
Energy= 2*np.pi*r**2*(gamma_pw+gamma_sw*np.cos(alpha)+gamma_sa*(1-np.cos(alpha))-0.5*gamma_aw*np.sin(alpha)**2)
elif i>=180+alpha*180/np.pi and i<=360-alpha*180/np.pi:
Energy=2*np.pi*r**2*(gamma_sw+gamma_pw*(np.cos(alpha))+gamma_pa*(1-np.cos(alpha))-0.5*gamma_aw*np.sin(alpha)**2)
elif i>180-alpha*180/np.pi and i<180+alpha*180/np.pi :
x=np.arcsin(((1/np.tan(-beta))*(1/np.tan(alpha))))
w=np.cos(alpha)
y=np.arctan((np.cos(-beta))/(np.sqrt((np.sin(beta)**2)-(np.cos(alpha)**2))))
z= (2*r**2)*((x*w)-y)
A_pa= (np.pi*r**2)*(1-np.cos(alpha))+z
A_sa=(2*np.pi*r**2)*(1-np.cos(alpha))-A_pa
A_sw=(2*np.pi*r**2)-A_sa
A_pw=(2*np.pi*r**2)-A_pa
Energy= (gamma_sa*A_sa)+(gamma_pa*A_pa)+(gamma_sw*A_sw)+(gamma_pw*A_pw)-(np.pi*r**2*gamma_aw*np.sin(alpha)**2)
else:
x=np.arcsin(((1/np.tan(beta))*(1/np.tan(alpha))))
w=np.cos(alpha)
y=np.arctan((np.cos(beta))/(np.sqrt((np.sin(beta)**2)-(np.cos(alpha)**2))))
z= (2*r**2)*((x*w)-y)
A_pa= (np.pi*r**2)*(1-np.cos(alpha))+z
A_sa=(2*np.pi*r**2)*(1-np.cos(alpha))-A_pa
A_sw=(2*np.pi*r**2)-A_sa
A_pw=(2*np.pi*r**2)-A_pa
Energy= (gamma_sa*A_sa)+(gamma_pa*A_pa)+(gamma_sw*A_sw)+(gamma_pw*A_pw)-(np.pi*r**2*gamma_aw*np.sin(alpha)**2)
orientation=i
i=i+0.1
E.append(Energy/kt)
B.append(orientation)
plt.figure(1)
plt.title('Change of surface energy with rotation')
plt.plot(B,E)
plt.grid (axis='both')
plt.xlabel(r'$90^0 $ - $\beta $')
plt.ylabel(r'E($\alpha $)/kT')
plt.show()

The problem is that you are putting the plot command outside the for loop and so the 4 curves will not be plotted. Moreover some of your variables needed to be redefined. Following is the working solution (without the if else statements):
import numpy as np
import matplotlib.pyplot as plt
# r, a, 5 gamma values and kt here
fig = plt.figure(figsize=(8, 6))
for n in a:
i = 0
E=[]
B=[]
alpha=n*(np.pi/180)
while i<360:
# Code here
.
.
.
Energy= (gamma_sa*A_sa)+(gamma_pa*A_pa)+(gamma_sw*A_sw)+(gamma_pw*A_pw)-(np.pi*r**2*gamma_aw*np.sin(alpha)**2)
orientation=i # Mind the indent. Should be outside elif
i=i+0.1
E.append(Energy/kt)
B.append(orientation)
plt.plot(B,E, label='$%d^o$'%n) # Mind the indentation here. Should be outside the while loop
plt.title('Change of surface energy with rotation')
plt.grid (axis='both')
plt.xlabel(r'$90^0 $ - $\beta $')
plt.ylabel(r'E($\alpha $)/kT')
plt.legend()
plt.tight_layout()
Output

Related

Simulating a square wave with a duty cycle (python)

I was trying to simulate a square wave with a duty cycle but something went wrong and i've been spending the last 3 hours understandig why.
Here are the pictures of what the function i have to use (1), what i should get (2), what I get (3) and the script (4).
https://imgur.com/a/mcbwoyS
δ varies from o to 1 (in my plot it was 0.6)
Here is my code
#libraries
import numpy as np
from matplotlib import pyplot as plt
#function
R=3290
C=1.1693*10**(-6)
f=1000
ft=10
tau=(ft*2*np.pi)**-1
delta=tau*f
D=0.6
x=np.linspace(-2/f,2/f, 4999)
k=np.zeros(5000)
i=0
k[0]=1
while i<5000:
k[i]=2*i+1
i+=1
ck = (2/(np.pi*k))*np.sin(k*np.pi*D)
omegak=(2*np.pi)*k*f
Ak=1/(np.sqrt(1+(k*f/ft)**2))
Dphik=np.arctan(-k*f/ft)
g=np.zeros(4999)
for j in range(0,4999):
g[j]=np.sum(ck*np.cos(omegak*x[j]))
#plot
plt.figure(figsize=(10,5))
plt.plot(x, g)
plt.xlabel('t[T]')
plt.ylabel('g(t)')
plt.show()
As you can see from the pictures i doesn't really work that well and i dont know why.

trying to plot a graph but comes back empty

hi trying to plot the graph of the results from a while loop but keeps returning an empty graph and saying there is a value error
#create function f(n)
def f(n):
if (n % 2)==0:
return n/2
else:
return (3*n+1)/2
#loop funtion
q=63
while q != 1:
q=f(q)
#plot the function
import numpy as np
import matplotlib.pyplot as plt
i=np.linspace(0,10,3)
plt.plot(q,i)
plt.show()
It might be helpful to properly indent the code as it's is easier to interpret :)
The reason you got value error was because the dimensions of your x and y values are dissimilar. While for x you were passing a variable of size 1, for y you are passing an array of size 3. Furthermore, when using matplotlib's plot function, it's advised to specify the attributes of the plot function which determine the kind of plot you want (otherwise it can output an empty plot). I have inputted example values in the revised code below.
Hope this helps in achieving your main goal of plotting the function!
import numpy as np
import matplotlib.pyplot as plt
def f(n):
if (n % 2)==0:
return n/2
else:
return (3*n+1)/2
#loop function
q=63
while (q != 1):
q=f(q)
#plot the function
i=np.linspace(0,10,3)
#Here i is an array of type float of size 3, so you need to pick one of the
#values in i to plot with the value of q(which is a float variable of size 1)
plt.plot(q, i[2], color='green', marker='o')
plt.show()

How'd I use the Pyplot function in Python?

I'm having trouble trying to display my results after the program is finished. I'm expecting to see a velocity vs position graph, but for some reason, it's not showing up. Is there something wrong with my code.
import numpy
from matplotlib import pyplot
import time,sys
#specifying parameters
nx=41 # number of space steps
nt=25 #number of time steps
dt=0.025 #width between time intervals
dx=2/(nx-1) #width between space intervals
c=1 # the speed of the initial wave
#boundary conditions
u = numpy.ones(nx)
u[int(0.5/dx):int(1/(dx+1))] = 2
un = numpy.ones(nx)
#initializing the velocity function
for i in range(nt):
un= u.copy()
for i in range(1,nx):
u[i]= un[i] -c*(dt/dx)*(u[i]-u[i-1])
pyplot.xlabel('Position')
pyplot.ylabel('Velocity')
pyplot.plot(numpy.linspace(0,2,nx),u)
There are a few things going on here
You don't need to write out the full name of the packages you are importing. You can just use aliasing to call those packages and use them with those aliases later on. This, for example.
import numpy as np
Your dx value initalization will give you 0 beause you are dividing 2 by 40 which will give you a zero. You can initialize the value of dx by making one of the values in that expression a float, so something like this.
dx=float(2)/(nx-1) #width between space intervals
As Meowcolm Law in the comments suggested in the comments, add pyplot.show() to
show the graph. This is what the edited version of your code will like
import numpy as np
import matplotlib.pyplot as plt
import time,sys
#specifying parameters
nx=41 # number of space steps
nt=25 #number of time steps
dt=0.025 #width between time intervals
dx=float(2)/(nx-1) #width between space intervals
c=1 # the speed of the initial wave
#boundary conditions
u = np.ones(nx)
u[int(0.5/dx):int(1/(dx+1))] = 2
un = np.ones(nx)
#initializing the velocity function
for i in range(nt):
un= u.copy()
for i in range(1,nx):
u[i]= un[i] -c*(dt/dx)*(u[i]-u[i-1])
plt.xlabel('Position')
plt.ylabel('Velocity')
plt.plot(np.linspace(0,2,nx),u)
plt.show()
You can add
%matplotlib inline
in order to view the plot inside the notebook. I missed this step following the same guide.

How to make Plt.plot show my parabolic line in python?

Maybe this will be duplicate question but I couldn't find any solution for this.
Normally what I coded should show me a curved line in python. But with this code I cant see it. Is there a problem with my code or pycharm ? This code only shows me an empty graphic with the correct axes.
And I did adding "ro" in plt.plot(at[i], st, "ro"). This showed me the spots on the graph but what I want to see the complete line.
at = [0,1,2,3,4,5,6]
for i in range(len(at)):
st = at[i]**2
plt.plot(at[i], st)
plt.show()
This is how you would normally do this:
import numpy as np
import matplotlib.pyplot as plt
at = np.array([0,1,2,3,4,5,6])
at2 = at ** 2
plt.plot(at,at2)
plt.show()
you can use something like plt.plot(at,at2, c='red', marker='o') to see the spots.
for detailed explanation please read the documentation.
Maybe rather calculate the to be plotted values entirely before plotting.
at = [0,1,2,3,4,5,6]
y = [xi**2 for xi in at]
plt.plot(at, y)
Or do it alternatively with a function
from math import pow
at = [0,1,2,3,4,5,6]
def parabolic(x):
return [pow(xi,2) for xi in x]
plt.plot(at, parabolic(at))
both return the following plot:
the other answers give fixes for your question, but don't tell you why your code is not working.
the reason for not "seeing anything" is that plt.plot(at[i], st) was trying to draw lines between the points you give it. but because you were only ever giving it single values it didn't have anything to draw lines between. as a result, nothing appeared on the plot
when you changed to call plt.plot(at[i], st, 'ro') you're telling it to draw single circles at points and these don't go between points so would appear
the other answers showed you how to pass multiple values to plot and hence matplotlib could draw lines between these values.
one of your comments says "its not parabolic still" and this is because matplotlib isn't a symbolic plotting library. you just give it numeric values and it draws these onto the output device. sympy is a library for doing symbolic computation and supports plotting, e.g:
from sympy import symbols, plot
x = symbols('x')
plot(x**2, (x, 0, 6))
does the right thing for me. the current release (1.4) doesn't handle discontinuities, but this will be fixed in the next release

How to use matplotlib to plot a function graph if I have 2 prepared np.arrays of points?

I provide a python-code which solves Gauss equations and plots a function graph. I have a problem in plotting my function. When I try to plot a function graph for example - "2sin(2πx)" I see lines which connect point and it isn't that i would see.
import numpy as np
import math
import random
import matplotlib.pyplot as plt
import pylab
from matplotlib import mlab
print 'case1=2sin(2πx)'
print 'case2=cos(2πx)'
print 'case3=5x^3 + x^2 + 5'
Your_function=raw_input("Enter your choise of your function: ")
def Choising_of_function(x, Your_function):
if Your_function=='case1':
return 2*math.sin(2*x*math.pi)
elif Your_function=='case2':
return math.cos(2*x*math.pi)
elif Your_function=='case3':
return 5*x**3 + x**2 + 5
Dimension_of_pol=int(raw_input("Enter your degree of polynom: "))
Points=int(raw_input("Enter number of points: "))# I just need only limited numbers of points to plot a function graph
Interval=int(raw_input("Enter interval of your points: "))
dx=float(raw_input("Enter interval your dx: "))
X_val=[]
Y_val=[]
for i in range(Points):# First, i generate my values of x
x = random.uniform(-Interval, Interval)
X_val.append(x)
for x in X_val:
y=Choising_of_function(x, Your_function)
Y_val.append(y)
print X_val, Y_val
Arr_Xo=[[x**i for i in range(Dimension_of_pol)] for x in X_val]
print Arr_Xo
D_mod={}
D={}
for y, x in zip(Y_val, X_val):
D_mod[y]=x
Arr_X_o=np.array(Arr_Xo)
print Arr_X_o
Arr_X=np.array(X_val) #My array of x-values
print Arr_X
Arr_Y=np.array(Y_val) #My array of y-values
print Arr_Y
m = np.linalg.lstsq(Arr_X_o, Arr_Y)[0]
print m
pylab.plot(Arr_X, Arr_Y, 'go')
line=plt.plot(Arr_X, Arr_Y)
line.show()
How i can plot my function without using frange.
My array of x:
[-15.9836388 13.78848867 -3.39805316 12.04429943 -12.34344464
-19.66512508 6.8480724 -5.58674018 7.59985149 11.46357551
-4.96507337 -2.40178658 -1.71320151 -12.87164233 -3.26385184
-7.44683254 5.52525074 -9.16879057 3.70939966 -4.80486815
-10.35409227 6.72283255 2.00436008 8.68484529 -17.81750773]
My array of y:
[ 0.20523902 -1.941802 -1.19527441 0.54952271 -1.66506802 1.72228361
-1.63215286 1.03684409 -1.17406016 0.45373838 0.43538662 -1.15733373
1.94677887 1.44373207 -1.99242991 -0.65576448 -0.31598064 -1.74524107
-1.9352764 1.88232214 -1.58727561 -1.97093284 0.05478352 -1.83473627
1.8227666 ]
I paste all of it in :
line=plt.plot(Arr_X, Arr_Y)
plt.show()
And my function graph doesnt looks like 2*sin(2px)
The problem is that your x axis values are not in order, therefore when you plot them your points will not be joined to the next point on the x axis, giving a graph that looks like the one in the question. A test of this will be to use plt.scatter instead of plt.plot:
This shows that the points you are generating are in the correct shape as seen in the left most image, however you are just generating the x values slightly wrong.
In order to get a nice looking graph you need to change the way you generate the x values. This can be done using np.linspace, the documentation can be found here.
# for i in range(Points): # First, i generate my values of x
# x = random.uniform(-Interval, Interval)
# X_val.append(x)
# replace the above 3 lines with the one below
X_val = np.linspace(-Interval,Interval,Points)
In addition, there is no need to assign plt.plot to a variable, therefore the last 3 lines of your code should be replaced with:
# pylab.plot(Arr_X, Arr_Y, 'go')
# line=plt.plot(Arr_X, Arr_Y)
# line.show()
# replace the above 3 lines with the one below
pylab.plot(Arr_X, Arr_Y)
plt.show()
This produces the following graph:
I do not know what the reason is to
pylab.plot(Arr_X, Arr_Y, 'go')
as well as
line=plt.plot(Arr_X, Arr_Y)
Why do you need pylab to plot instead of just using pyplot?
Your
line.show() in line 63 gives me an attribute error
"list" object has no attribute "show"
only plt has show(), if you see in print dir(plt)
As I am to lazy to go trough your full code stick to this general plotting example:
import matplotlib.pyplot as plt
figure, axis = plt.subplots(figsize=(7.6, 6.1))
for x in range(0, 500):
axis.plot(x, x*2, 'o-')
plt.show()

Categories