Reputation: 1342
I'm trying to write a simple program to plot x
vs y
. However, it does not seem to be computing the correct value ofy
.
For instance in the first case when x = -1
the value of e^(x^2/2 - x) -1
should be 3.48
, but instead it is returning 1
.
The other error I have is it doesn't seem to be plotting x
vs y
, but instead a separate line for each value of x
.
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.arange(-2, 2)
y = np.arange(-2, 2)
for i in range(-3, 3):
y[i] = math.exp(( x[i]^2/2 ) - x[i])-1
print x, y
plt.plot([x, y])
plt.show()
Upvotes: 1
Views: 160
Reputation: 20257
The built in numpy
array operations are perfect for this.
This is the line you want:
y = np.exp(np.power(x, 2)/2 - x) - 1
Full code then becomes
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.arange(-2, 2)
y = np.exp(np.power(x, 2)/2 - x) - 1
print(x, y)
plt.plot(x, y)
plt.show()
(Note, the plot
statement is also changed here)
If you start to write a loop when working with numpy
, look for another way. Vector operations can be much faster (sometimes several orders of magnitude) than the corresponding python code, that's why people love it. Many of the basic operations (+
, -
, *
, /
, **
) are even overloaded. Check the last item in the References section for more info.
Upvotes: 3
Reputation: 8711
The problems in your code:
^
instead of the exponentiation operator **
plt.plot()
properly3/2 -> 1
y[i]
, because y
was made as an array of integers (as @efirvida explained, this is because np.arange()
infers the type from the given values)This works on Python 3.4:
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.arange(-2, 2)
y = np.ndarray(len(x), float)
for i in range(len(x)):
y[i] = math.exp(( (x[i]**2)/2.0 ) - x[i])-1
print(x, y)
plt.plot(x, y)
plt.show()
Upvotes: 2
Reputation: 47800
^
isn't the exponentiation operator in Python, it's bitwise-XOR. You need to use **
instead. Also, if you're plotting functions over arrays, it's much cleaner to write your function directly and apply it via vectorize
.
Also, if you're using Python2.7 you should add from __future__ import division
to get true (floating point) division, otherwise x/2
will use integer division instead.
from __future__ import division
import math
import numpy as np
import matplotlib.pyplot as plt
f = np.vectorize(lambda x: math.exp((x**2/2) - x) - 1)
x = np.arange(-2, 2)
y = f(x)
Finally, you need to pass x
and y
as separate arguments to plot
, not put them in a list:
plt.plot(x, y)
Upvotes: 0
Reputation: 4855
As @xnx answer my question few days ago "NumPy arrays have a fixed datatype (dtype) which is inferred from the initialization data if you don't specify it yourself. It won't change unless you tell it to"
And this is what happening here, you are using a range of int np.arange(-2, 2), and then the number has no floating point division.
import numpy as np
import math
import matplotlib.pyplot as plt
x = np.arange(-2., 2.) #<-- use dots to define a float array
y = []
for i in range(-3, 3):
y.append(math.exp(( x[i]**2/2 ) - x[i])-1)
y = np.array(y)
print x, y
# x = array([-2., -1., 0., 1.])
# y = array([ 3.48168907, 0. , 0.39346934, 53.59815003, 3.48168907, 0.])
Upvotes: 0