I want to plot a function in python but I can't seem to do it. I am running the following code, but I get an error that says I can't multiply a generator and a float together. Where is this coming from?
from math import *
import matplotlib.pyplot as plt
t=0.1
cd=t*exp(-t/2)
tau=10
nt=100
v=0.01
w=0.9
u=0.4
s0=10
p=5
for i in range (1,10):
sigma= u/(w+(s0/(p*cd)))
print(sigma)
C= lambda ksi: cd * (1-exp(((u-w * sigma)/v)*ksi))
plt.plot([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1],[C(i for i in range (-10,-1))])
plt.xlabel(ksi)
plt.ylabel(concentration)
plt.title("tumeur avec regénessence")
plt.legend()
plt.show()
t+=tau/nt
this is the error I get
Traceback (most recent call last):
File "C:\Users\ilyes\Downloads\tumeur_avec_regénesence.py", line 18, in <module>
plt.plot([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1],[C(i for i in range (-10,-1))])
File "C:\Users\ilyes\Downloads\tumeur_avec_regénesence.py", line 17, in <lambda>
C= lambda ksi: cd * (1-exp(((u-w * sigma)/v)*ksi))
TypeError: unsupported operand type(s) for *: 'float' and 'generator'
use
plt.plot([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1],[C(i) for i in range (-10, 0)])
instead of
plt.plot([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1],[C(i for i in range (-10,-1))])
explanation: you want to apply C on each value not on the hole list at once.
range(-10,-1) gives you values -10 <= v < -1 but you want -1 to be included.
Use numpy.
import numpy as np
import matplotlib.pyplot as plt
tau=10
nt=100
v=0.01
w=0.9
u=0.4
s0=10
p=5
ksi = np.arange(-10,0)
for t in np.arange(1,10)*tau/nt:
cd = t*np.exp(-t/2)
sigma = u/(w+(s0/(p*cd)))
C = lambda ksi: cd * (1-np.exp(((u-w * sigma)/v)*ksi))
plt.plot(ksi, C(ksi), label=f"t = {t}")
plt.xlabel("ksi")
plt.ylabel("concentration")
plt.title("tumeur avec regénessence")
plt.legend()
plt.show()
Related
I want to plot a function for 0.975 ≤ x ≤ 1.044 with step size 0.0001 and wonder how I can use a float number as step size?
The function I want to plot is y=−1+7x−21x2 +35x3 −35x4 +21x5 −7x6 +x7 and I have computed the code
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.975, 1.044, 0.0001)
# calculate y for each element of x
y = x**7 - 7*x**6 + 21*x**5 - 35*x**4 + 35*x**3 - 21*x**2 + 7*x -1
fig, ax = plt.subplots()
ax.plot(x, y)
The code works fine if I replace the step size value to a int instead of a float, but when I use 0.0001 I get the error below. Is there someway I can fix this?
File "/opt/anaconda3/lib/python3.8/site-packages/numpy/core/function_base.py", line 117, in linspace
num = operator.index(num)
TypeError: 'float' object cannot be interpreted as an integer
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/idalundmark/Desktop/Programmeringsteknik för matematiker (Labb)/Avklarade labbar/untitled0.py", line 13, in <module>
x = np.linspace(0.975, 1.044, 0.0001)
File "<__array_function__ internals>", line 5, in linspace
File "/opt/anaconda3/lib/python3.8/site-packages/numpy/core/function_base.py", line 119, in linspace
raise TypeError(
TypeError: object of type <class 'float'> cannot be safely interpreted as an integer.
In numpy.linespace() the third parameter indicates the number of samples to generate. (Default it is 50) This could be a non-negative integer value. For more information, you can refer to the official documentation
As #AcaNg suggested in the comments, you can use numpy.arrange() instead. This is also similar to linspace, but uses a step size (instead of the number of samples).
If you do as shown here and below, the problem will be solved.
import matplotlib.pyplot as plt
import numpy as np
N = (1.044 - 0.975) / 0.0001
x = np.linspace(0.975, 1.044, num=int(N), endpoint= True)
# calculate y for each element of x
y = x**7 - 7*x**6 + 21*x**5 - 35*x**4 + 35*x**3 - 21*x**2 + 7*x -1
fig, ax = plt.subplots()
ax.plot(x, y)
I’m having trouble using the bisect optimizer within scipy. Here are the relevant portions of my code:
How I’m importing things
import numpy as np
import scipy.optimize as sp
import matplotlib.pyplot as plt
Break in code, section causing errors below
#All variables are previously defined except for h
def BeamHeight(h):
x = 1000e3*M[i]*h/(fw*h^3-(fw-wt)(h-2*ft)^3) - Max_stress_steel
return x
for i in range(0,50):
h = np.zeros((50))
h[i] = sp.bisect(BeamHeight, hb, 5,xtol = 0.001)
Causing this error:
Traceback (most recent call last):
File "ShearMoment.py", line 63, in <module>
h[i] = sp.bisect(BeamHeight, hb, 5,xtol = 0.001)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/zeros.py", line 248, in bisect
r = _zeros._bisect(f,a,b,xtol,rtol,maxiter,args,full_output,disp)
File "ShearMoment.py", line 58, in BeamHeight
x = 1000e3*M[i]*h/(fw*h^3-(fw-wt)(h-2*ft)^3) - Max_stress_steel
TypeError: 'float' object is not callable
I understand that scipy.optimize expects a function as one of its arguments. Am I doing this incorrectly?
In Python, concatenation is not implicitly multiplication, and ^ is not exponentiation. Multiplication must be made explicit with *, and exponentiation must be written as **. This part of BeamHeight:
fw*h^3-(fw-wt)(h-2*ft)^3
must be written as
fw*h**3-(fw-wt)*(h-2*ft)**3
I am trying to plot a graph using matplotlib.pyplot in Python but getting an error:
int() argument must be a string, a bytes-like object or a number, not
'list'
in the second-to-last line.
Here is the code:
import numpy as np
import random
import matplotlib.pyplot as plt
#constants
mUn0 = 1350
Vcat = 18000000
n = 2 * pow(10,16)
e = 1.6 * pow(10,-19)
#variable
E = 1000
d = []
f = []
for i in range(1,E):
j = log(n*e*mUn0) + log(i) - 0.5 * log(1+pow((mUn0*i/Vcat),2))
f.append(j)
d.append(log(i))
plt.xlabel('E')
plt.ylabel('V')
plt.subplot(2,1,2)
plt.subplot(f,d,'bo')
plt.show()
Thank you
pyplot.subplot() requires subplot(nrows, ncols, plot_number), all three options are integers.
Matplotlib is trying to cast your f and d lists to integer type and failing.
Just a couple of small issues. You have to use plt.plot() to plot, and you can't just use log, you need np.log() or to import the math module and then use math.log(). I noted the lines I changed with #FIXED
import numpy as np
import random
import matplotlib.pyplot as plt
#constants
mUn0 = 1350
Vcat = 18000000
n = 2 * pow(10,16)
e = 1.6 * pow(10,-19)
#variable
E = 1000
d = []
f = []
for i in range(1,E):
j = np.log(n*e*mUn0) + np.log(i) - 0.5 * np.log(1+pow((mUn0*i/Vcat),2)) #FIXED
f.append(j)
d.append(np.log(i)) #FIXED
plt.xlabel('E')
plt.ylabel('V')
plt.subplot(2,1,2) #not needed, but maybe a holdover from full code
plt.plot(f,d,'bo') #FIXED
plt.show()
That takes care of the syntax errors. Using a subplot works with one plot but you don't need it, so I don't know what type of logic error that is (do you want two plots?)
I was trying to fit a specific function with scipy and I got weird results. I decided to test something I know the answer to so I created this:
from scipy.optimize import curve_fit as cf
import numpy as np
import random
def func(x,a):
return a+X
X =[]
for i in range (10):
V = random.random()
X.append(i+3 + V/10)
print cf(func, np.array(range(10)),np.array(X))
I expected to get something around 3, nevertheless, here the output:
(array([ -2.18158824e-12]), inf)
As a side note, I tried to see what I send something to func and I got this:
print func(np.array(range(10)),3)
Traceback (most recent call last):
File "/tmp/py1759O-P", line 16, in <module>
print func(np.array(range(10)),3)
File "/tmp/py1759O-P", line 6, in func
return a+X
TypeError: unsupported operand type(s) for +: 'int' and 'list
What am I doing wrong?
Don't use x and X as variable names when they carry such different meanings (or perhaps you didn't know Python is case sensitive?):
def func(x,a):
return a+X
X =[]
x is a numpy array, X is a list, and a is a scalar parameter value.
a+X results in an error since you can not add a scalar to a list.
In func, the argument is x, but X is used in the body of the function.
Here's a modified version of your code. It uses a few more features of numpy (e.g. np.random.random() instead of random.random()).
from scipy.optimize import curve_fit as cf
import numpy as np
def func(x, a):
return a + x
n = 10
xdata = np.arange(n)
ydata = func(xdata, 3) + np.random.random(n) / 10
print cf(func, xdata, ydata)
The output is
(array([ 3.04734293]), array([[ 8.19208558e-05]]))
After my blunder with the infinity factorial sum XD I redid the code, but I keep getting syntax error :\
from scitools.std import *
from math import factorial, cos, e
from scipy import *
import numpy as np
def f1(t):
return 0.5*(1 + sum( (a**(2*n)*cos(2*sqrt(1 + n)*t))/(e**a**2*factorial(n)) for n in range(0,100)))
a=4
t = linspace(0, 35, 1000)
y1 = f1(t)
plot(t, y1)
xlabel(r'$\tau$')
ylabel(r'P($\tau$)')
legend(r'P($\tau$)')
axis([0.0, 35.0, 0.0, 1.0])
grid(True)
show()
It says that there's an error in my program: invalid syntax and the a is red :\
What's wrong now? :(
EDIT:
I've added another ) at the end of the sum, but now I keep getting huge error:
Traceback (most recent call last):
File "D:\faxstuff\3.godina\kvantna\vježbe\qm2\v8\plot.py", line 12, in <module>
y1 = f1(t)
File "D:\faxstuff\3.godina\kvantna\vježbe\qm2\v8\plot.py", line 8, in f1
return 0.5*(1 + sum( (a**(2*n)*cos(2*sqrt(1 + n)*t))/(e**a**2*factorial(n)) for n in range(0,100)))
File "C:\Python26\lib\site-packages\numpy\core\fromnumeric.py", line 1415, in sum
res = _sum_(a)
File "D:\faxstuff\3.godina\kvantna\vježbe\qm2\v8\plot.py", line 8, in <genexpr>
return 0.5*(1 + sum( (a**(2*n)*cos(2*sqrt(1 + n)*t))/(e**a**2*factorial(n)) for n in range(0,100)))
TypeError: unsupported operand type(s) for /: 'numpy.ndarray' and 'numpy.float64'
Should I make so that the sum expression gives back an array from which I can plot or?
The parentheses in return 0.5*(1 + sum(... are not balanced.
As a matter of style, I would recommend avoiding from <module> import *-style imports. In your specific example you end up with a single-letter variable name (e) imported into the global namespace, which you then proceed to use. This could lead to confusion and, worse, hard-to-diagnose bugs.