Julia 绘图问题:标签重叠和 LaTeXStings 扩展
Julia plotting issues: label overlap and LaTeXStings expansion
我在下面的示例图中遇到了两个相互排斥的问题。
- y 轴标签和 y 刻度标签彼此重叠。我有
也没能找到转移的方法。我想要
要扩展的地块大小以适应必要的间距。
- 我希望 y 轴标签是带有下标 theta 的 sigma。看起来 Unicode 不允许下标 theta。我希望通过使用 LaTeXStrings 来绕过这个限制。但是,我无法将 LatexString 扩展为图上的适当形式。请注意,无论是否使用 LatexString 作为 ylabel,问题 #1 都会发生,并且 LatexString 扩展也不适用于其他字符串值。
下面提供了示例图、代码和数据以供重现。我在 Windows.
上使用带有 Plotly 后端的 Juno 编辑器
using Plots, DelimitedFiles, LaTeXStrings
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
data=readdlm("hoopstress.txt",skipstart=1)
r=data[:,2]
σθ=data[:,end-1:end]
plot(r,σθ,label=["Simplified Vessel" "Full Vessel"],xlabel="r",ylabel=L"\sigma_\theta")
Length Simple Full
1 0. 53280 56859
2 9.4e-2 52158 55405
3 0.1875 51036 53951
4 0.28125 49915 52498
5 0.375 48793 51044
6 0.46875 47671 49590
7 0.5625 46550 48136
8 0.65625 45428 46682
9 0.75 44307 45228
10 0.84375 43185 43774
11 0.9375 42063 42320
12 1.0312 40942 40866
13 1.125 39883 39411
14 1.2187 39256 38780
15 1.3125 38629 38150
16 1.4062 38002 37519
17 1.5 37375 36888
18 1.5938 36748 36257
19 1.6875 36121 35627
20 1.7813 35494 34996
21 1.875 34867 34365
22 1.9688 34239 33735
23 2.0625 33612 33104
24 2.1562 32985 32473
25 2.25 32389 31842
26 2.3437 31998 31441
27 2.4375 31607 31039
28 2.5312 31216 30637
29 2.625 30825 30235
30 2.7187 30434 29833
31 2.8125 30043 29431
32 2.9062 29652 29029
33 3. 29261 28628
34 3.0938 28870 28226
35 3.1875 28479 27824
36 3.2813 28088 27422
37 3.375 27714 27020
38 3.4688 27452 26693
39 3.5625 27190 26367
40 3.6563 26927 26040
41 3.75 26665 25714
42 3.8438 26403 25387
43 3.9375 26141 25061
44 4.0313 25879 24734
45 4.125 25617 24408
46 4.2187 25354 24081
47 4.3125 25092 23755
48 4.4062 24830 23428
49 4.5 24568 23102
切换到 PyPlot
后端立即解决了这两个问题。
切换到 GR
后端解决了 LaTeX 问题,但标签重叠变得更糟。
通过在脚本顶部添加 using Plots.PlotMeasures
并将 left_margin=80px
添加到 plot
或 plotly
,我在 Plotly
后端取得了一些成功] 声明。然而,结果并不尽如人意。添加边距不会影响 GR
后端的标签间距。
还是想找个直接修改plot label定位的方案,因为plotly交互性更好
Latex 输出似乎是 currently broken in Plotly。
我读到,对于某些人来说,这取决于浏览器。我无法让它在 Edge 和 Chrome.
上运行
不幸的是,关于重叠,它是 plotly 本身的标准设置。然而,plotly 和 Julia 包 Plotly
提供了 yaxis.automargin = true
参数来覆盖这个设置。
如果您想要额外的 space,您可以通过在标题中添加 non-empty 行来实现,这是通过添加 html 代码 <br>
来实现的
下面我在 Plotly
中提供了实现此目的的示例代码。 (目前,Plots
的plotly()
后端不支持传递backend-specific参数。但是有work going on可以实现。)
using Plotly
trace1 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [1, 4, 9, 16] .* 1000000,
"name" => L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
trace2 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [0.5, 2, 4.5, 8] .* 1000000,
"name" => L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
data = [trace1, trace2]
# standard layout (shortens numbers by SI prefix)
layout1 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}")
)
# sets the number format to "0", i.e. without prefixing
layout2 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}",
tickformat = "0")
)
# forces automargin
layout3 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}",
tickformat = "0",
automargin = true)
)
# adds an additional space by adding a line to the title
# note that Plotly seems to accept html code ...
layout4 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}<br> ",
tickformat = "0",
automargin = true)
)
p1 = Plotly.plot(data, layout1)
p2 = Plotly.plot(data, layout2)
p3 = Plotly.plot(data, layout3)
p4 = Plotly.plot(data, layout4)
目前plotly不提供mathjax环境,但Jupyter提供。然而,默认情况下,Jupyter 不安装 TeX 字体,现在似乎是 Mathjax 默认字体。
为了解决这个问题,您必须将原始的 mathjax 分发复制到 jupyter 保存其静态文件的目录。
- 下载MathJax-2.7.7.zip
- 将
jax
文件夹从 MathJax-2.7.7.zip 复制到 C:\Users\<username>\.julia\conda\Lib\site-packages\notebook\static\components\MathJax
或文件存储在系统上的任何位置。请注意,可能会有更多 MathJax 文件夹,例如C:\Users\<username>\.julia\conda\pkgs\notebook-6.0.3-py36_0\Lib\site-packages\notebook\static\components\MathJax
,但只有一个是服务器的真实来源。
现在您可以使用 Plotly
using Plotly
trace1 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [1, 4, 9, 16] .* 1000000,
"name" => L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
trace2 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [0.5, 2, 4.5, 8] .* 1000000,
"name" => L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
data = [trace1, trace2]
layout = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"\sigma_\theta\?",
tickformat = "0",
automargin = true)
)
p = Plotly.plot(data, layout)
(我找不到 LaTeX 语法中换行符的快速解决方案。只有在我添加字符时才会保留换行符。也许,其他人可以在这里做出贡献;-))
或地块:
using Plots, LaTeXStrings
plotly()
Plots.plot(1:4, [[1,4,9,16], [0.5, 2, 4.5, 8]],
labels = [L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}" L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}"],
xlabel = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}",
ylabel = L"d, r \text{ (solar radius)}"
)
为了使其在 Juno 中工作,请确保安装了 Conda
包并按上述方法复制了 mathjax 字体。然后进行如下定义:
import Plots.plotly_html_head
import Conda.ROOTENV
function mathjax()
mathjaxdir = joinpath(ROOTENV, "Lib\site-packages\notebook\static\components\MathJax")
mathjaxfile = joinpath(mathjaxdir, "MathJax.js?config=TeX-AMS-MML_HTMLorMML-full")
return """<script type="text/javascript" src="file://$mathjaxfile"></script>"""
end
function plotly_html_head(plt::Plots.Plot)
local_file = ("file://" * Plots.plotly_local_file_path)
plotly = Plots.use_local_dependencies[] ? Plots.local_file : Plots.plotly_remote_file_path
if Plots.isijulia() && !Plots.ijulia_initialized[]
# using requirejs seems to be key to load a js depency in IJulia!
# https://requirejs.org/docs/start.html
# https://github.com/JuliaLang/IJulia.jl/issues/345
display("text/html", """
<script type="text/javascript">
requirejs([$(repr(plotly))], function(p) {
window.Plotly = p
});
</script>
""")
ijulia_initialized[] = true
end
return """$(mathjax())
<script src=$(repr(plotly))></script>"""
end
我提交了一个PR来解决这个问题,刚刚合并到master :-)
所以以后你可以做到
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
r = 1:10
σθ = [100000 ./ (1:10) .+ 10000, 100000 ./ (1:10) .- 1000 .+ 10000]
plot(r , σθ, label=["Simplified Vessel" "Full Vessel"],
xlabel = "r",
ylabel = L"\sigma_\theta\\color{white}.",
yformatter = :plain,
include_mathjax = "cdn",
extra_kwargs = :plot)
如果您已连接到互联网。
对于本地使用,如果安装了 Conda 和 IJulia,并且按照我之前的回答中的描述复制了 TeX 字体,您可以执行以下操作。
import Conda.ROOTENV
function local_mathjax()
joinpath(ROOTENV, "Lib", "site-packages", "notebook", "static", "components", "MathJax",
"MathJax.js?config=TeX-AMS-MML_HTMLorMML-full")
end
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
r = 1:10
σθ = [100000 ./ (1:10) .+ 10000, 100000 ./ (1:10) .- 1000 .+ 10000]
plot(r , σθ, label=["Simplified Vessel" "Full Vessel"],
xlabel = "r",
ylabel = L"\sigma_\theta\\color{white}.",
yformatter = :plain,
include_mathjax = local_mathjax(),
extra_kwargs = :plot)
y-axis 数字的格式现在通过 yformatter = :plain
实现,y-title 中的 space 是通过添加带有 white-formatted 的行实现的点.
当然,您也可以在系统的任何位置放置一个 mathjax 副本,并将 link 放在 includ_mathjax
参数中。
可以在 PR 中找到有关用法的更多详细信息。
编码愉快!
我在下面的示例图中遇到了两个相互排斥的问题。
- y 轴标签和 y 刻度标签彼此重叠。我有 也没能找到转移的方法。我想要 要扩展的地块大小以适应必要的间距。
- 我希望 y 轴标签是带有下标 theta 的 sigma。看起来 Unicode 不允许下标 theta。我希望通过使用 LaTeXStrings 来绕过这个限制。但是,我无法将 LatexString 扩展为图上的适当形式。请注意,无论是否使用 LatexString 作为 ylabel,问题 #1 都会发生,并且 LatexString 扩展也不适用于其他字符串值。
下面提供了示例图、代码和数据以供重现。我在 Windows.
上使用带有 Plotly 后端的 Juno 编辑器using Plots, DelimitedFiles, LaTeXStrings
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
data=readdlm("hoopstress.txt",skipstart=1)
r=data[:,2]
σθ=data[:,end-1:end]
plot(r,σθ,label=["Simplified Vessel" "Full Vessel"],xlabel="r",ylabel=L"\sigma_\theta")
Length Simple Full
1 0. 53280 56859
2 9.4e-2 52158 55405
3 0.1875 51036 53951
4 0.28125 49915 52498
5 0.375 48793 51044
6 0.46875 47671 49590
7 0.5625 46550 48136
8 0.65625 45428 46682
9 0.75 44307 45228
10 0.84375 43185 43774
11 0.9375 42063 42320
12 1.0312 40942 40866
13 1.125 39883 39411
14 1.2187 39256 38780
15 1.3125 38629 38150
16 1.4062 38002 37519
17 1.5 37375 36888
18 1.5938 36748 36257
19 1.6875 36121 35627
20 1.7813 35494 34996
21 1.875 34867 34365
22 1.9688 34239 33735
23 2.0625 33612 33104
24 2.1562 32985 32473
25 2.25 32389 31842
26 2.3437 31998 31441
27 2.4375 31607 31039
28 2.5312 31216 30637
29 2.625 30825 30235
30 2.7187 30434 29833
31 2.8125 30043 29431
32 2.9062 29652 29029
33 3. 29261 28628
34 3.0938 28870 28226
35 3.1875 28479 27824
36 3.2813 28088 27422
37 3.375 27714 27020
38 3.4688 27452 26693
39 3.5625 27190 26367
40 3.6563 26927 26040
41 3.75 26665 25714
42 3.8438 26403 25387
43 3.9375 26141 25061
44 4.0313 25879 24734
45 4.125 25617 24408
46 4.2187 25354 24081
47 4.3125 25092 23755
48 4.4062 24830 23428
49 4.5 24568 23102
切换到 PyPlot
后端立即解决了这两个问题。
切换到 GR
后端解决了 LaTeX 问题,但标签重叠变得更糟。
通过在脚本顶部添加 using Plots.PlotMeasures
并将 left_margin=80px
添加到 plot
或 plotly
,我在 Plotly
后端取得了一些成功] 声明。然而,结果并不尽如人意。添加边距不会影响 GR
后端的标签间距。
还是想找个直接修改plot label定位的方案,因为plotly交互性更好
Latex 输出似乎是 currently broken in Plotly。 我读到,对于某些人来说,这取决于浏览器。我无法让它在 Edge 和 Chrome.
上运行不幸的是,关于重叠,它是 plotly 本身的标准设置。然而,plotly 和 Julia 包 Plotly
提供了 yaxis.automargin = true
参数来覆盖这个设置。
如果您想要额外的 space,您可以通过在标题中添加 non-empty 行来实现,这是通过添加 html 代码 <br>
来实现的
下面我在 Plotly
中提供了实现此目的的示例代码。 (目前,Plots
的plotly()
后端不支持传递backend-specific参数。但是有work going on可以实现。)
using Plotly
trace1 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [1, 4, 9, 16] .* 1000000,
"name" => L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
trace2 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [0.5, 2, 4.5, 8] .* 1000000,
"name" => L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
data = [trace1, trace2]
# standard layout (shortens numbers by SI prefix)
layout1 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}")
)
# sets the number format to "0", i.e. without prefixing
layout2 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}",
tickformat = "0")
)
# forces automargin
layout3 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}",
tickformat = "0",
automargin = true)
)
# adds an additional space by adding a line to the title
# note that Plotly seems to accept html code ...
layout4 = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"$d, r \text{ (solar radius)}<br> ",
tickformat = "0",
automargin = true)
)
p1 = Plotly.plot(data, layout1)
p2 = Plotly.plot(data, layout2)
p3 = Plotly.plot(data, layout3)
p4 = Plotly.plot(data, layout4)
目前plotly不提供mathjax环境,但Jupyter提供。然而,默认情况下,Jupyter 不安装 TeX 字体,现在似乎是 Mathjax 默认字体。
为了解决这个问题,您必须将原始的 mathjax 分发复制到 jupyter 保存其静态文件的目录。
- 下载MathJax-2.7.7.zip
- 将
jax
文件夹从 MathJax-2.7.7.zip 复制到C:\Users\<username>\.julia\conda\Lib\site-packages\notebook\static\components\MathJax
或文件存储在系统上的任何位置。请注意,可能会有更多 MathJax 文件夹,例如C:\Users\<username>\.julia\conda\pkgs\notebook-6.0.3-py36_0\Lib\site-packages\notebook\static\components\MathJax
,但只有一个是服务器的真实来源。
现在您可以使用 Plotly
using Plotly
trace1 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [1, 4, 9, 16] .* 1000000,
"name" => L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
trace2 = Plotly.scatter(Dict(
"x" => [1, 2, 3, 4],
"y" => [0.5, 2, 4.5, 8] .* 1000000,
"name" => L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}",
"type" => "scatter")
)
data = [trace1, trace2]
layout = Layout(xaxis = attr(title = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}"),
yaxis = attr(title = L"\sigma_\theta\?",
tickformat = "0",
automargin = true)
)
p = Plotly.plot(data, layout)
(我找不到 LaTeX 语法中换行符的快速解决方案。只有在我添加字符时才会保留换行符。也许,其他人可以在这里做出贡献;-))
或地块:
using Plots, LaTeXStrings
plotly()
Plots.plot(1:4, [[1,4,9,16], [0.5, 2, 4.5, 8]],
labels = [L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}" L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}"],
xlabel = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}",
ylabel = L"d, r \text{ (solar radius)}"
)
为了使其在 Juno 中工作,请确保安装了 Conda
包并按上述方法复制了 mathjax 字体。然后进行如下定义:
import Plots.plotly_html_head
import Conda.ROOTENV
function mathjax()
mathjaxdir = joinpath(ROOTENV, "Lib\site-packages\notebook\static\components\MathJax")
mathjaxfile = joinpath(mathjaxdir, "MathJax.js?config=TeX-AMS-MML_HTMLorMML-full")
return """<script type="text/javascript" src="file://$mathjaxfile"></script>"""
end
function plotly_html_head(plt::Plots.Plot)
local_file = ("file://" * Plots.plotly_local_file_path)
plotly = Plots.use_local_dependencies[] ? Plots.local_file : Plots.plotly_remote_file_path
if Plots.isijulia() && !Plots.ijulia_initialized[]
# using requirejs seems to be key to load a js depency in IJulia!
# https://requirejs.org/docs/start.html
# https://github.com/JuliaLang/IJulia.jl/issues/345
display("text/html", """
<script type="text/javascript">
requirejs([$(repr(plotly))], function(p) {
window.Plotly = p
});
</script>
""")
ijulia_initialized[] = true
end
return """$(mathjax())
<script src=$(repr(plotly))></script>"""
end
我提交了一个PR来解决这个问题,刚刚合并到master :-)
所以以后你可以做到
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
r = 1:10
σθ = [100000 ./ (1:10) .+ 10000, 100000 ./ (1:10) .- 1000 .+ 10000]
plot(r , σθ, label=["Simplified Vessel" "Full Vessel"],
xlabel = "r",
ylabel = L"\sigma_\theta\\color{white}.",
yformatter = :plain,
include_mathjax = "cdn",
extra_kwargs = :plot)
如果您已连接到互联网。
对于本地使用,如果安装了 Conda 和 IJulia,并且按照我之前的回答中的描述复制了 TeX 字体,您可以执行以下操作。
import Conda.ROOTENV
function local_mathjax()
joinpath(ROOTENV, "Lib", "site-packages", "notebook", "static", "components", "MathJax",
"MathJax.js?config=TeX-AMS-MML_HTMLorMML-full")
end
plotly(linewidth=3,titlefont=18,legendfont=16,guidefont=18,tickfont=14,formatter=:plain)
r = 1:10
σθ = [100000 ./ (1:10) .+ 10000, 100000 ./ (1:10) .- 1000 .+ 10000]
plot(r , σθ, label=["Simplified Vessel" "Full Vessel"],
xlabel = "r",
ylabel = L"\sigma_\theta\\color{white}.",
yformatter = :plain,
include_mathjax = local_mathjax(),
extra_kwargs = :plot)
y-axis 数字的格式现在通过 yformatter = :plain
实现,y-title 中的 space 是通过添加带有 white-formatted 的行实现的点.
当然,您也可以在系统的任何位置放置一个 mathjax 副本,并将 link 放在 includ_mathjax
参数中。
可以在 PR 中找到有关用法的更多详细信息。 编码愉快!