朱莉娅绘图问题:标签重叠和LaTeX字符串扩展

3

我在下面的示例图中遇到了两个互斥的问题。

  1. y轴标签和y刻度标签重叠在一起。我没有找到任何方法来移动它们,我希望图形的大小可以扩展以容纳必要的间距。
  2. 我想让y轴标签为sigma,带有下标theta。看起来Unicode不允许下标theta。我希望通过使用LaTeXStrings来解决这个限制。然而,我无法使LatexString以正确的形式展开到图表中。请注意,问题#1会在有或没有LatexString作为ylabel时发生,并且对于其他字符串值,LatexString扩展也无法工作。

下面提供了示例绘图、代码和数据,以便复现。我正在Windows上使用Juno编辑器与Plotly后端。

显示y轴问题的示例图

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
4个回答

2
我提交了一个公关请求来解决问题,它已经被合并到主分支中 :-)
所以将来你就可以做到了。
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轴数字的格式现在通过yformatter = :plain实现,y标题中的空格是通过添加一个带有白色格式化点的行来实现的。
当然,您也可以在系统的任何位置放置一个MathJax副本,并将链接放入includ_mathjax参数中。
有关用法的更多详细信息,请参阅PR。 愉快编码!

2
Latex输出在Plotly中似乎存在问题,目前已经破裂。 我了解到对于某些人来说,这取决于浏览器。我无法在Edge或Chrome上使其正常工作。
关于重叠,不幸的是,这是plotly本身的标准设置。但是,plotly和Julia软件包Plotly提供了yaxis.automargin = true参数来覆盖此设置。 如果您需要额外的空间,可以通过向标题添加非空行来实现,方法是添加html代码<br>&nbsp; 下面我提供了在Plotly中实现此目的的示例代码。(目前,Plotsplotly()后端不支持传递后端特定参数。但是有正在进行的工作来实现这一点。)
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>&nbsp;",
                              tickformat = "0",
                              automargin = true)
)

p1 = Plotly.plot(data, layout1)
p2 = Plotly.plot(data, layout2)
p3 = Plotly.plot(data, layout3)
p4 = Plotly.plot(data, layout4)

Layout 1 Layout 2 Layout 3 Layout 4


为了他人的利益,PyPlot将接受"\n"作为绘图标签中的换行符,但GR和Plotly不会。此外,在LaTeX字符串内部,"\n"也无法正常工作。 - Nathan Boyer

1

PyPlot Output

将后端切换为PyPlot立即解决了这两个问题。

将后端切换为GR解决了LaTeX的问题,但使标签重叠更加严重。

通过在脚本顶部添加using Plots.PlotMeasures并在plotplotly语句中添加left_margin=80px,我在Plotly后端上取得了一些成功。然而,结果并不是非常令人满意。边距的添加并没有影响到GR后端的标签间距。

我仍然希望找到一种直接修改图表标签定位的解决方案,因为plotly具有更好的互动性。


1

目前plotly不提供mathjax环境,但Jupyter提供。然而,默认情况下,Jupyter不安装TeX字体,这似乎是Mathjax默认字体。

为了解决这个问题,您需要将原始的mathjax分发复制到jupyter保留其静态文件的目录中。

  • 下载MathJax-2.7.7.zip
  • 将MathJax-2.7.7.zip中的jax文件夹复制到C:\Users\<username>\.julia\conda\3\Lib\site-packages\notebook\static\components\MathJax或存储在您系统上的任何其他位置。请注意,可能会有更多的MathJax文件夹,例如C:\Users\<username>\.julia\conda\3\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 in Plotly

我在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)}"
    )

LaTeX with plotly backend of Plots

为了在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接