Different plotly behavour across computers

I am using Plots with the plotly() backend for plotting a time vector against a vector containing 10 vectors using the following:

plot(time_vect, dataMat, hover = time_vect, layout = (10,1))

This works fine on both my computers and with 10 subplots as expected. However when I try to link axis with the following:

plot(time_vect, dataMat, hover = time_vect, layout = (10,1), link = :x)

it works fine on one windows 10 machine, but on the other windows 10 machine I get the following error:

julia> plot(time_vect, dataMat, hover = time_vect, layout = (10,1), link = :x)
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
iterate(::Core.SimpleVector) at essentials.jl:603
iterate(::Core.SimpleVector, ::Any) at essentials.jl:603
iterate(::ExponentialBackOff) at error.jl:253
…
Stacktrace:
[1] isempty(::Symbol) at .\essentials.jl:739
[2] _update_axis_links(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Axis, ::Symbol) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1480
[3] _update_axis(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Symbol, ::Int64) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1439
[4] _update_subplot_args(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Int64, ::Bool) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1503
[5] _subplot_setup(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\pipeline.jl:273
[6] plot_setup! at C:\Users\jason.julia\packages\Plots\Vfmes\src\pipeline.jl:157 [inlined]
[7] recipe_pipeline!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Any,1}}) at C:\Users\jason.julia\packages\RecipesPipeline\5b2IP\src\RecipesPipeline.jl:85
[8] _plot!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Any,1}}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\plot.jl:167
[9] plot(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N; kw::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:hover, :layout, :link),Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Tuple{Int64,Int64},Symbol}}}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\plot.jl:57
[10] top-level scope at none:0

I have done an update of all packages with “] update”.

Why would it work on one but not the other?

Any suggestions on what else I can try before I try a clean reinstall of Julia and all packages?

The first thing I would check is that all relevant package versions are the same (pkg> status).

3 Likes

Machine that works is Plots v0.29.8
Machine that doesn’t work is Plots v1.2.6

The machine that worked under v0.29.8 no longer works when I update to v1.2.6

Thanks, we have worked out its the Plots version 1.2.6 is broken somewhere! Progress!

What should I do next? Report it somewhere?

I am not sure that it’s Plots that is broken (instead of your setup), but any kind of investigation would need more details than “it no longer works”. I would suggest that you isolate the issue and then ask here (with version, an MWE, error messages, etc).

Im a bit new to all this, so not sure what MWE is, please let me know what other information I should add to the following in order to isolate the issue better:

I am using Julia Version 1.4.1 (2020-04-14). When I use Plots and the plotly() backend, Plots v1.2.6 sends an error message when I try to use:

plot(time_vect, dataMat, hover = time_vect, layout = (10,1), link = :x)

but works fine (i.e. without linking x axes of course) if i remove the “link = :x” as follows:

plot(time_vect, dataMat, hover = time_vect, layout = (10,1))

The “link = :x” works fine on Plots v0.29.8, but stopped when I updated to Plots v1.2.6.

The error message is as follows:

julia> plot(time_vect, dataMat, hover = time_vect, layout = (10,1), link = :x)
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
iterate(::Core.SimpleVector) at essentials.jl:603
iterate(::Core.SimpleVector, ::Any) at essentials.jl:603
iterate(::ExponentialBackOff) at error.jl:253
…
Stacktrace:
[1] isempty(::Symbol) at .\essentials.jl:739
[2] _update_axis_links(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Axis, ::Symbol) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1480
[3] _update_axis(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Symbol, ::Int64) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1439
[4] _update_subplot_args(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Int64, ::Bool) at C:\Users\jason.julia\packages\Plots\Vfmes\src\args.jl:1503
[5] _subplot_setup(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\pipeline.jl:273
[6] plot_setup! at C:\Users\jason.julia\packages\Plots\Vfmes\src\pipeline.jl:157 [inlined]
[7] recipe_pipeline!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Any,1}}) at C:\Users\jason.julia\packages\RecipesPipeline\5b2IP\src\RecipesPipeline.jl:85
[8] _plot!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Any,1}}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\plot.jl:167
[9] plot(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N; kw::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:hover, :layout, :link),Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Tuple{Int64,Int64},Symbol}}}) at C:\Users\jason.julia\packages\Plots\Vfmes\src\plot.jl:57
[10] top-level scope at none:0

