# Speed of plotting using PlotlyJS

**URL:** <https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937>\
**Category:** General Usage\
**Tags:** plotting\
**Created:** [September 2, 2020, 9:28am UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937 "2020-09-02T09:28:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oto\_Brzobohaty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oto_brzobohaty/32/10370_2.png) [@Oto\_Brzobohaty](https://discourse.julialang.org/u/Oto_Brzobohaty)\
**Post date:** [September 2, 2020, 9:28am UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/1 "2020-09-02T09:28:36Z")

</div>

Is it normal that plotting using PlotlyJS takes 2-5 sec?

```julia
using PlotlyJS
plot(heatmap(z = rand(2000, 1000)))

```

---

<div class="post-metadata">

**Author:** ![sglyon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sglyon/32/67_2.png) [@sglyon](https://discourse.julialang.org/u/sglyon)\
**Post date:** [September 2, 2020, 12:03pm UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/2 "2020-09-02T12:03:21Z")

</div>

Hi @Oto_Brzobohaty this is expected.

The vast majority of the time it taken up converting the large (2000, 1000) matrix to a nested JSON array to emebd in the WebIO scope. We would love to use a binary transport between julia and the web frontend, but that has yet to be implemented.

See below. 3526/5086 and then again another 1441/5086 of the traces are taken inside `@JSON/src/Writer.jl` for a total of 4967/5086, or ~97%

See the very end for the pure Julia side where I use `Plot` instead of `plot`. Depending on what you are trying to do with the plot, you might be able to get away with just `Plot`.

```julia
julia> using PlotlyJS

julia> using Profile

julia> @time plot(heatmap(z=rand(2000, 1000)));
  2.669931 seconds (8.99 M allocations: 1.276 GiB, 7.95% gc time)

julia> @time plot(heatmap(z=rand(2000, 1000)));
  0.966190 seconds (4.00 M allocations: 1.014 GiB, 11.70% gc time)

julia> @time rand(2000, 1000);
  0.002154 seconds (2 allocations: 15.259 MiB)

julia> Profile.@profile for i in 1:5 plot(heatmap(z=rand(2000, 1000))); end

julia> Profile.print()
Overhead ╎ [+additional indent] Count File:Line; Function
=========================================================
    ╎5086 @Base/client.jl:506; _start()
    ╎ 5086 @Base/client.jl:313; exec_options(::Base.JLOptions)
    ╎ 5086 @Base/client.jl:383; run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool)
    ╎ 5086 @Base/essentials.jl:709; invokelatest
    ╎ 5086 @Base/essentials.jl:710; #invokelatest#1
    ╎ 5086 @Base/client.jl:399; (::Base.var"#806#808"{Bool,Bool,Bool,Bool})(::Module)
    ╎ ╎ 5086 ...e_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288; run_repl(::REPL.AbstractREPL, ::Any)
    ╎ ╎ 5086 ..._linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:292; run_repl(::REPL.AbstractREPL, ::Any; backend_on_current_task::Bool)
    ╎ ╎ 5086 ..._linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:180; start_repl_backend(::REPL.REPLBackend, ::Any)
    ╎ ╎ 5086 ..._linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:195; repl_backend_loop(::REPL.REPLBackend)
    ╎ ╎ 5086 ...linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:134; eval_user_input(::Any, ::REPL.REPLBackend)
    ╎ ╎ ╎ 5086 @Base/boot.jl:331; eval(::Module, ::Any)
    ╎ ╎ ╎ 5086 ...4/build/usr/share/julia/stdlib/v1.5/Profile/src/Profile.jl:28; top-level scope
    ╎ ╎ ╎ 5086 REPL[7]:1; macro expansion
    ╎ ╎ ╎ 22 ...64/build/usr/share/julia/stdlib/v1.5/Random/src/Random.jl:277; rand
    ╎ ╎ ╎ 22 ...4/build/usr/share/julia/stdlib/v1.5/Random/src/Random.jl:289; rand(::Type{Float64}, ::Tuple{Int64,Int64})
    ╎ ╎ ╎ ╎ 22 ...4/build/usr/share/julia/stdlib/v1.5/Random/src/Random.jl:288; rand
    ╎ ╎ ╎ ╎ 15 @Base/boot.jl:423; Array
    ╎ ╎ ╎ ╎ 15 @Base/boot.jl:416; Array
  15╎ ╎ ╎ ╎ 15 @Base/boot.jl:408; Array
    ╎ ╎ ╎ ╎ 7 .../build/usr/share/julia/stdlib/v1.5/Random/src/Random.jl:267; rand!
    ╎ ╎ ╎ ╎ 7 ...64/build/usr/share/julia/stdlib/v1.5/Random/src/RNGs.jl:513; rand!
    ╎ ╎ ╎ ╎ 7 ...64/build/usr/share/julia/stdlib/v1.5/Random/src/RNGs.jl:507; _rand!
    ╎ ╎ ╎ ╎ 7 ...4/build/usr/share/julia/stdlib/v1.5/Random/src/RNGs.jl:495; rand!(::Random.MersenneTwister, ::Random.UnsafeView{Float64}, ::Random.SamplerTrivi...
    ╎ ╎ ╎ ╎ ╎ 7 ...4/build/usr/share/julia/stdlib/v1.5/Random/src/RNGs.jl:469; fill_array!
   6╎ ╎ ╎ ╎ ╎ 7 .../build/usr/share/julia/stdlib/v1.5/Random/src/DSFMT.jl:95; dsfmt_fill_array_close_open!(::Random.DSFMT.DSFMT_state, ::Ptr{Float64}, ::Int64)
    ╎ ╎ ╎ 5064 @PlotlyJS/src/display.jl:145; plot
    ╎ ╎ ╎ 5064 @PlotlyJS/src/display.jl:145; #plot#6
    ╎ ╎ ╎ ╎ 5064 @PlotlyJS/src/display.jl:24; Type##kw
    ╎ ╎ ╎ ╎ 6 @PlotlyJS/src/display.jl:47; PlotlyJS.SyncPlot(::Plot{Array{GenericTrace{Dict{Symbol,Any}},1},Layout{Dict{Symbol,A...
    ╎ ╎ ╎ ╎ 6 @WebIO/src/scope.jl:224; setindex!
    ╎ ╎ ╎ ╎ 6 @WebIO/src/scope.jl:185; setobservable!
    ╎ ╎ ╎ ╎ 6 @WebIO/src/scope.jl:195; setobservable!(::WebIO.Scope, ::String, ::Observables.Observable{String}; sync::Not...
    ╎ ╎ ╎ ╎ ╎ 6 @Base/weakkeydict.jl:82; setindex!
    ╎ ╎ ╎ ╎ ╎ 6 @Base/weakkeydict.jl:76; lock
    ╎ ╎ ╎ ╎ ╎ 6 @Base/lock.jl:161; lock(::Base.var"#507#508"{WeakKeyDict{Any,Any},Tuple{WeakRef,String},Observables....
    ╎ ╎ ╎ ╎ ╎ 6 @Base/weakkeydict.jl:83; #507
    ╎ ╎ ╎ ╎ ╎ 6 @Base/dict.jl:381; setindex!(::Dict{WeakRef,Any}, ::Tuple{WeakRef,String}, ::WeakRef)
    ╎ ╎ ╎ ╎ ╎ ╎ 6 @Base/dict.jl:326; ht_keyindex2!(::Dict{WeakRef,Any}, ::WeakRef)
    ╎ ╎ ╎ ╎ ╎ ╎ 6 @Base/operators.jl:123; isequal
   6╎ ╎ ╎ ╎ ╎ ╎ 6 @Base/gcutils.jl:3; ==(::WeakRef, ::WeakRef)
    ╎ ╎ ╎ ╎ 5058 @PlotlyJS/src/display.jl:78; PlotlyJS.SyncPlot(::Plot{Array{GenericTrace{Dict{Symbol,Any}},1},Layout{Dict{Symbol,A...
    ╎ ╎ ╎ ╎ 2 @Base/strings/substring.jl:191; string(::String, ::String, ::Vararg{String,N} where N)
   2╎ ╎ ╎ ╎ 2 @Base/strings/string.jl:60; _string_n
    ╎ ╎ ╎ ╎ 37 @Base/strings/substring.jl:194; string(::String, ::String, ::Vararg{String,N} where N)
    ╎ ╎ ╎ ╎ 37 @Base/strings/substring.jl:178; __unsafe_string!
  37╎ ╎ ╎ ╎ 37 @Base/array.jl:245; unsafe_copyto!
    ╎ ╎ ╎ ╎ 3526 @JSExpr/src/JSExpr.jl:19; jsexpr(::Array{GenericTrace{Dict{Symbol,Any}},1})
    ╎ ╎ ╎ ╎ 3526 @Base/strings/io.jl:101; sprint
    ╎ ╎ ╎ ╎ 3526 @Base/strings/io.jl:105; sprint(::Function, ::Array{GenericTrace{Dict{Symbol,Any}},1}; context::Nothing, siz...
    ╎ ╎ ╎ ╎ ╎ 3526 @JSExpr/src/JSExpr.jl:20; (::JSExpr.var"#1#2")(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Array{GenericTrace{D...
    ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:324; show_json
    ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:325; #show_json#3
    ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:293; show_json(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::W...
    ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:218; show_element(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}},...
    ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:314; show_json
    ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:271; show_json(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}}, :...
    ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:243; show_pair(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ...
    ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:241; show_pair(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ...
    ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:306; show_json(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}},...
    ╎ ╎ ╎ ╎ ╎ ╎ ╎ 3526 @JSON/src/Writer.jl:218; show_element(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1...
   1╎ ╎ ╎ ╎ ╎ ╎ ╎ 1 @JSON/src/Writer.jl:215; show_element(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1...
   3╎ ╎ ╎ ╎ ╎ ╎ ╎ 3 @JSON/src/Writer.jl:218; show_element(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1...
  13╎ ╎ ╎ ╎ ╎ ╎ ╎ 3522 @JSON/src/Writer.jl:293; 

XXXXXXXXXX MANY LINES DELETED!

    ╎ ╎ ╎ ╎ 1493 @WebIO/src/scope.jl:313; onimport
    ╎ ╎ ╎ ╎ 1493 @Base/strings/io.jl:101; sprint
    ╎ ╎ ╎ ╎ 1493 @Base/strings/io.jl:105; sprint(::Function; context::Nothing, sizehint::Int64)
    ╎ ╎ ╎ ╎ ╎ 1493 @WebIO/src/syntax.jl:221; (::WebIO.var"#42#43"{WebIO.Scope,WebIO.JSString})(::Base.GenericIOBuffer{Array{UIn...

XXXXXXXXXX MANY LINES DELETED!

    ╎ ╎ ╎ ╎ ╎ 1492 @WebIO/src/syntax.jl:193; showjs
    ╎ ╎ ╎ ╎ ╎ 1492 @JSON/src/Writer.jl:324; show_json
    ╎ ╎ ╎ ╎ ╎ 1492 @JSON/src/Writer.jl:325; #show_json#3
    ╎ ╎ ╎ ╎ ╎ 1492 @WebIO/src/syntax.jl:246; show_json(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::...
    ╎ ╎ ╎ ╎ ╎ ╎ 1492 @Base/strings/io.jl:185; print
   1╎ ╎ ╎ ╎ ╎ ╎ 1492 @Base/strings/io.jl:183; write
    ╎ ╎ ╎ ╎ ╎ ╎ 1491 @Base/io.jl:233; unsafe_write(::JSON.Writer.CompactContext{Base.GenericIOBuffer{Array{UInt8,1}}...
   3╎ ╎ ╎ ╎ ╎ ╎ 5 @Base/pointer.jl:105; unsafe_load
    ╎ ╎ ╎ ╎ ╎ ╎ 2 @Base/boot.jl:708; Int64
    ╎ ╎ ╎ ╎ ╎ ╎ ╎ 2 @Base/boot.jl:633; toInt64
   2╎ ╎ ╎ ╎ ╎ ╎ ╎ 2 @Base/boot.jl:572; check_top_bit
    ╎ ╎ ╎ ╎ ╎ ╎ 45 @Base/range.jl:624; iterate
  45╎ ╎ ╎ ╎ ╎ ╎ 45 @Base/promotion.jl:398; ==
    ╎ ╎ ╎ ╎ ╎ ╎ 1441 @JSON/src/Writer.jl:122; write

XXXXXXXXXX MANY LINES DELETED!

Total snapshots: 5095

julia> @time Plot(heatmap(z=rand(2000, 1000)));
  0.003693 seconds (23 allocations: 15.261 MiB)

```

---

<div class="post-metadata">

**Author:** ![Oto\_Brzobohaty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oto_brzobohaty/32/10370_2.png) [@Oto\_Brzobohaty](https://discourse.julialang.org/u/Oto_Brzobohaty)\
**Post date:** [September 2, 2020, 6:26pm UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/3 "2020-09-02T18:26:00Z")

</div>

Thank you for the clarification. Typically, I use VS Code with plot pane and the plotting is very slow. The plot command is done and the profile gives me st like this

```julia
@time Plot(heatmap(z = rand(2000, 1000)))
  0.006809 seconds (22 allocations: 15.261 MiB)

```

But the plotting either in VS Code Plot pane or electron window takes 2-5 secs.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [September 2, 2020, 7:17pm UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/4 "2020-09-02T19:17:51Z")

</div>

Generating the plot itself (or at least the heatmap for it) is strictly fast (e.g. if you would only want to get it to a file). PlotlyJS is web technology, but you’re not displaying it in a web browser that’s already open. The wrapper, uses Blink, that starts a GUI for you, while not obvious is a full web browser, that’s the thing taking time to start ( ~~the first time~~ each time), and that’s at least part of the problem.

[https://juliahub.com/ui/Packages/Blink/wSmkt/0.12.3?t=0](https://juliahub.com/ui/Packages/Blink/wSmkt/0.12.3?t=0)

That’s (kind of) what’s meant by the docs saying:

> This package does not interact with the [Plotly web API](https://api.plot.ly/v2/), but rather leverages the underlying javascript library to construct plotly graphics using all local resources.

Using some other plotting package that converts to a picture, not JSON, might be what you need to speed this up.

I use Julia 1.6, and depending on options this is the speed:

```julia
$ julia -O1 -q
julia> @time using Plots
  4.253229 seconds (5.80 M allocations: 414.695 MiB, 2.36% gc time)

julia> @time plot(heatmap(z = rand(2000, 1000)))
  1.185529 seconds (1.20 M allocations: 84.774 MiB, 5.22% gc time)

```

[I’m having trouble on my machine with GR.jl, that’s the default backend for above, making it hang. I think, I’m not sure, you would see something with above, this fast.]

I didn’t find the best Plots.jl backend (or look much further) to actually see the plot (and the first plot/heatmap is going to be the slowest):

```julia
$ julia -O0 --compile=min -q
julia> @time using Plots
  3.606296 seconds (5.12 M allocations: 376.402 MiB, 2.88% gc time)

julia> @time heatmap(z = rand(2000, 1000));
  0.228301 seconds (128.01 k allocations: 23.188 MiB, 33.66% gc time)

julia> @time heatmap(z = rand(2000, 1000));
  0.034798 seconds (5.44 k allocations: 15.436 MiB)

```

This seemed to work (did you get similar?), note, deprecations are known to slow down Julia:

```julia
julia> using PlotlyJS
[Info: Precompiling PlotlyJS [f0f68f2c-4968-5e81-91da-67840de0976a]
┌ Warning: `@get!(dict, key, default)` at /home/pharaldsson_sym/.julia/packages/WebIO/nTMDV/src/scope.jl:160 is deprecated, use `get!(()->default, dict, key)` instead.
└ @ Base deprecated.jl:204
┌ Warning: `@get!(dict, key, default)` at /home/pharaldsson_sym/.julia/packages/WebIO/nTMDV/src/scope.jl:357 is deprecated, use `get!(()->default, dict, key)` instead.
└ @ Base deprecated.jl:204
WARNING: using HTTP.stack in module Mux conflicts with an existing identifier.

```

---

<div class="post-metadata">

**Author:** ![Oto\_Brzobohaty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oto_brzobohaty/32/10370_2.png) [@Oto\_Brzobohaty](https://discourse.julialang.org/u/Oto_Brzobohaty)\
**Post date:** [September 7, 2020, 6:50am UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/5 "2020-09-07T06:50:52Z")

</div>

Is there any way how to improve drawing speed in VSCode plot pane?

Usually, I have plotted several graphs and even deleting them is very slow.

---

<div class="post-metadata">

**Author:** ![sglyon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sglyon/32/67_2.png) [@sglyon](https://discourse.julialang.org/u/sglyon)\
**Post date:** [September 12, 2020, 8:54pm UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/6 "2020-09-12T20:54:12Z")

</div>

@Oto_Brzobohaty could you do an experiment for us?

Can you try using PlotlyBase for plotting in vs code instead of PlotlyJS? (note you’ll need to use `Plot` with a capital `P` instead of `plot` after `using PlotlyBase` - other than that everything should be the same)

After doing that can you report to see if it is still slow?

---

<div class="post-metadata">

**Author:** ![Oto\_Brzobohaty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oto_brzobohaty/32/10370_2.png) [@Oto\_Brzobohaty](https://discourse.julialang.org/u/Oto_Brzobohaty)\
**Post date:** [September 13, 2020, 10:03am UTC](https://discourse.julialang.org/t/speed-of-plotting-using-plotlyjs/45937/7 "2020-09-13T10:03:09Z")

</div>

Is this what do you need?

[https://youtu.be/JHQYgFvl5i0](https://youtu.be/JHQYgFvl5i0)
