plotly - 在 Jupyter 和导出的 PDF 或 PNG 中绘制不同的 LaTeX 字体
问题描述
我正在尝试创建我在 jupyter lab 中用 plotly 完成的绘图的 PDF,但是我在字体方面遇到了很多麻烦。Plotly 为浏览器中的所有普通文本使用正确的字体,但所有 LaTeX 代码标签都使用不同的字体。这是意料之中的,因为 plotly 使用 MathJax 进行渲染,而且显然它被配置为使用STIX
. STIX
如果它与导出的图形一致,我可以接受并将非 LaTeX 字体更改为。真正困扰我的是,当我将绘图导出为 PDF 时,LaTeX 标签使用了另一种字体。出于某种原因,MathJax 然后默认为MathJax_Main
. 如果导出为 PNG 或 PDF,为了完全混淆,正常字体默认为Liberation Serif
.
所以,这里有一些创建绘图的示例代码。我在 Debian 11 和 python 3.9 上运行它。requirements.txt
如果有任何用处,我可以添加完整的。
import plotly.graph_objects as go
from plotly.express.colors import qualitative
layout = go.Layout(
font=dict(
family='Latin Modern Math',
color='black',
size=20,
),
colorway=qualitative.D3,
width=600,
height=320,
margin=dict(l=10,r=10,t=10,b=10),
paper_bgcolor='rgba(255,255,255,1)',
plot_bgcolor='rgba(0,0,0,0)',
xaxis=dict(
showline=True,
linecolor='black',
ticks='inside',
exponentformat='e',
mirror='ticks',
),
yaxis=dict(
showline=True,
linecolor='black',
ticks='inside',
exponentformat='e',
mirror='ticks',
),
legend=dict(
xanchor="left",
yanchor="bottom",
x=0.1,
y=1.01,
),
)
fig = go.Figure(layout=layout)
X = np.linspace(0, 2 * np.pi, 100)
Y1 = np.sin(X)
Y2 = np.cos(X)
fig.add_trace(go.Scatter(x=X, y=Y1, name=r'$\text{The quick brown fox jumps over the lazy dog}$'))
fig.add_trace(go.Scatter(x=X, y=Y2, name='The quick brown fox jumps over the lazy dog'))
fig.show()
浏览器输出
LaTeX:STIX
普通:拉丁现代数学
PDF 导出
乳胶:MathJax_Main
普通:解放衬线
PNG 导出
乳胶:MathJax_Main
普通:解放衬线
我想问题的根源是无论在后台导出什么(可能是 Kaleido)和/或 MathJax 都找不到正确的字体或使用不同的配置。但我不知道该配置在哪里或它应该是什么样子。
编辑 1
我查看了 plotly 和 kaleido 的源代码。看起来 kaleido 附带了自己的 mathjax,所以这可能是问题所在。如果我理解正确,请将图形交给 Kaleido(https://github.com/plotly/plotly.py/blob/24cda54b22b7c541a30fd6a080e4ccf5a0684106/packages/python/plotly/plotly/io/_kaleido.py#L145),它实现一个PlotlyScope
。Kaleido 然后调用_perform_transform
(https://github.com/plotly/Kaleido/blob/6a46ecae926b4c004bf7232383cf7c74c70748fd/repos/kaleido/py/kaleido/scopes/plotly.py#L153),这会创建一个 JSON 转储并将其传送到某个子进程,这返回最终图像。你可以看到PlotlyScope
有一个成员mathjax
在我的例子中指向$HOME/venvs/jupyter/lib/python3.9/site-packages/kaleido/executable/etc/mathjax/MathJax.js
. 在这条链中,我看不到任何字体规范都被改变了。所以我假设子进程(Kaleido 正在运行)接收到正确的字体规范,但随后默认为任何内容,因为它找不到字体。不幸的是,发生这种情况时不会打印任何错误。
解决方案
推荐阅读
- java - Java - 如何从套接字附加到 jTextArea?
- html - 带有文本和点的进度条
- ios - iOS 11.4(15g77) 的设备支持文件
- java - Jsoup 去除字符串中的多个空格
- visual-studio-code - 使用 vscode 进行远程调试,console.log 有效,但 stdout 被抑制
- configuration - GitLab:从作业脚本影响作业配置
- python - 为什么赋值给None提示未定义变量
- reactjs - ReactJs Collapse 打开后关闭
- python-3.x - 打开时出现奇怪的语法错误
- pascal - Pascal(免费或 Turbo)读取