如何用滑块动态查看SymPy中参数q变化时的不等式区域变化
动态绘制不等式区域的实现方案
以下提供两种实用方案,分别基于Matplotlib(适合Jupyter环境)和Plotly(适合网页交互),均可通过滑块动态调整参数q并实时更新(u,c)的可行域。
方案一:Matplotlib + ipywidgets(Jupyter Notebook/Lab 适用)
该方案依赖ipywidgets库,在交互式笔记本中可以快速实现滑块控制,代码结构简洁易修改。
示例代码
import numpy as np import matplotlib.pyplot as plt from ipywidgets import interact, FloatSlider # 定义绘图函数,参数q为滑块传入的实时值 def plot_feasible_region(q=0.5): # 生成u和c的网格数据,范围(0,1) u = np.linspace(0, 1, 200) c = np.linspace(0, 1, 200) U, C = np.meshgrid(u, c) # -------------------------- # 替换为你的多组不等式条件 # 示例:u > q*c, c < 1-u, 且u,c∈(0,1) feasible_mask = (U > q * C) & (C < 1 - U) & (U > 0) & (U < 1) & (C > 0) & (C < 1) # -------------------------- # 绘制可行域 plt.figure(figsize=(6,6)) plt.imshow(feasible_mask.astype(int), extent=(0,1,0,1), origin='lower', cmap='Blues', alpha=0.5) plt.xlabel('u') plt.ylabel('c') plt.title(f'Feasible Region (q = {q:.2f})') plt.grid(True, alpha=0.3) plt.show() # 创建滑块控件,q的范围(0.01, 0.99),步长0.01 interact(plot_feasible_region, q=FloatSlider(min=0.01, max=0.99, step=0.01, value=0.5, description='q:'))
适配SymPy不等式
如果你的原始不等式是用SymPy定义的,可以通过lambdify将符号表达式转换为数值计算函数,示例如下:
from sympy import symbols, lambdify # 定义符号变量 u_sym, c_sym, q_sym = symbols('u c q') # 定义SymPy不等式(替换为你的实际不等式) sym_expr1 = u_sym > q_sym * c_sym sym_expr2 = c_sym < 1 - u_sym # 转换为可计算的lambda函数 calc_expr1 = lambdify((u_sym, c_sym, q_sym), sym_expr1) calc_expr2 = lambdify((u_sym, c_sym, q_sym), sym_expr2) # 在绘图函数中使用 feasible_mask = calc_expr1(U, C, q) & calc_expr2(U, C, q) & (U > 0) & (U < 1) & (C > 0) & (C < 1)
方案二:Plotly(支持网页交互)
Plotly自带交互式组件,无需额外依赖,生成的图表可直接在网页中分享,交互体验更流畅。
示例代码
import plotly.graph_objects as go import numpy as np # 生成u和c的网格数据 u = np.linspace(0, 1, 200) c = np.linspace(0, 1, 200) U, C = np.meshgrid(u, c) # 定义初始q值和可行域掩码(替换为你的不等式) q_initial = 0.5 feasible_mask = (U > q_initial * C) & (C < 1 - U) & (U > 0) & (U < 1) & (C > 0) & (C < 1) # 创建热力图绘制可行域 fig = go.Figure(data=go.Heatmap( z=feasible_mask.astype(int), x=u, y=c, colorscale=['white', 'royalblue'], showscale=False, hoverinfo='none' )) # 添加滑块控件,动态更新q值 fig.update_layout( sliders=[{ 'active': int((q_initial - 0.01)/0.01), 'currentvalue': {'prefix': '当前q值: '}, 'pad': {'t': 60}, 'steps': [{ 'label': f'{q:.2f}', 'method': 'update', 'args': [{'z': [(U > q * C) & (C < 1 - U) & (U >0) & (U<1) & (C>0) & (C<1)]}] } for q in np.linspace(0.01, 0.99, 99)] }], xaxis_title='u', yaxis_title='c', title='动态调整q的可行域', width=600, height=600 ) # 显示交互式图表 fig.show()
关键说明
- 两种方案中,核心是替换可行域的掩码计算逻辑,将示例中的不等式替换为你实际需要满足的多组不等式即可。
- 若使用SymPy,务必通过
lambdify完成符号表达式到数值函数的转换,确保能在网格数据上批量计算。
内容的提问来源于stack exchange,提问作者djsteve
相关产品推荐
相关产品推荐

