求解决:计算展示函数梯度向量时plt.quiver()报isinfinite错误
isinfinite Error in plt.quiver() for Gradient Vector Fields Hey there! Let's dig into why your gradient vector field code is throwing that infinite value error and get it working smoothly. The core issue here is exactly what you suspected: you're mixing SymPy symbolic variables with NumPy numerical arrays without converting between them, which plt.quiver() can't handle properly.
The Root Cause
When you calculate gradi and gradj in get_grad(), you're creating SymPy symbolic expressions (like 2*x and 2*y for your z_func(x,y) = x² + y²). But when you pass these raw symbolic expressions directly to plt.quiver() in show_vector(), Matplotlib has no idea how to interpret them as numerical values—it sees symbols, not numbers, leading to the infinite value error.
The Fix: Convert SymPy Expressions to NumPy-Compatible Functions
We need to turn those SymPy symbolic gradients into functions that can take NumPy arrays (from meshgrid) and spit out numerical gradient values. SymPy's lambdify() method does exactly this. Here's how to adjust your code:
Step 1: Add Missing Imports (if you haven't already)
First, make sure you've imported all required libraries at the top of your script:
import numpy as np import sympy as sy import matplotlib.pyplot as plt
Step 2: Rewrite the show_vector Function
Update this function to convert symbolic gradients to numerical arrays before passing to plt.quiver():
def show_vector(gradi, gradj): # Use distinct names for symbolic variables vs. numerical arrays to avoid confusion x_sym, y_sym = sy.symbols('x y') # Convert symbolic gradient expressions to NumPy-compatible functions u_func = sy.lambdify((x_sym, y_sym), gradi, 'numpy') v_func = sy.lambdify((x_sym, y_sym), gradj, 'numpy') # Create numerical grid for vector field x, y = np.meshgrid(np.linspace(-10, 10, 10), np.linspace(-10, 10, 10)) # Calculate numerical gradient values u = u_func(x, y) v = v_func(x, y) # Plot the vector field figv = plt.figure(1) plt.xlabel('X') plt.ylabel('Y') plt.quiver(x, y, u, v) plt.title('Gradient Vector Field', fontweight='bold', fontsize=14)
Step 3: Verify and Clean Up Other Functions
Your core surface plot logic is solid—here's the full cleaned-up code for context:
def z_func(x,y): return (x**2 + y**2) def show_graph(): x,y = np.meshgrid(np.linspace(-15,15,20), np.linspace(-15,15,20)) z = z_func(x,y) fig = plt.figure(2) ax = fig.gca(projection='3d') surf = ax.plot_surface(x,y,z,rstride=1,cstride=1, cmap='viridis') ax.set_xlabel('X', fontweight='bold', fontsize=14) ax.set_ylabel('Y', fontweight='bold', fontsize=14) ax.set_zlabel('Z', fontweight='bold', fontsize=14) plt.title('3D Surface of z = x² + y²', fontweight='bold', fontsize=16) def get_grad(): x, y = sy.symbols('x y') f = z_func(x,y) gradi = sy.diff(f,x) gradj = sy.diff(f,y) show_vector(gradi,gradj) def lazy(): get_grad() show_graph() plt.show() lazy()
Key Changes Explained
sy.lambdify(): This function takes your SymPy expression and turns it into a Python function that can accept NumPy arrays as inputs. The'numpy'argument tells it to use NumPy operations for calculations (likenp.multiplyinstead of SymPy's symbolic multiplication).- Variable Name Clarity: We renamed symbolic variables to
x_sym/y_symto avoid mixing them up with the NumPy arraysx/y—this prevents accidental overwriting and makes the code easier to read. - Numerical Gradient Calculation: Now
uandvare actual NumPy arrays of gradient values, whichplt.quiver()can properly render without infinite value errors.
Run the corrected code, and you'll see both the 3D surface plot and its gradient vector field working as expected!
内容的提问来源于stack exchange,提问作者Koby Robles

