下面是一个使用Python实现显函数、隐函数及复杂曲线交互式绘图的完整解决方案。这个程序利用Matplotlib和NumPy进行数学可视化,并添加了交互控件让用户探索不同类型的数学函数。
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()
这个交互式数学可视化工具提供以下功能:
这个程序展示了Python在数学可视化方面的强大能力,结合了Matplotlib的绘图功能和交互控件,为探索数学函数提供了直观的界面。
要运行此程序,您需要安装以下Python库:
<<text>>
numpy matplotlib scipy sympy
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。