Matplotlib plots straight line for Exp[x] - python

It plots correctly if I delete the function problem2, I need to print both of them, but whenever that's done, Exp[x] is printed as a straight line. I've printed f(x) to see is it getting the right values or not and it does get the right values. Problem2 is a differential eqn. I have solved it using odeint, f(x) is the answer of Problem2 given in the book, I want to plot both of them together to see whether the solution given by python is correct or not. Problem20 = 10 is an initial value I have taken randomly ( can it be also a source of error, I failed to see how if so).
import numpy as np
import scipy.integrate as sciint
import matplotlib.pyplot as plt
def problem2(y, x):
return x + x * y
def f(x):
return np.exp(x)
if __name__ == '__main__':
x = np.linspace(0, 5, 50)
problem20 = 10
sol = sciint.odeint(problem2, problem20, x)
plt.plot(x, sol, label="Calculated")
print(f(x))
plt.plot(x, f(x), label="Given in book")
plt.legend()
plt.show()

Related

Finding value of a parameter using set of data

I have a set of value for x and y and I'm looking to find a way to find the value of a parameter for a function.
I have a function y = Ax^{4/3}.
I was thinking about using curvefit, but I'm not sure if this is the right way.
I tried to linearize the function and find the slope with polyfit, but the slope change radically if I remove some points.
Edit: I tried curvefit and something strange is happening. curvefit gives me A=0.55, but this value doesn't fit at all. However, 0.055 seems to work.
Here's my code.
def func(A,x):
return A*x**(4/3)
popt,pcov = curve_fit(func,x[:18], y[:18])
Any help will be appraciated.
Here is an example on how to fit data to your model:
Import relevant libraries:
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
Define x values:
x = np.linspace(0, 10)
Define a function representing your model:
def f(x: np.ndarray, a: float) -> float:
return a * x ** (4/3)
Let's sample data from the above model and add noise:
y = f(x, a=16) * np.random.uniform(1, 2, len(x))
Perform the curve fitting:
popt, pcov = curve_fit(f, x, y)
Plot the results:
plt.scatter(x, y)
plt.plot(x, f(x, *popt), c="r")
plt.show()

Plotting Taylor series expansions from Sympy in MatPlotLib [duplicate]

iยดam trying to plot the function sin(x)/x and a taylor approximation of it.
i use python 3 and pyzo - the first plot works but i have problems converting the series coming from the sympy module to an numpy expression that would work.
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x
x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine
### this is a code that removes the "0(x**something)" part of
the series at the end
i found it here http://pastebin.com/ZNQakWP7
def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
p = t.as_coeff_exponent(x)[1]
if p < n:
expansion.append(t)
else:
break
if not removeO:
expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####
y_t=series(sp.sin(x)/x,x,0,6,removeO=True)
if i look at y_t now i get this approximation
out: x**4/120 - x**2/6 + 1
Now i try to convert this to numpy in order to plot it as i did with the first function.
f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before
plt.plot(x, y_t, 'b') #this is where the problem occurs
i get the first plot also a second error message:
File "<console>", line 1, in <module>
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
ret = ax.plot(*args, **kwargs)
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
for line in self._get_lines(*args, **kwargs):
How can i achieve my idea to plot something coming from sympy?
Another idea i had was to convert the sympy out from the series to a string and then parsing this somehow to a numpy expression. I would be thankful for any help here!
I think your problem is that this:
plt.plot(x, y_t, 'b') #this is where the problem occurs
should be something like:
plt.plot(x, f_t(x), 'b')
f_t is the lambdified series, so it is a callable function that evaluates its argument.
I used lambdify in the following example, and it works for me:
from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify
import numpy as np
import matplotlib.pyplot as plt
func = sin(x)/x
taylor = series(func, n=6).removeO()
evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])
t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()
Here's the plot generated by the script.

Plotting a function with more than one variable in Matplotlib