From what I can gather, it looks like either the syntax has changed for Plots to link axes, or it isn’t properly implemented in Plots with the plotly backend.

Any help in finding the problem would be greatly appreciated.

It works for me:

julia> time_vect=[1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> dataMat=[2 2 2;3 3 3;4 4 4]
3Ă—3 Array{Int64,2}:
 2  2  2
 3  3  3
 4  4  4

julia> using Plots

julia> plotly()
[ Info: For saving to png with the Plotly backend ORCA has to be installed.
Plots.PlotlyBackend()

julia> plot(time_vect, dataMat, hover = time_vect, layout = (3,1), link=:x)

gives:
newplot

What you see above is a MWE (minimal working example), because others can just copy&paste the code to try and find issues.

Now whats needed next is your MNWE (minimal non working example). There is probably something wrong in your data, which results in the error.

See also

julia> versioninfo()
Julia Version 1.4.1
Commit 381693d3df* (2020-04-14 17:20 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: AMD Ryzen 5 3600 6-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, znver1)

(@v1.4) pkg> st
Status `C:\Users\USER\.julia\environments\v1.4\Project.toml`
...
  [91a5bcdd] Plots v1.2.6
...
3 Likes

Thanks for that example, which also works for me. However, dataMat that isn’t working is a bit different to your example because it is a vector of vectors (sorry, dataMat is a bad variable name!):

julia> time_vect=[1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

julia> dataMat=[[2 2 2], [3 3 3], [4 4 4]]
3-element Array{Array{Int64,2},1}:
 [2 2 2]
 [3 3 3]
 [4 4 4]

julia> plot(time_vect, dataMat, hover = time_vect, layout = (3,1), link=:x)
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
  iterate(::Core.SimpleVector) at essentials.jl:603
  iterate(::Core.SimpleVector, ::Any) at essentials.jl:603
  iterate(::ExponentialBackOff) at error.jl:253
  ...
Stacktrace:
 [1] isempty(::Symbol) at .\essentials.jl:739
 [2] _update_axis_links(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Axis, ::Symbol) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\args.jl:1480
 [3] _update_axis(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Symbol, ::Int64) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\args.jl:1439
 [4] _update_subplot_args(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Int64, ::Bool) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\args.jl:1503
 [5] _subplot_setup(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\pipeline.jl:273
 [6] plot_setup! at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\pipeline.jl:157 [inlined]
 [7] recipe_pipeline!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Int64,1},Array{Array{Int64,2},1}}) at C:\Users\z3002230\.julia\packages\RecipesPipeline\5b2IP\src\RecipesPipeline.jl:85
 [8] _plot!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Int64,1},Array{Array{Int64,2},1}}) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\plot.jl:167
 [9] plot(::Array{Int64,1}, ::Vararg{Any,N} where N; kw::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:hover, :layout, :link),Tuple{Array{Int64,1},Tuple{Int64,Int64},Symbol}}}) at C:\Users\z3002230\.julia\packages\Plots\Vfmes\src\plot.jl:57
 [10] top-level scope at REPL[9]:1

However, dataMat in this from works on Plots v0.29.8 but stopped working on v1.2.6. I need this to work because each vector is of different lengths so I cant plot it as a matrix.

