MATLAB Getting Error When Plotting Graph (Using Python w/ matplotlib.pyplot)

AI Thread Summary
The discussion revolves around a Python code snippet using matplotlib to plot the sinc function, which generates a "RuntimeWarning" due to division by zero when x equals 0. The original code attempts to handle this with a conditional statement in the sinc function but still encounters issues with vectorized input. A suggested solution is to use `numpy.vectorize` to properly handle the case when x is zero without causing an error. Additionally, an alternative approach is provided, which involves modifying the input array to avoid division by zero altogether. The conversation highlights the importance of managing edge cases in numerical computations effectively.
Ascendant0
Messages
175
Reaction score
38
TL;DR Summary
We were given an assignment to produce a plot of the function ## f(x) = sin(x)/x ##, and set it up visually the way he has (including a red dashed line on y = 0). I have completed the code, but I'm getting an error message and not sure why
This is my code:
Python:
import numpy as np
import matplotlib.pyplot as plt

def sinc(x):
    return np.where(x == 0, 1, np.sin(x)/x)

x = np.linspace(0, 25, 500) # mainly for setting the number of values generated
y = sinc(x)

plt.xlim(0, 25) # set range for x axis
plt.ylim(-0.4, 1) # set range for y axis

plt.plot(x, y, color='green', linewidth=1.5, label='sinc(x)')  # sin(x)/x graph
plt.axhline(0, color='red', linewidth=1, linestyle='--', label='y=0') # y=0 graph

plt.xlabel('x')
plt.ylabel('sinc(x)')
# obviously these 2 are for the x and y axes labels

plt.show()
-----------------------

Now, while that is showing my plot correctly just as he had on the example, it is giving me this error message when I run it:
"RuntimeWarning: invalid value encountered in divide return np.where(x == 0, 1, np.sin(x)/x)"

I'm not sure why though, and I don't want to mess it up. Please keep in mind this is my VERY first time EVER using Python (and I don't know MATLAB either), so I compiled that part based off the best way I could figure out to do it. Would there be a better way to code that part, or is there just something slight I need to adjust in it? Again, please keep in mind it is plotting correctly as-is, so I have what I need, I just want to clean up whatever the problem is. Help would be greatly appreciated, as I can't figure it out. Every time I try to adjust it, it ends up not working anymore.
 
Last edited by a moderator:
Physics news on Phys.org
So, I cleaned up my code some. Changed these two lines to this:

"def sinc(x):
return np.sin(x)/x)"

Realized I didn't need that other code. I still get the same error, but I'm thinking now it's due to sin(x)/x being invalid at 0. Just not sure how to get it to overlook that, or if it is just something it will always point out like that?
 
Maybe you could adjust your linspace() function with a starting value of 0.0001 or something to that effect.
 
Change your definition of sinc to return 1 if the argument is 0.
 
Ascendant0 said:
TL;DR Summary: We were given an assignment to produce a plot of the function ## f(x) = sin(x)/x ##, and set it up visually the way he has (including a red dashed line on y = 0). I have completed the code, but I'm getting an error message and not sure why

This is my code:

import numpy as np
import matplotlib.pyplot as plt
Code:
def sinc(x):
    return np.where(x == 0, 1, np.sin(x)/x)

The problem is that python will evaluate all of the arguments of np.where before passing them to it - including, in the case x == 0, the result of np.sin(0)/0. Thus you need to ensure that np.sin(x)/x is not evaluated for x == 0.

Orodruin said:
Change your definition of sinc to return 1 if the argument is 0.

That by itself doesn't work for vectorised input, which is almost the entire point of NumPy. There is, however, a solution: use numpy.vectorize.

Python:
>>> import numpy as np
>>> def my_sinc(x):
...     if x == 0:
...         return 1.0
...     else:
...         return np.sin(x)/x
 
>>> my_sinc(np.array([0,1]))
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    my_sinc(np.array([0,1]))
  File "<pyshell#7>", line 2, in my_sinc
    if x == 0:
ValueError: The truth value of an array with more than one element is ambiguous. 
Use a.any() or a.all()
>>> np.vectorize(my_sinc)(np.array([0,1]))
array([1.        , 0.84147098])

I should note for completeness that NumPy has its own library function numpy.sinc, defined as <br /> \operatorname{sinc} : x \mapsto \begin{cases} 1 &amp; x = 0, \\ \frac{\sin(\pi x)}{\pi x} &amp; x \neq 0. \end{cases}

EDIT: Another option is
Python:
x = np.linspace(0, 25, 5000)
y = np.concatenate([
   np.array([1.0]),
   np.sin(x[1:])/x[1:]],
   axis = 0
)
 
Last edited:
pasmith said:
That by itself doesn't work for vectorised input, which is almost the entire point of NumPy.
Not if you just take the function as written, obviously. There are simple solutions though. Vectorizing should not be necessary.
 

Similar threads

Replies
3
Views
2K
Replies
1
Views
2K
Replies
6
Views
3K
Replies
11
Views
4K
Replies
3
Views
2K
Back
Top