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

  • Context: MATLAB 
  • Thread starter Thread starter Ascendant0
  • Start date Start date
  • Tags Tags
    Error Graph Plotting
Click For Summary
SUMMARY

The discussion focuses on resolving a "RuntimeWarning: invalid value encountered in divide" error when plotting the sinc function using Python's NumPy and Matplotlib libraries. The original code attempts to handle the division by zero using a conditional statement within the sinc function, but this leads to issues when x is an array. A recommended solution is to utilize NumPy's vectorization capabilities or to define the sinc function using numpy.sinc, which inherently manages the division by zero case. The user is encouraged to adjust their linspace to avoid zero or to use numpy.vectorize for handling array inputs effectively.

PREREQUISITES
  • Familiarity with Python programming
  • Understanding of NumPy for numerical operations
  • Basic knowledge of Matplotlib for plotting
  • Concept of vectorization in Python
NEXT STEPS
  • Learn about numpy.vectorize for handling array inputs in custom functions
  • Explore numpy.sinc for a built-in solution to the sinc function
  • Investigate error handling in Python, particularly with NumPy arrays
  • Study advanced plotting techniques using Matplotlib for better visualizations
USEFUL FOR

Python developers, data scientists, and anyone interested in numerical computing and data visualization using NumPy and Matplotlib.

Ascendant0
Messages
176
Reaction score
37
TL;DR
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 11 ·
Replies
11
Views
3K
  • · Replies 11 ·
Replies
11
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
Replies
7
Views
3K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 7 ·
Replies
7
Views
3K
Replies
2
Views
3K