Plots + PlotlyJS + LaTeX

I love PlotlyJS interactivity mainly in Jupyter notebook or VS Code Plot pane, on the other hand, I had always problems with latex in labels.

Recently, I noticed that in one of my julia environment (Julia 1.3.1, jupyter 2.0.0, plotly extension) the LaTeX rendering in Jupyter notebook just works

using Plots, LaTeXStrings

font = Plots.font("arial", 12)

plotlyjs(guidefont=font, xtickfont=font, 
   ytickfont=font, legendfont=font, lw = 2, size=(600,400));

p = plot(rand(10))
p = xlabel!("\$\\alpha \\, F_\\mathrm{test}\$")
p = ylabel!(L"\Gamma^2")





gave errors IOError(Base.IOError("connect: connection refused (ECONNREFUSED)", -111) during request(http://localhost:7982)) and empty file.

I can save it only as an HTML, but in the web browser, the LaTeX formulas were not rendered. The same ouput I got in VS Code plot pane.

I followed the plotly.js readme and now I have plotly figure with correct LaTeX rendering.

Original HTML HEAD was

        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <script src=""></script>


The new HTML HEAD is

         <meta http-equiv="content-type" content="text/html; charset=UTF-8">
         <script src="mathjax/MathJax.js?config=TeX-AMS-MML_SVG"></script>
            window.PlotlyConfig = {MathJaxConfig: 'local'}
         <script src="plotly.js"></script>

Here, I downloaded plotly.js

Any chance to get it to work out of the box?


Best to open an issue at

If you are using plotly.js as well, loading MathJax before Plotly might fail to render TeX code. Loading Plotly before MathJax should work.

Auto generated HTML doc by Weave and Jupyter puts mathjax before plotly in the header. So you may work around by editing the doc manually but It would be great if users can control the ordering programatically.

According to it should be as it in my example above. The html with edited head section works fine.

Today, I found here in Plots docs that

Plotly needs to load mathjax to render LaTeX strings, therefore passing extra keywords with extra_kwargs = :plot is implemented. With that it is possible to pass a header to the extra include_mathjax keyword. It has the following options:

However, the example they provided does not work for me.

using Plots, LaTeXStrings
plot(1:4, [[1,4,9,16]*10000, [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}"] |> permutedims,
           xlabel = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}",
           ylabel = L"d, r \text{ (solar radius)}",
           yformatter = :plain,
           extra_plot_kwargs = KW(
               :include_mathjax => "cdn",
               :yaxis => KW(:automargin => true),
               :xaxis => KW(:domain => "auto")

I have this error:

ERROR: Unknown key: extra_plot_kwargs
[1] default(::Symbol) at /Users/oto/.julia/packages/Plots/WwFyB/src/args.jl:632
[2] warnOnUnsupported_args(::Plots.PlotlyBackend, ::Dict{Symbol,Any}) at /Users/oto/.julia/packages/Plots/WwFyB/src/args.jl:1160
[3] _add_the_series(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}) at /Users/oto/.julia/packages/Plots/WwFyB/src/pipeline.jl:376
[4] _process_seriesrecipe(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}) at /Users/oto/.julia/packages/Plots/WwFyB/src/pipeline.jl:404
[5] _plot!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{UnitRange{Int64},Array{Array{Float64,1},1}}) at /Users/oto/.julia/packages/Plots/WwFyB/src/plot.jl:234
[6] #plot#137(::Base.Iterators.Pairs{Symbol,Any,NTuple{5,Symbol},NamedTuple{(:labels, :xlabel, :ylabel, :yformatter, :extra_plot_kwargs),Tuple{Array{LaTeXString,2},LaTeXString,LaTeXString,Symbol,Dict{Symbol,Any}}}}, ::typeof(plot), ::UnitRange{Int64}, ::Vararg{Any,N} where N) at /Users/oto/.julia/packages/Plots/WwFyB/src/plot.jl:57
[7] (::RecipesBase.var"#kw##plot")(::NamedTuple{(:labels, :xlabel, :ylabel, :yformatter, :extra_plot_kwargs),Tuple{Array{LaTeXString,2},LaTeXString,LaTeXString,Symbol,Dict{Symbol,Any}}}, ::typeof(plot), ::UnitRange{Int64}, ::Array{Array{Float64,1},1}) at ./none:0
[8] top-level scope at REPL[3]:1

You are probably on an older version of Plots

1 Like

I see, you are right one package downgraded my Plots package.
Unfortunately, I have latex rendered only when saved as html.
In vs code plot pane and in PDF the latex is not correct.

For me it is similiar. In the html everything works, but if I save savefig(p1, <file_path>) i.e. as a pdf it isn´t working

PlotlyJS supports latex string via Mathjax, but only in html format. (Latex)
Is there any way how to convert html figure to pdf/eps?

1 Like

For me, even the original code does not work (disabled plot pane):

Guess, MathJax must be enabled for the standalone windows somehow.

You need to save it as HTML…