trying to plot a graph but comes back empty - python

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()

Related

Plot multiple graph using same graph

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

Python plot- Change X axis scale and Plot threshold

I want to change x axis scale. For example, I am reading a data from txt file.
This data is like a=[ 1,2,5,9,12,17] and I want to convert to this number this scale[0,3]. I mean this data a=[ 1,2,5,9,12,17] has 6 number but I need to scale these number in [0,3] so that my axis should only be c=[0,3].I have other data c=[1,2,3,4,5,6]. I plot this data in normal way plot(a,b) but I want to scale this like plot(c,b). I don't know which function I will use for that.
Other question, I used plt.axhline(y=0.005), I want to change with linestyle='-' because otherwise giving continues line. How can I put max and minimum threshold with '-' ?
Second question answer:
import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='b', linestyle='--',linewidth=1)
plt.axhline(y=-0.5, color='b', linestyle='--',linewidth=1)
plt.show()` I solved my second question like this.
If NumPy is available you can use the interp function to generate your scaled values (docs):
import numpy as np
scaled_a = np.interp(a, (min(a), max(a)), c)
The scaled_a variable is a NumPy array that can be passed to matplotlib's plot function in place of the original a variable.
If NumPy is not available you'll have to do a bit of arithmetic to calculate the new values:
def scaler(x, old_min, old_max, new_min, new_max):
old_diff = old_max - old_min
new_diff = new_max - new_min
return ((x - old_min) * (new_diff / old_diff)) + new_min
old_min = min(a)
old_max = max(a)
scaled_a = [scaler(x, old_min, old_max, c[0], c[1]) for x in a]
The variable scaled_a is now a python list, but it can still be passed to the plot function.

How to make a 2D plot with color density as the 3rd argument in python 3

I'd like to make a plot where each point it has its x&y value and it also has a third value expressing the color density at that point. Applying my python code in mathematica I am able to do it using the following code, but now I want to do it only using python(preferably using matlibplot).
def printMath2DTableMethod():
print('{', end="")
for i in range(0, lines, 1):
print('{', end="")
for j in range(0, columns, 1):
f = int(columns * rearrange_.rearrangeMethod(i) + rearrange_.rearrangeMethod(j))
print('%d' % size[f], end = '')
if (j < columns - 1):
print(',', end='')
if (i < lines - 1):
print('},')
else:
print('}}')
The plotting should look something similar to the images of these two questions
How can I make a scatter plot colored by density in matplotlib?
How to plot a density map in python?
it should have a colorbar at the side and the points with the biggest density should be on the top of the other points(if they overlap).
The data that this method produces I append it to some file and it looks like:
1,2,4,5,6,2,6 x256 columns in total
3,2,4,5,1,6,4
4,2,5,6,1,7,5
x256 rows in total
The plotting can be made by using the code directly or by reading the data from the file, but what I don't know is how to assign values to x(which is the i at the 1st for loop at the code above), to y(which is the j at the 2nd for loop at the code above) and especially to the 3rd argument, the one which will show the color density(which is the size[f] at the code above) since it is depended on i and j of the for loops.
I have been trying to research and solve it myself all these days, but not much success, so any help would be highly appreciated. Thanks in advance :)
Here are examples for both plots you linked
import matplotlib.pyplot as plt
import scipy as sp
# scatterplot as link 1
Data = sp.randn(1000,3)
plt.scatter(Data[:,0],Data[:,1],c=Data[:,2],cmap='magma')
plt.colorbar()
# density matrix as link 2
Nbins = 50
M = sp.zeros((Nbins+1,Nbins+1))
xinds = sp.digitize(Data[:,0],sp.linspace(-3,3,Nbins)) # chose limits accordingly
yinds = sp.digitize(Data[:,1],sp.linspace(-3,3,Nbins))
# to account for the highest density drawn over the others
sort_inds = sp.argsort(Data[:,2])[::-1]
Data = Data[sort_inds,:]
xinds = xinds[sort_inds]
yinds = yinds[sort_inds]
for i in range(Data.shape[0]):
M[xinds[i],yinds[i]] = Data[i,2]
plt.matshow(M,cmap='magma',
extent=(Data[:,0].min(),Data[:,0].max(),Data[:,1].max(),Data[:,1].min()),
aspect='equal')
plt.colorbar()

BeamDeflection Plot

I'm having trouble with my script not showing a plot.
The plot must show the deflection of the beam as a function of the x-coordinate of the entire beam. I don't know if I can make the statements: "x[i]>a[v]" if x is not given...
import numpy as np #Imports NumPy
import matplotlib.pyplot as plt
def beamPlot(beamLength, loadPositions, loadForces, beamSupport):
l=beamLength #Scalar
a=loadPositions #Vector
W=loadForces #Vector
x=np.array(range(0,l))
E=200*10**9 #Constant [N/m^2]
I=0.001 #Constant [m^4]
#Makes an empty vector with the same size as x
y=np.empty_like(x)
for i in range(np.size(x)): #Continues as long as the vector x
for v in range(np.size(a)):
if a[v]==[ ] and W[v]==[ ]:
return np.zeros(np.size(x))
elif beamSupport=="both" and x[i]<a[v]:
y[i]=np.sum(((W[v]*(l-a[v])*x[i])/(6*E*I*l))*(l**2-x[i]**2-(l-a[v])**2))
elif beamSupport=="both" and x[i]>=a[v]:
y[i]=np.sum(W[v]*a[v]*(l-x[i])/(6*E*I*l)*(l**2-(l-x[i])**2-a[v]**2))
elif beamSupport=="cantilever" and x[i]<a[v]:
y[i]=np.sum((W[v]*x[i]**2)/(6*E*I)*(3*a[v]-x[i]))
elif beamSupport=="cantilever" and x[i]>=a[v]:
y[i]=np.sum((W[v]*a[v]**2)/(6*E*I)*(3*x[i]-a[v]))
deflection=y
plt.ylim([0,10000])
plt.xlim([0,l])
plt.title("Beam deflection")
plt.plot(x, deflection)
plt.show()
Your array x is created with a list of integers from range(0,l), which means that the elements in the array are of type int. You create the y array using np.epty_like() which means that it also has elements of type int. Unless you are using huge values for the loads, the float values created by your calculations get rounded to 0 when converted to int, so the plot is a flat line at y=0.
You can fix this by specifying that y should contain float values when it is created by adding dtype=float to:
y=np.empty_like(x, dtype=float)
You should also remove the plt.ylim(0,10000) and instead let matplotlib autoscale your y-axis, since the displacements are probably not going to be this large for any reasonable values of loads (given your stiffness)

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