I'm writing a function using numpy and matplotlib.pyplot to generate a slope field based on some code I found in an old blog. That code works fine, but I was trying to make a function for it. The function takes a range for x and y, a frequency, and finally some differential equation in the form dy/dx = (some function of x and y). The differential equation is itself a function. Of course, depending on the equation, division by zero can occur. When it does, I get a
RuntimeWarning: divide by zero encountered in double_scalars
and the rest of the slope field displays in pyplot as expected, absent a value at whatever coordinate(s) caused division by zero. Finding the actual value of the equation at those coordinates is beyond the scope of the simple function, but I would obviously like to handle such cases.
The differential equation I used to test different methods of dealing with this can be described in python as:
def fun3(x, y):
return (x + y) / (x - y)
For this particular equation, the only point causing the issue is the point (0, 0). As such, the slope field returned by my function looks like:
No line at (0, 0), but that's not an issue. The problem is that before the field is displayed, I get the RuntimeWarning
described above.
The code that actually generates the field is here:
for j in x:
for k in y:
slope = diff(j, k)
domain = np.linspace(j - 0.07, j + 0.07, 2)
def fun(x1, y1):
z = slope * (domain - x1) + y1
return z
field += plt.plot(domain, fun(j, k))
Where x
and y
are ndarrays containing the x-values and y-values, respectively, where the lines are to be drawn, including in this case (0, 0). field
is what is returned by the function, a list of artists added to the plot.
My first attempt at fixing the issue was to just catch the ZeroDivisionError
within the loop, before assigning slope
, using:
try:
diff(j, k)
except ZeroDivisionError:
continue
Where diff
is the equation described by fun3
above. However, this failed to produce the desired result and in fact changed nothing at all about the output. When I tried recreating this result outside of the function using something like,
try:
fun3(0, 0)
except ZeroDivisionError:
print('oops')
'oops'
is printed as expected. What makes this different than the code inside the function that didn't work? It ultimately does the same thing by calling fun3
and checking for the ZeroDivisionError
. When the nested loops eventually reach the value (0, 0), If the ZeroDivisionError
does not appear, how can I handle the RuntimeWarning
?