Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术

Python 中的数学曲线可视化,尤其是显函数隐函数参数方程以及一些复杂/奇异曲线,在教学、研究和探索中非常常见。

2026 年主流的交互式方案已经非常成熟,主要分为三大路线:

路线库组合交互能力隐函数支持参数方程3D 支持学习曲线推荐场景(2026视角)
1matplotlib + ipywidgets / ipympl中等(滑块、按钮、下拉)一般(需 contour)优秀优秀(mpl_toolkits.mplot3d)低~中Jupyter 教学、快速原型
2sympy.plotting弱(基本静态)优秀(plot_implicit)优秀(plot_parametric)中等符号数学 + 快速查看
3plotly (express/graph_objects)优秀(缩放、旋转、hover、动画)中等(contour / isosurface)优秀非常优秀展示、报告、网页分享
4panel / holoviews + datashader优秀~极强(非常灵活)好(通过 holoviews)优秀中~高大数据曲线、复杂 dashboard

下面按实用程度给出代码模板 + 对比(以 Jupyter Notebook 环境为主)。

1. 最常用:matplotlib + ipywidgets(交互滑块)

%matplotlib widget          # 或 %matplotlib notebook (旧版)
# 如果用 VSCode/JupyterLab 推荐装 ipympl: pip install ipympl

import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider, IntSlider, Dropdown

# ----------------显函数 y = f(x)----------------
def plot_explicit(a=1, b=0, func='sin'):
    x = np.linspace(-5, 5, 1000)
    if func == 'sin':    y = np.sin(a*x + b)
    elif func == 'x²':   y = a*x**2 + b
    elif func == 'exp':  y = a*np.exp(x) + b
    else: y = x**3 + a*x + b

    plt.figure(figsize=(9,5))
    plt.plot(x, y, lw=2.5, color='#1f77b4')
    plt.axhline(0, color='gray', lw=0.8, alpha=0.6)
    plt.axvline(0, color='gray', lw=0.8, alpha=0.6)
    plt.grid(True, alpha=0.3)
    plt.title(f"y = {func}( {a:.2f} x + {b:.2f} )")
    plt.ylim(-10,10)
    plt.show()

interact(plot_explicit,
         a=FloatSlider(min=-5, max=5, step=0.1, value=1),
         b=FloatSlider(min=-10, max=10, step=0.5, value=0),
         func=Dropdown(options=['sin','x²','exp','cubic'], value='sin'));

2. 隐函数 F(x,y) = 0 —— 最经典三种画法

# 方法1:matplotlib contour (最常用)
def plot_implicit_contour(expr_str="x**2 + y**2 - 1", level=0):
    x = np.linspace(-5, 5, 800)
    y = np.linspace(-5, 5, 800)
    X, Y = np.meshgrid(x, y)
    try:
        Z = eval(expr_str, {"np":np, "x":X, "y":Y})
    except:
        print("表达式解析失败")
        return

    plt.figure(figsize=(8,8))
    plt.contour(X, Y, Z, levels=[level], colors='#d62728', linewidths=2.5)
    plt.axhline(0, color='k', lw=0.6); plt.axvline(0, color='k', lw=0.6)
    plt.grid(alpha=0.25)
    plt.title(f"隐函数:{expr_str} = {level}")
    plt.axis('equal')
    plt.show()

interact(plot_implicit_contour,
         expr_str=['x**2 + y**2 - 1',          # 圆
                   'x**2/4 + y**2/9 - 1',      # 椭圆
                   'y**2 - x**3 + x',          # 半立方抛物线
                   '(x**2 + y**2)**2 - x**2 + y**2',  # 心形线变体
                   'x*y - sin(x+y)'],          # 复杂超越
         level=FloatSlider(-5,5,0.1,0));
# 方法2:sympy(符号 + 隐函数最优雅)
from sympy import *
from sympy.plotting import plot_implicit

x, y = symbols('x y')

@interact
def sympy_implicit(eq = "(x**2 + y**2 - 4)*(x**2 + y**2 - 1) - 4*y**2",
                   xlim = (-5,5), ylim=(-5,5)):
    p = plot_implicit(sympify(eq), (x, xlim[0],xlim[1]), (y,ylim[0],ylim[1]),
                      adaptive=True, points=400, show=False)
    p[0].line_color = 'purple'
    p.show()

3. 参数方程(parametric)—— 交互最友好

def plot_parametric(curve='cardioid', tmin=0, tmax=2*np.pi, steps=800):
    t = np.linspace(tmin, tmax, steps)

    if curve == 'cardioid':
        r = 1 - np.cos(t); x,y = r*np.cos(t), r*np.sin(t)
    elif curve == 'astroid':
        x = np.cos(t)**3; y = np.sin(t)**3
    elif curve == 'hypocycloid':
        x = (3-1)*np.cos(t) + np.cos((3-1)*t)
        y = (3-1)*np.sin(t) - np.sin((3-1)*t)
    elif curve == 'lissajous':
        x = np.sin(3*t); y = np.sin(4*t + np.pi/2)
    else:
        x = t; y = np.sin(5*t) + 0.5*np.sin(7*t)

    plt.figure(figsize=(7,7))
    plt.plot(x, y, lw=2, color='teal')
    plt.axis('equal'); plt.grid(alpha=0.3)
    plt.title(f"参数曲线:{curve}")
    plt.show()

interact(plot_parametric,
         curve=Dropdown(['cardioid','astroid','hypocycloid','lissajous','custom']),
         tmin=FloatSlider(-10,0,0.1,-2*np.pi),
         tmax=FloatSlider(0,20,0.1,2*np.pi*2),
         steps=IntSlider(200,3000,200,800));

4. Plotly 版本(最美观、可分享到网页)

import plotly.graph_objects as go
from ipywidgets import interact

@interact(a=(-5,5,0.2), b=(-5,5,0.2))
def plotly_implicit(a=1, b=1):
    x = np.linspace(-5,5,200)
    y = np.linspace(-5,5,200)
    X,Y = np.meshgrid(x,y)
    Z = X**2/a**2 + Y**2/b**2 - 1

    fig = go.Figure(data=
        go.Contour(x=x, y=y, z=Z,
                   contours_coloring='lines',
                   line_width=2.5,
                   colorscale='RdBu',
                   showscale=False,
                   contours=dict(start=-1, end=1, size=0.1))
    )
    fig.update_layout(width=600, height=600, 
                      xaxis_range=[-5,5], yaxis_range=[-5,5],
                      title="交互隐函数:x²/a² + y²/b² = 1")
    fig.show()

推荐学习路径(2026 年)

阶段目标首选工具理由
0–3 天快速上手显/参/隐matplotlib + ipywidgets环境最稳定,教学最友好
3–10 天符号 + 复杂隐函数sympy.plotting无需手动网格,最优雅画隐函数
10+ 天美观 + 分享plotly / panel3D旋转、网页嵌入、动画都强
进阶大量点/高维holoviews + datashader避免卡顿,适合分形、混沌吸引子

你现在最想交互式探索哪类曲线?

  • 心形线 / 玫瑰线 / 蝴蝶曲线 等经典参数曲线
  • 更复杂的隐函数(如 folium、Cassini 卵形线)
  • 3D 曲面(显式 z=f(x,y) 或隐式 F(x,y,z)=0)
  • 分形 / 混沌吸引子(如 Lorenz、Henon)

告诉我你的兴趣方向,我可以给你更针对性的交互代码模板~

文章已创建 3958

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部