如何在Matplotlib中正确绘制含垂直渐近线的函数1/sin(x)
解决Matplotlib绘制1/sin(x)时垂直渐近线错误连线的问题
1/sin(x)的垂直渐近线是所有整数倍的π(即x = kπ,k为任意整数),sympy的solve函数仅返回主值解(0和π),无法给出所有零点,得换方式处理:
方法一:过滤接近渐近线的点
生成密集x点后,筛掉sin(x)接近0的点,避免除以0和跨渐近线连线:
import numpy as np import matplotlib.pyplot as plt # 设定绘图区间 x_start = -2 * np.pi x_end = 2 * np.pi # 生成大量x采样点 x = np.linspace(x_start, x_end, 1000) # 过滤掉sin(x)接近0的点(容差1e-6) mask = ~np.isclose(np.sin(x), 0, atol=1e-6) x_filtered = x[mask] y = 1 / np.sin(x_filtered) plt.plot(x_filtered, y) plt.ylim(-10, 10) # 限制y轴范围,避免无穷大值撑爆视图 plt.axhline(0, color='black', linewidth=0.5) plt.axvline(0, color='black', linewidth=0.5) plt.title(r'$y = 1/\sin(x)$') plt.xlabel('x') plt.ylabel('y') plt.show()
方法二:拆分区间逐个绘制
把整个绘图区间拆分成相邻渐近线之间的子区间,分别绘图,彻底避免跨渐近线连线:
import numpy as np import matplotlib.pyplot as plt # 生成指定范围内的所有渐近线位置(kπ) asymptotes = np.arange(-2, 3) * np.pi # 覆盖-2π到2π的渐近线 # 遍历每一对相邻渐近线,绘制中间区间的曲线 for i in range(len(asymptotes)-1): # 避开渐近线本身,留极小偏移量 x_sub_start = asymptotes[i] + 1e-6 x_sub_end = asymptotes[i+1] - 1e-6 x_sub = np.linspace(x_sub_start, x_sub_end, 200) y_sub = 1 / np.sin(x_sub) plt.plot(x_sub, y_sub) plt.ylim(-10, 10) plt.axhline(0, color='black', linewidth=0.5) plt.axvline(0, color='black', linewidth=0.5) plt.title(r'$y = 1/\sin(x)$') plt.xlabel('x') plt.ylabel('y') plt.show()
为什么solve无法得到所有零点?
sympy的solve函数默认求解符号方程的有限主解,不会返回无穷多的整数倍解。要获取所有零点,直接通过kπ(k为整数)的规律生成即可,无需依赖符号求解。
内容的提问来源于stack exchange,提问作者Julio Orlando Sanchez Perez
相关产品推荐
相关产品推荐