julia> versioninfo()
Julia Version 1.4.0
Commit b8e9a9ecc6 (2020-03-21 16:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-8.0.1 (ORCJIT, icelake-client)

Ok, for me this isn’t a Plots question anymore. I don’t have an idea how to solve this with Plots only, but maybe there is a way.

So I suggest to reformat the dataMat Array of Arrays and I assume the following:

  • Your dataMat is an Array of Arrays with different length and looks e.g. like:
julia> dataMat
3-element Array{Array{Int64,2},1}:
 [2 2 2]
 [3 3 3 3]
 [4 4 4 4]
  • This dataMat should be plotted like the matrix I assumed above, that means for this Array of Arrays: 4 Plots, each plot produces a line through y = 2,3,4, except plot #4 which only has a line through y=3,4.

To achieve this I reformat your dataMat into a matrix where each Row is filled up with missings at the end except for the longest rows:

julia> ml=maximum(length.(dataMat))
4

julia> dataMat2=reduce(vcat,[ if length(a)==ml a else hcat(a,Array{Missing}(missing,ml-length(a))) end for a in dataMat ])
3Ă—4 Array{Union{Missing, Int64},2}:
 2  2  2   missing
 3  3  3  3
 4  4  4  4

julia> plot(time_vect, dataMat2, hover = time_vect, layout = (4,1), link=:x)

newplot

The reformat and reshape thing can be solved more elegant I guess…

1 Like

Thanks for your reply, I am grateful for your help.

The data I have isn’t in the format of the example you provided. Instead it is like this:

time_vect = [1, 2, 3, 4]
dataMat1 = [ ]
push!(dataMat1, [1; 2; 3 ;1])
push!(dataMat1, [1; 3; 2 ;1])
push!(dataMat1, [1; 2; 3 ;1])

julia> dataMat1
3-element Array{Any,1}:
 [1, 2, 3, 1]
 [1, 3, 2, 1]
 [1, 2, 3, 1]

Each vector is supposed to be a single subplot itself. The data is in that format after various processing steps, so that format (array of vectors) is my starting point.

In the older version of Plots v0.29.8, I could use “link = :x” and it would work, whereas in Plots v 12.6, it no longer works as before, even though I can still plot the data without linking the axes:

plot(time_vect, dataMat1, layout = (3,1))

newplot
(works fine)

but adding “link = :x” causes problems:

julia> plot(time_vect, dataMat1, layout = (3,1), link = :x)

ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
  iterate(::Core.SimpleVector) at essentials.jl:603
  iterate(::Core.SimpleVector, ::Any) at essentials.jl:603
  iterate(::ExponentialBackOff) at error.jl:253
  ...
Stacktrace:
 [1] isempty(::Symbol) at .\essentials.jl:739
 [2] _update_axis_links(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Axis, ::Symbol) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\args.jl:1480
 [3] _update_axis(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Symbol, ::Int64) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\args.jl:1439
 [4] _update_subplot_args(::Plots.Plot{Plots.PlotlyBackend}, ::Plots.Subplot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Int64, ::Bool) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\args.jl:1503    
 [5] _subplot_setup(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Array{Dict{Symbol,Any},1}) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\pipeline.jl:273
 [6] plot_setup! at C:\Users\jason\.julia\packages\Plots\Vfmes\src\pipeline.jl:157 [inlined]
 [7] recipe_pipeline!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Int64,1},Array{Any,1}}) at C:\Users\jason\.julia\packages\RecipesPipeline\5b2IP\src\RecipesPipeline.jl:85      
 [8] _plot!(::Plots.Plot{Plots.PlotlyBackend}, ::Dict{Symbol,Any}, ::Tuple{Array{Int64,1},Array{Any,1}}) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\plot.jl:167
 [9] plot(::Array{Int64,1}, ::Vararg{Any,N} where N; kw::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol},NamedTuple{(:layout, :link),Tuple{Tuple{Int64,Int64},Symbol}}}) at C:\Users\jason\.julia\packages\Plots\Vfmes\src\plot.jl:57
 [10] top-level scope at none:0

So I think its because Plots has changed through the versions and no longer supports linking axes if the data is in the above format, even though it still plots ok it otherwise.

Using your approach I managed to get it to work, but I’ve had to make extra variables to do that (my vectors are large signals i.e. big data sets), when if Plots worked as it did before, I wouldn’t require additional memory allocation:


julia> dataMat1
3-element Array{Any,1}:
 [1, 2, 3, 1]
 [1, 3, 2, 1]
 [1, 2, 3, 1]


dataMat2 = reduce(hcat,[a for a in dataMat1]) # 2nd matrix

julia> dataMat2
4Ă—3 Array{Int64,2}:
 1  1  1
 2  3  2
 3  2  3
 1  1  1

plot(time_vect, dataMat2, layout = (3,1), link = :x) # this works with linked x axes across subplots

I think something was left out of Plots. What is the best way to report this?

ps: thanks for showing me the comprehension expression, I was going crazy trying to flatten the array into a simple matrix, plus your addition of missing values will be very handy when my vectors have different lengths! If you know of a simpler way to make dataMat2, please let me know, those manipulations get me every time!

This is the place to report this issue:

2 Likes

Thanks again for your help!