首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python数学可视化:显函数、隐函数及复杂曲线的交互式绘图

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

原创
作者头像
hide
发布2025-07-01 18:06:35
发布2025-07-01 18:06:35
3720
举报
文章被收录于专栏:技术教程技术教程

下面是一个使用Python实现显函数、隐函数及复杂曲线交互式绘图的完整解决方案。这个程序利用Matplotlib和NumPy进行数学可视化,并添加了交互控件让用户探索不同类型的数学函数。

代码语言:python
复制
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, RadioButtons, Button
import matplotlib.gridspec as gridspec
from matplotlib import cm
import sympy as sp
from scipy.optimize import fsolve

# 创建图形和布局
fig = plt.figure(figsize=(14, 10))
fig.suptitle('数学函数交互式可视化', fontsize=16, fontweight='bold')

# 使用GridSpec创建复杂布局
gs = gridspec.GridSpec(3, 3, height_ratios=[1, 0.1, 0.1], width_ratios=[1, 0.03, 0.2])
ax = plt.subplot(gs[0, 0])
ax_param = plt.subplot(gs[2, 0])
ax_radio = plt.subplot(gs[0, 2])
ax_color = plt.subplot(gs[0, 1])
ax_reset = plt.subplot(gs[2, 2])

# 设置坐标轴
ax.set_xlim(-5, 5)
ax.set_ylim(-5, 5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.grid(True, linestyle='--', alpha=0.7)
ax.set_aspect('equal', adjustable='box')
ax.set_facecolor('#f0f0f0')

# 初始函数参数
initial_params = {
    'amplitude': 1.0,
    'frequency': 1.0,
    'phase': 0.0,
    'a': 1.0,
    'b': 1.0,
    'c': 0.5,
    'n': 3,
    'density': 100,
    'color': 'blue'
}

# 定义函数类型
function_types = ['显函数', '隐函数', '参数方程', '极坐标', '3D曲面']
current_function = function_types[0]

# 显函数示例
def explicit_function(x, params):
    a = params['amplitude']
    f = params['frequency']
    p = params['phase']
    return a * np.sin(f * x + p)

# 隐函数示例 (椭圆)
def implicit_function(x, y, params):
    a = params['a']
    b = params['b']
    return (x/a)**2 + (y/b)**2 - 1

# 参数方程示例 (圆)
def parametric_function(t, params):
    a = params['a']
    b = params['b']
    return a * np.cos(t), b * np.sin(t)

# 极坐标函数示例 (玫瑰线)
def polar_function(theta, params):
    n = params['n']
    return np.cos(n * theta)

# 3D函数示例 (双曲面)
def three_d_function(x, y, params):
    a = params['a']
    b = params['b']
    c = params['c']
    return (x**2/a**2) + (y**2/b**2) - (c**2)

# 绘制函数
def plot_function(params, func_type):
    ax.clear()
    ax.set_xlim(-5, 5)
    ax.set_ylim(-5, 5)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.grid(True, linestyle='--', alpha=0.7)
    ax.set_aspect('equal', adjustable='box')
    ax.set_facecolor('#f0f0f0')
    
    color = params['color']
    density = int(params['density'])
    
    if func_type == '显函数':
        x = np.linspace(-5, 5, 1000)
        y = explicit_function(x, params)
        ax.plot(x, y, color=color, linewidth=2)
        ax.set_title(f'显函数: y = {params["amplitude"]:.1f}·sin({params["frequency"]:.1f}x + {params["phase"]:.1f})')
    
    elif func_type == '隐函数':
        x = np.linspace(-5, 5, density)
        y = np.linspace(-5, 5, density)
        X, Y = np.meshgrid(x, y)
        Z = implicit_function(X, Y, params)
        contour = ax.contour(X, Y, Z, [0], colors=color, linewidths=2)
        ax.set_title(f'隐函数: (x/{params["a"]:.1f})² + (y/{params["b"]:.1f})² = 1')
    
    elif func_type == '参数方程':
        t = np.linspace(0, 2*np.pi, density)
        x, y = parametric_function(t, params)
        ax.plot(x, y, color=color, linewidth=2)
        ax.set_title(f'参数方程: x = {params["a"]:.1f}·cos(t), y = {params["b"]:.1f}·sin(t)')
    
    elif func_type == '极坐标':
        theta = np.linspace(0, 2*np.pi, density)
        r = polar_function(theta, params)
        x = r * np.cos(theta)
        y = r * np.sin(theta)
        ax.plot(x, y, color=color, linewidth=2)
        ax.set_title(f'极坐标: r = cos({params["n"]}θ)')
    
    elif func_type == '3D曲面':
        # 为3D图创建新的坐标轴
        ax.remove()
        ax_3d = fig.add_subplot(gs[0, 0], projection='3d')
        
        x = np.linspace(-5, 5, density)
        y = np.linspace(-5, 5, density)
        X, Y = np.meshgrid(x, y)
        Z = three_d_function(X, Y, params)
        
        # 创建3D曲面图
        surface = ax_3d.plot_surface(X, Y, Z, cmap=cm.viridis, 
                                    rstride=1, cstride=1, alpha=0.8, 
                                    edgecolor='none', antialiased=True)
        
        # 添加等高线
        ax_3d.contour(X, Y, Z, 10, zdir='z', offset=-5, cmap=cm.viridis, alpha=0.5)
        
        ax_3d.set_xlim(-5, 5)
        ax_3d.set_ylim(-5, 5)
        ax_3d.set_zlim(-5, 5)
        ax_3d.set_xlabel('X')
        ax_3d.set_ylabel('Y')
        ax_3d.set_zlabel('Z')
        ax_3d.set_title(f'3D曲面: (x²/{params["a"]:.1f}²) + (y²/{params["b"]:.1f}²) - {params["c"]:.1f}² = 0')
        ax_3d.grid(True, linestyle='--', alpha=0.7)
        fig.colorbar(surface, ax=ax_3d, shrink=0.5, aspect=10)
        
        return ax_3d
    
    return ax

# 创建滑块
slider_amp = Slider(ax=plt.axes([0.1, 0.05, 0.3, 0.03]), label='振幅', valmin=0.1, valmax=3.0, valinit=initial_params['amplitude'])
slider_freq = Slider(ax=plt.axes([0.1, 0.01, 0.3, 0.03]), label='频率', valmin=0.1, valmax=5.0, valinit=initial_params['frequency'])
slider_phase = Slider(ax=plt.axes([0.5, 0.05, 0.3, 0.03]), label='相位', valmin=-np.pi, valmax=np.pi, valinit=initial_params['phase'])
slider_a = Slider(ax=plt.axes([0.5, 0.01, 0.3, 0.03]), label='参数 a', valmin=0.1, valmax=3.0, valinit=initial_params['a'])
slider_b = Slider(ax=plt.axes([0.1, 0.05, 0.3, 0.03]), label='参数 b', valmin=0.1, valmax=3.0, valinit=initial_params['b'])
slider_c = Slider(ax=plt.axes([0.1, 0.01, 0.3, 0.03]), label='参数 c', valmin=0.1, valmax=3.0, valinit=initial_params['c'])
slider_n = Slider(ax=plt.axes([0.5, 0.05, 0.3, 0.03]), label='参数 n', valmin=1, valmax=10, valinit=initial_params['n'], valstep=1)
slider_density = Slider(ax=plt.axes([0.5, 0.01, 0.3, 0.03]), label='密度', valmin=20, valmax=500, valinit=initial_params['density'], valstep=10)

# 创建颜色选择滑块
ax_color = plt.axes([0.92, 0.25, 0.03, 0.5])
slider_color = Slider(ax=ax_color, label='颜色', valmin=0, valmax=1, valinit=0, 
                     orientation='vertical', color='#ff0000')

# 创建单选按钮
radio = RadioButtons(ax_radio, function_types, active=0)

# 重置按钮
reset_button = Button(ax_reset, '重置参数')

# 初始绘图
plot_function(initial_params, current_function)

# 更新函数
def update(val):
    params = {
        'amplitude': slider_amp.val,
        'frequency': slider_freq.val,
        'phase': slider_phase.val,
        'a': slider_a.val,
        'b': slider_b.val,
        'c': slider_c.val,
        'n': slider_n.val,
        'density': slider_density.val,
        'color': plt.cm.hsv(slider_color.val)
    }
    
    # 根据颜色滑块值设置颜色
    slider_color.ax.set_facecolor(plt.cm.hsv(slider_color.val))
    
    # 根据当前函数类型更新显示
    if current_function == '显函数':
        slider_amp.ax.set_visible(True)
        slider_freq.ax.set_visible(True)
        slider_phase.ax.set_visible(True)
        slider_a.ax.set_visible(False)
        slider_b.ax.set_visible(False)
        slider_c.ax.set_visible(False)
        slider_n.ax.set_visible(False)
    elif current_function == '隐函数':
        slider_amp.ax.set_visible(False)
        slider_freq.ax.set_visible(False)
        slider_phase.ax.set_visible(False)
        slider_a.ax.set_visible(True)
        slider_b.ax.set_visible(True)
        slider_c.ax.set_visible(False)
        slider_n.ax.set_visible(False)
    elif current_function == '参数方程':
        slider_amp.ax.set_visible(False)
        slider_freq.ax.set_visible(False)
        slider_phase.ax.set_visible(False)
        slider_a.ax.set_visible(True)
        slider_b.ax.set_visible(True)
        slider_c.ax.set_visible(False)
        slider_n.ax.set_visible(False)
    elif current_function == '极坐标':
        slider_amp.ax.set_visible(False)
        slider_freq.ax.set_visible(False)
        slider_phase.ax.set_visible(False)
        slider_a.ax.set_visible(False)
        slider_b.ax.set_visible(False)
        slider_c.ax.set_visible(False)
        slider_n.ax.set_visible(True)
    elif current_function == '3D曲面':
        slider_amp.ax.set_visible(False)
        slider_freq.ax.set_visible(False)
        slider_phase.ax.set_visible(False)
        slider_a.ax.set_visible(True)
        slider_b.ax.set_visible(True)
        slider_c.ax.set_visible(True)
        slider_n.ax.set_visible(False)
    
    plot_function(params, current_function)
    fig.canvas.draw_idle()

# 函数类型选择
def select_function(label):
    global current_function
    current_function = label
    update(None)

# 重置函数
def reset(event):
    slider_amp.reset()
    slider_freq.reset()
    slider_phase.reset()
    slider_a.reset()
    slider_b.reset()
    slider_c.reset()
    slider_n.reset()
    slider_density.reset()
    slider_color.reset()

# 连接事件
slider_amp.on_changed(update)
slider_freq.on_changed(update)
slider_phase.on_changed(update)
slider_a.on_changed(update)
slider_b.on_changed(update)
slider_c.on_changed(update)
slider_n.on_changed(update)
slider_density.on_changed(update)
slider_color.on_changed(update)
radio.on_clicked(select_function)
reset_button.on_clicked(reset)

# 初始更新
update(None)

plt.tight_layout(rect=[0, 0.1, 0.95, 0.95])
plt.subplots_adjust(bottom=0.15)
plt.show()

功能说明

这个交互式数学可视化工具提供以下功能:

  1. 多种函数类型支持
    • 显函数(如正弦函数)
    • 隐函数(如椭圆方程)
    • 参数方程(如圆的参数方程)
    • 极坐标函数(如玫瑰线)
    • 3D曲面(如双曲面)
  2. 交互控件
    • 参数滑块:调整函数的不同参数
    • 函数类型选择:通过单选按钮切换不同函数类型
    • 颜色选择器:改变函数曲线的颜色
    • 密度控制:调整曲线绘制的精细度
    • 重置按钮:恢复所有参数到初始值
  3. 可视化效果
    • 高质量的函数曲线绘制
    • 自适应坐标轴
    • 网格和背景美化
    • 3D曲面带等高线投影
    • 实时函数表达式显示

使用说明

  1. 在左上角选择要可视化的函数类型
  2. 使用底部滑块调整函数参数
  3. 使用右侧垂直滑块改变曲线颜色
  4. 调整"密度"滑块改变曲线精细度(特别对隐函数和参数方程重要)
  5. 点击"重置参数"按钮恢复默认设置

这个程序展示了Python在数学可视化方面的强大能力,结合了Matplotlib的绘图功能和交互控件,为探索数学函数提供了直观的界面。

要运行此程序,您需要安装以下Python库:

代码语言:txt
复制
<<text>>

numpy matplotlib scipy sympy

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 功能说明
  • 使用说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档