import numpy as np
import matplotlib.pyplot as plt
import sympy as sym
from ipywidgets.widgets import interact
sym.init_printing(use_latex="mathjax")
x, y, z, t = sym.symbols('x y z t')
We were given a function in class to write as code
\begin{equation}
p_w(z,t)=\frac{1}{\sqrt{\pi \left(1-\exp\left[-2 t\right]\right)}}
\exp\left[-\frac{\left(z-\exp\left[-t\right]\right)^{2}}{1-
\exp\left[-2t\right]}\right]
\end{equation}
which I have written as this
p_w = (1/(sym.sqrt((sym.pi)*(1-(sym.exp(-2*t))))))*(sym.exp((-(z-sym.exp(-t))**2)/(1-sym.exp(-2*t))))
Then find the partial differential equation
โˆ‚๐‘ก๐‘๐‘ค(๐‘ง,๐‘ก)=โˆ‚๐‘ง[๐‘ง๐‘๐‘ค(๐‘ง,๐‘ก)]+1/2 โˆ‚2๐‘ง๐‘๐‘ค(๐‘ง,๐‘ก)
which I have written as this:
LHS=sym.diff(p_w,t,1)
#differentiate once with respect to t
RHS=sym.diff(z*p_w,z,1)+((1/2)*(sym.diff(p_w,z,2)))
#now differentiate with respect to z
Now we need to plot it and can only use matplotlib/numpy/sympy libraries.
Plot ๐‘๐‘ค(๐‘ง,๐‘ก) for the three values t=0.1,1,10 in a ๐‘๐‘ค(๐‘ง,๐‘ก) versus z diagram.
Here's what I've got so far:
t_points=[0.1,1,10]
#pw = sym.lambdify(t,p_w)
mytspace=np.linspace(0,10,200)
#myzspace=pw(mytspace)
plt.xlabel("t axis")
plt.ylabel("z axis")
plt.plot(t_array,np.zeros(3),'bs')
I haven't studied multivariable calculus before so I'm a bit lost!
Since one of your variables is given (you know t must be t=0.1, t=1 or t=10) your only variable for plotting is z. I know you are using sympy for the calculations, but for plotting maybe it's simpler to just return p_w as a numpy array. You can define a function to return p_w as so:
import numpy as np
import matplotlib.pyplot as plt
def p_w(z, t):
p_w = (1/(np.sqrt((np.pi)*(1-(np.exp(-2*t))))))*(np.exp((-(z-np.exp(-t))**2)/(1-np.exp(-2*t))))
return p_w
This will give you a numpy array with the results of p_w(z, t) where z is an array and t is just one number. Then you can just iterate over the values of t that you need:
t_points=[0.1, 1, 10]
z = np.linspace(0,10,200)
for t in t_points:
plt.plot(z, p_w(z, t), label='t = {0}'.format(t))
plt.legend()
plt.show()
Result:

How do I use scipy and matplotlib to fit a reverse sigmoid function

I have some data points which I was successfully able to graph, but now I would like to fit a curve to the data. I looked into other stackoverflow answers and found a few questions, but I can't seem to implement them. I know the function is a reverse sigmoid.
I would like to use this hill equation: https://imgur.com/rYqEASm
So far I tried to use the curve_fit() function from the scipy package to find the parameters but my code always breaks.
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
x = np.array([1, 1.90, 7.70, 30.10, 120.40, 481.60, 1925.00, 7700.00])
y = np.array([4118.47, 4305.79, 4337.47, 4838.11, 2660.76, 1365.05, 79.21, -16.40])
def fit_hill(t,b,s,i,h):
return b + ((t-b)/(1 + (((x * s)/i)**-h)))
plt.plot(x,y, 'o')
plt.xscale('log')
plt.show()
params = curve_fit(fit_hill, x, y)
[t,b,s,i,h] = params[0]
fit_hill should have 6 parameters.
(see https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html)
fit_hill(x,t,b,s,i,h).
You should try to give an initial guess for parameters.
For example in your model, when x=0, the value is t. So you can set the value at x=0 as an estimate for t.
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
x = np.array([1, 1.90, 7.70, 30.10, 120.40, 481.60, 1925.00])
y = np.array([4118.47, 4305.79, 4337.47, 4838.11, 2660.76, 1365.05, 79.21])
def fit_hill(x,t,b,s,i,h):
return b + ((t-b)/(1 + (((x * s)/i)**-h)))
plt.plot(x,y, 'o')
popt,pcov = curve_fit(fit_hill, x, y,(4118,200,1,1900,-2))
plt.plot(x,fit_hill(x,*popt),'+')
plt.xscale('log')
plt.show()
Have you drawn your model to visualize if it is suitable for you data ?
s and i, used only in s/i could be replaced with one variable in your model.

Plot/Convert an expression coming from sympy: Taylor series with matplotlib

iยดam trying to plot the function sin(x)/x and a taylor approximation of it.
i use python 3 and pyzo - the first plot works but i have problems converting the series coming from the sympy module to an numpy expression that would work.
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x
x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine
### this is a code that removes the "0(x**something)" part of
the series at the end
i found it here http://pastebin.com/ZNQakWP7
def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
p = t.as_coeff_exponent(x)[1]
if p < n:
expansion.append(t)
else:
break
if not removeO:
expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####
y_t=series(sp.sin(x)/x,x,0,6,removeO=True)
if i look at y_t now i get this approximation
out: x**4/120 - x**2/6 + 1
Now i try to convert this to numpy in order to plot it as i did with the first function.
f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before
plt.plot(x, y_t, 'b') #this is where the problem occurs
i get the first plot also a second error message:
File "<console>", line 1, in <module>
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
ret = ax.plot(*args, **kwargs)
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
for line in self._get_lines(*args, **kwargs):
How can i achieve my idea to plot something coming from sympy?
Another idea i had was to convert the sympy out from the series to a string and then parsing this somehow to a numpy expression. I would be thankful for any help here!
I think your problem is that this:
plt.plot(x, y_t, 'b') #this is where the problem occurs
should be something like:
plt.plot(x, f_t(x), 'b')
f_t is the lambdified series, so it is a callable function that evaluates its argument.
I used lambdify in the following example, and it works for me:
from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify
import numpy as np
import matplotlib.pyplot as plt
func = sin(x)/x
taylor = series(func, n=6).removeO()
evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])
t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()
Here's the plot generated by the script.

Categories