In the following code I am trying to add an index to my graph so I can label the different two lines, However I am running into the following error, how can I fix it?
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-115-3c7429a6498c> in <module>()
36 n_inv_4.append(1.0 / ((2*i)**4))
37 n_lines = plt.loglog(n, n_inv_4)
---> 38 plt.figlegend((error_lines[0], n_lines[0]), ('Error', '1/n**4'), ('upper right'))
39 plt.show()
TypeError: 'Text' object does not support indexing
and here is my code, below I have the image it outputs:
from math import pi, cos, sin
from matplotlib import pyplot as plt
def simpson(f, a, b, n):
h = (b - a) / (2*n)
s = f(a) + f(b)
for i in range(1, 2*n, 2):
s += 4 * f(a + i * h)
for i in range(2, 2*n-1, 2):
s += 2 * f(a + i * h)
return s * h / 3
diffs = {}
exact = 1 - cos(pi/2)
for n in range(1, 100):
result = simpson(lambda x: sin(x), 0.0, pi/2, n)
diffs[2*n] = abs(exact - result) # use 2*n or n here, your choice.
ordered = sorted(diffs.items())
x,y = zip(*ordered)
plt.autoscale()
plt.loglog(x,y)
error_lines = plt.xlabel("Intervals n")
plt.ylabel("Absolute Error")
n = []
n_inv_4 = []
for i in range(1,100):
n.append(2*i)
n_inv_4.append(1.0 / ((2*i)**4))
n_lines = plt.loglog(n, n_inv_4)
plt.figlegend((error_lines[0], n_lines[0]), ('Error', '1/n**4'), ('upper right')
plt.show()
and here is the output:
I think you just missed the intended line for inserting error_lines = - it should be one line above.
However, note that you can simply add a legend without parameters (plt.legend()) when you set the label-kwargs of your plot commands before, e.g.
plt.loglog(x, y, label='firstplot')
plt.loglog(n, n_inv_4, label='secondplot')
Related
I am writing a program where the user enters a mathematical equation (e.g. x^2 + 2x + 2) and the function plotFunction will plot it out on a graph using matplotlib.
When I enter a parameter such as "x2" it returns the error:
ValueError: Illegal format string "x2"; two marker symbols
import matplotlib.pyplot as plt
import numpy as np
class Plotter:
def __init__(self):
pass
def plotFunction(self, func):
x = np.arange(-100, 100)
y = func
plt.plot(x, y)
plt.show()
p1 = Plotter()
p1.plotFunction("x**2")
This is not exactly ideal, however, it is what I came up with that works right now.
import matplotlib.pyplot as plt
def plot_func():
three = float(input("X ** 3:\n"))
two = float(input("X ** 2:\n"))
one = float(input("X:\n"))
b = float(input("B:\n"))
n = -10
x = []
y = []
while n <= 10:
x.append(n)
y.append( (three * n) ** 3 + (two * n) ** 2 + (one * n) + b)
n += 1
return x, y
x, y = plot_func()
plt.scatter(x, y)
plt.show()
I basically just broke up the different parts and it will work with any function up to x ** 3 and of course you could add more. Just make your x ** 3 equal 0 if you only have an x ** 2 function. Again, not ideal, but it will work until you can figure out something better.
So, I checked other questions and answers about this and I didn't understand the reason, could you please help me with this, please
I'm learning linear regression and I implemented the code for Linear Regression with two variables.
This implementation should predict the sum of two numbers but it's giving an error
Implemented code here:
import matplotlib.pyplot as plt
import numpy as np
x = np.array([[1,1],[1,2],[2,3],[3,4],[4,5],[5,6]])
y = np.array([2,3,5,7,9,11])
#hypothesis
def hypothesis(theta, x):
return theta[0] + theta[1]*x[0] + theta[2]*x[1]
#cost function J(t0, t1, t2)
def cost(theta, x, y):
m = x.shape[0]
error = 0
for i in range(m):
d = x[i]
hx = hypothesis(theta, d)
error = error + (hx - y[i])**2
return error
#differentiation of cost function
def diffGradient(theta, x, y):
grad = np.zeros((3,))
m = x.shape[0]
for i in range(m):
hx = hypothesis(theta, x)
grad[0] = grad[0] + (hx - y[i])
grad[1] = grad[1] + (hx - y[i])*x[0]
grad[2] = grad[2] + (hx - y[i])*x[1]
return 0
#gradient descent funtion
def gradientDescent(x, y, learning_rate = 0.001):
theta = [-2.0,0.0,1.0]
iter = 100
error_list = []
theta_list = []
for i in range(iter):
d = x[i]
grad = diffGradient(theta, d, y)
e = cost(theta, d, y)
error_list.append(e)
theta_list.append((theta[0],theta[1],theta[2]))
#simultaneous update
theta[0] = theta[0] - learning_rate*grad[0]
theta[1] = theta[1] - learning_rate*grad[1]
theta[2] = theta[2] - learning_rate*grad[2]
return theta, theta_list, error_list
final_theta, theta_list, error_list = gradientDescent(x,y)
After the above line, I'm getting this error
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-56-bda7687d0af9> in <module>
----> 1 final_theta, theta_list, error_list = gradientDescent(x,y)
<ipython-input-55-033133fbfbd5> in gradientDescent(x, y, learning_rate)
8 d = x[i]
9 grad = diffGradient(theta, d, y)
---> 10 e = cost(theta, d, y)
11 error_list.append(e)
12 theta_list.append((theta[0],theta[1],theta[2]))
<ipython-input-41-6a07f4b81c9c> in cost(theta, x, y)
5 for i in range(m):
6 d = x[i]
----> 7 hx = hypothesis(theta, d)
8 error = error + (hx - y[i])**2
9 return error
<ipython-input-27-43ce9d7c567b> in hypothesis(theta, x)
1 #hypothesis
2 def hypothesis(theta, x):
----> 3 return theta[0] + theta[1]*x[0] + theta[2]*x[1]
IndexError: invalid index to scalar variable.
I don't know what I'm doing wrong. Any help would be appreciated.
What's the x that you pass to
gradientDescent(x,y)
Look at the traceback and try to figure out what variable has the problem - the problem is that you can't index a scalar, a number. It has to be a list or array. Trace the problem variable back up through your code.
In the traceback:
in the problem line you use x[0] and x[1]. What's x at this point?
In the calling function it's d, which is set with d = x[i]
In gradientDescent the passed variable is again called d, and set as d = x[i]
So you have 3 levels of indexing. Does the original x support that?
You have to understand the problem before you try a fix.
I'm trying to plot the result of a trapezoidal method into a graph, I figured out that to get the exact value of the integral you can use integrate.trapz(f(x)) from the scypy libary. This is my second month learning comp math, not really sure about libraries usage yet.
Here is my code
from scipy import integrate
def f(x):
return 1 - x - 4*x**3 + 2*x**5
def trapezoid(a, b, n):
h = (b - a) / n
s = (f(a) + f(b))
i = 1
while i < n:
s += 2 * f(a + i * h)
i += 1
area = ((h / 2) * s)
return area
def graphTrapezoid():
val = []
err = []
exact_sum = integrate.trapz(f(b))-integrate.trapz(f(a))
for i in range (2,100):
val.append(trapezoid(a,b,i))
errVal = abs((trapezoid(a,b,i) - exact_sum)/exact_sum)
err.append(errVal)
plt.plot(val, err)
a = 1
b = 5
n = 1
graphTrapezoid()
Below is the error statement that I got
IndexError Traceback (most recent call last)
<ipython-input-134-504c0acc46bf> in <module>
39
40
---> 41 graphTrapezoid()
<ipython-input-134-504c0acc46bf> in graphTrapezoid()
29 val = []
30 err = []
---> 31 exact_sum = integrate.trapz(f(b))-integrate.trapz(f(a))
32 for i in range (2,100):
33 val.append(trapezoid(a,b,i))
~\Anaconda3\lib\site-packages\numpy\lib\function_base.py in trapz(y, x, dx, axis)
4059 slice1 = [slice(None)]*nd
4060 slice2 = [slice(None)]*nd
-> 4061 slice1[axis] = slice(1, None)
4062 slice2[axis] = slice(None, -1)
4063 try:
IndexError: list assignment index out of range
From the scipy.integrate.trapz documentation:
The function definition is:
scipy.integrate.trapz(y, x=None, dx=1.0, axis=-1)
Where y should be "array_like". However, you are passing two integer values to the trapz function.
If you want to integrate f betweeen b and a, maybe you could first define a list of x values:
a = 1
b = 5
step = 0.1 # A smaller step will give you a more precise result
x = []
for i in range(int((b-a)/step + 1)):
x.append(a + i*step)
Then, sample your function:
y = [f(val) for val in x]
And lastly, you could integrate your samples:
result = integrate.trapz(y, x, dx=step)
In the following code I have implemented composite Simpsons Rule in python. I have tested it by integrating f = sinx over [0,pi/2] and plotting the resulting absolute error as a function of n for a suitable range of integer values for n. As shown below. Now I am trying to verify that my method is of order 4. To do this instead of plotting the error vs n I need to plot n vs n^(-4) to show that both have the same slope.
from math import pi, cos, sin
from matplotlib import pyplot as plt
def simpson(f, a, b, n):
"""Approximates the definite integral of f from a to b by the composite Simpson's rule, using 2n subintervals """
h = (b - a) / (2*n)
s = f(a) + f(b)
for i in range(1, 2*n, 2):
s += 4 * f(a + i * h)
for i in range(2, 2*n-1, 2):
s += 2 * f(a + i * h)
return s * h / 3
diffs = {}
exact = 1 - cos(pi/2)
for n in range(1, 100):
result = simpson(lambda x: sin(x), 0.0, pi/2, n)
diffs[2*n] = abs(exact - result) # use 2*n or n here, your choice.
ordered = sorted(diffs.items())
x,y = zip(*ordered)
plt.autoscale()
plt.loglog(x,y)
plt.xlabel("Intervals")
plt.ylabel("Error")
plt.show()
this results in my error graph:
You can add another line to your plot by making another call to plt.loglog(). So just before your plt.show() you can add:
n = []
n_inv_4 = []
for i in range(1,100):
n.append(2*i)
n_inv_4.append(1.0 / ((2*i)**4))
plt.loglog(n, n_inv_4)
Note that the above calculations use (2*i) to match the (2*n) used in the simpson method.
I am currently using Python to solve a function with the rk method. r8_rkf45 is a file, which helps to plot the function (http://people.sc.fsu.edu/~jburkardt/py_src/rkf45/rkf45.py).
import numpy as np
import matplotlib.pyplot as plt
from numpy import zeros, linspace, exp, sqrt
from rkf45 import *
from r8_rkf45 import *
def rungekutta(ode2, x0, t, n):
n = 200
z = zeros(n)
a = zeros(n)
f = ode2
neqn = 1
abserr = sqrt(finfo(double).eps)
relerr = sqrt(finfo(double).eps)
flag = 1
t_start = 0.0
t_stop = 10.0
t_out = t = 0.0
y = np.array([0.0])
yp[t, y] = ode2[t, y]
for i_step in xrange(0, n - 1):
t = ((n - i_step + 1) * t_start + (i_step - 1) * t_stop) / (n)
t_out = ((n - i_step) * t_start + (i_step) * t_stop) / (n)
y, yp, t = r8_rkf45(ode2, neqn, y, yp, t, t_out, relerr, abserr, flag)
z[i_step - 1] = t
a[i_step - 1] = y
def ode2(x0, t):
alpha = -1
xp = -alpha * x0
return xp
def main():
n = 200
c, b = (0.0, 10.0)
x0 = 1.0
t = linspace(c, b, n)
y = np.array([0.0])
yp[t, y] = ode2[t, y]
plt.plot()
result_rungekutta = rungekutta(yp, x0, t, n)
plt.plot(t, result_rungekutta, "r")
plt.xlabel(t)
plt.ylabel(xp)
plt.legend("Runge-Kutta")
plt.show()
if __name__ == "__main__":
main()
But I still get a Traceback:
Traceback (most recent call last):
File "C:/Python27/idea.py", line 50, in <module>
main()
File "C:/Python27/idea.py", line 40, in main
yp [t,y]= ode2 [t, y]
TypeError: 'function' object has no attribute '__getitem__'
What am I doing wrong?
ode2 is a function, not a list (or other object that has members that can be accessed via indices). Try, yp [t,y]= ode2(t, y)
You need to call a function with ():
yp [t,y]= ode2(t, y)