定义贝塞尔函数:
可以使用scipy.special.jn()
函数,其中需要计算整数阶贝塞尔函数 Jn 的零点,可以使用函数 scipy.special.jn_zeros(n, nt)
import numpy as np
from scipy.special import jn, jn_zeros
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Songti SC'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rc("xtick", labelsize="small")
plt.rc("ytick", labelsize="small")
fig = plt.figure(figsize=(8, 4), dpi=100)
ax = plt.subplot(xlim=[0, 20], ylim=[-0.5, 1])
i = 0
X = np.linspace(0, 20, 1000, endpoint=True)
Ji = jn(i, X)
# 配置图表样式参数
linewidth = 1.5 if i == 0 else 1
linestyle = "-" if i == 0 else "-"
color = "C1" if i == 0 else "%.2f" % (i / n)
label = r"$J_%d$" % i
# 绘图
ax.plot(
X,
Ji,
color=color,
clip_on=False,
zorder=10 - i, # 图形叠放次序
linewidth=linewidth,
linestyle=linestyle,
label=label,
)
ax.legend()
k = np.argmax(Ji) # 获取曲线最大值的索引
# 在曲线最大位置上面标注
ax.text(
X[k],
Ji[k] + 0.05,
label,
color=color,
usetex=True, # 使用Latex语法
ha="center",
va="bottom",
size="small",
)
# 计算整数阶贝塞尔函数 Jn 的零点
Zx = [x for x in jn_zeros(i, 6) if x < 20]
# y 值恒等于0
Zy = np.zeros(len(Zx))
# 绘制散点图
ax.scatter(Zx, Zy, s=15,
zorder=20,
edgecolor=color,
facecolor="white",
linewidth=1)
# 箭头标注
ax.annotate(
"Root", # 标注文字
(Zx[0], Zy[0]),
size="small",
xytext=(-30, -30),
textcoords="offset points",
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=-0.3"),
)
# y 等于0 的一条线
ax.axhline(0, color="0.5", linewidth=0.5)
ax.set_title(
"Bessel functions",
x=1,
weight="light", ha="right",
family="Hiragino Sans",
transform=ax.transAxes,
)
ax.text(
1, 0.98,
r"$J_n(x) = \frac{1}{2\pi} \int_{-\pi}^\pi e^{i(x \sin \tau -n \tau)} \,d\tau$",
va="top", ha="right",
transform=ax.transAxes,
size=12, usetex=True,)
Zy = -0.6 * np.ones(len(Zx))
# 在x轴上用散点图的方式绘制出每个贝塞尔函数零点的刻度标识
ax.scatter(
Zx, Zy,
s=30, zorder=20,
clip_on=False,
marker="|",
facecolor="black",
linewidth=0.5,
)
# 设置轴刻度标签
ax.set_yticks([-0.5, 0, 0.5, 1])
ax.set_xticks([0, 10, 20])
# 隐藏上面和右边的轴线
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
# 调整左边和底部的轴线位置
ax.spines["left"].set_position(("data", -1))
ax.spines["bottom"].set_position(("data", -0.6))
因为有多条线的交叉,我们设置白色间隙,在绘制每条函数折线时,同时绘制一条位于其下方、宽度略宽于对应折线的白色折线。因此在视觉效果上更加清晰分辨二者。
ax.plot(X, Ji, color="white", clip_on=False,
zorder=10 - i, linewidth=2.5)
报错:
No such file or directory: 'latex'.
解决:
第一步:安装MiKTeX; 第二步:安装dviping(a DVI-to-PNG convert):MiKTeX中的miktex包含安装程序dviping.exe,在路径"bin/x64/dvipng.exe"下; 第三部:安装Ghostscript[1];安装完成后需要进行一些必要的软件安装和PATH环境变量的配置。
第一步:安装python模块latex:pip3 install latex 第二步:安装latex环境MacTex[2]:brew install mactex 或者直接在官网下载安装包[3]
第三步:MacTex安装成功后打开Tex Live Utility app然后将里面可更跟新的全部更新。参考文档[5]
⚠️记得,如果上述办法都试过,还不行,重新电脑!
[1]
Ghostscript: http://nicethemes.cn/news/txtlist_i101534v.html
[2]
latex环境MacTex: https://www.cnblogs.com/antiquality/p/15561627.html
[3]
官网下载安装包: https://tug.org/mactex/mactex-download.html
[4]
https://liuchengxu.blog.csdn.net/article/details/50608124
[5]
https://stackoverflow.com/questions/31214214/matplotlib-error-latex-was-not-able-to-process-the-following-string-lp
[6]
Scientific Visualisation-Python & Matplotlib