装饰物指定所有你可以添加到一个画布的额外元素,这样可以看美化它或使它表达更清晰。装饰物包括一些标准元素,如图例、注释、颜色条、文本等,但你也可以专门为你的画布设计自己的元素。今天云朵君和大家一起学习标准元素(注释和文本)以及特定元素(使用垂直标记在x轴上报告的根)的混合。
定义贝塞尔函数:
可以使用scipy.special.jn()
函数,其中需要计算整数阶贝塞尔函数 Jn 的零点,可以使用函数 scipy.special.jn_zeros(n, nt)
绘图前准备
代码语言:javascript复制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")
设置画布
代码语言:javascript复制fig = plt.figure(figsize=(8, 4), dpi=100)
ax = plt.subplot(xlim=[0, 20], ylim=[-0.5, 1])
绘图
代码语言:javascript复制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,
)
配置图例
使用图例函数
代码语言:javascript复制ax.legend()
使用文字注释
代码语言:javascript复制k = np.argmax(Ji) # 获取曲线最大值的索引
# 在曲线最大位置上面标注
ax.text(
X[k],
Ji[k] 0.05,
label,
color=color,
usetex=True, # 使用Latex语法
ha="center",
va="bottom",
size="small",
)
标注出函数等于零时的根
代码语言:javascript复制# 计算整数阶贝塞尔函数 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)
标注函数公式及名称
代码语言:javascript复制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}{2pi} int_{-pi}^pi e^{i(x sin tau -n tau)} ,dtau$",
va="top", ha="right",
transform=ax.transAxes,
size=12, usetex=True,)
配置坐标轴
代码语言:javascript复制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))
绘制多阶贝塞尔函数
细节处理
因为有多条线的交叉,我们设置白色间隙,在绘制每条函数折线时,同时绘制一条位于其下方、宽度略宽于对应折线的白色折线。因此在视觉效果上更加清晰分辨二者。
代码语言:javascript复制ax.plot(X, Ji, color="white", clip_on=False,
zorder=10 - i, linewidth=2.5)
绘制过程视频欣赏
附录:报错与解决
报错:
代码语言:javascript复制No such file or directory: 'latex'.
解决:
windows系统下的安装步骤:
第一步:安装MiKTeX; 第二步:安装dviping(a DVI-to-PNG convert):MiKTeX中的miktex包含安装程序dviping.exe,在路径"bin/x64/dvipng.exe"下; 第三部:安装Ghostscript[1];安装完成后需要进行一些必要的软件安装和PATH环境变量的配置。
mac系统下的安装步骤:
第一步:安装python模块latex:pip3 install latex 第二步:安装latex环境MacTex[2]:brew install mactex 或者直接在官网下载安装包[3]
- 查看是否安装成功 latex --version或者which latex
- latex的使用参考文档[4]
第三步: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