1

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()
2
  • Can you show what the graph looks like? Commented Sep 30, 2015 at 14:51
  • 2
    A couple points: (1) exponentiation is **, not ^; (2) x is an integer array, so x[i]**2/2 uses integer arithmetic in Python 2. You can fix that by using x[i]**2/2.0. Commented Sep 30, 2015 at 14:56

4 Answers 4

3

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)

Details

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.

References

Sign up to request clarification or add additional context in comments.

Comments

2

The problems in your code:

  • you used the xor operator ^ instead of the exponentiation operator **
  • you didn't pass the lists of values to plt.plot() properly
  • by dividing an integer by an integer, you were actually doing integer division, i.e. 3/2 -> 1
  • you accidentally rounded all of the results into integers by assigning to 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)
  • the range of indexes you were iterating over was very unclear, lots of room for mistakes there... (not actually a bug)

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

4 Comments

I didn't realize that python would do integer division. Cool trick to get around it. Any advice on how to plot my points using a higher order degree polynomial?
Never mind realized I could just create more points with the arange command.
Advice: 1) use IPython and work interactively 2) just write any formula you want in Python, it will just work, e.g. x ** 3.5 - 6.7 3) make sure to use floats instead of integers 4) define each formula as a function and then map that on the range of inputs (read about the map() function)
If this answered your question and you think it is the best of the given answers, please accept it.
0

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.])

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.