# Error using PGFPlots.jl

``````using PGFPlots
p = []
fun = [sin, cos]
x = 0:10
for i = 1:2
push!(p, Plots.Linear(x, fun[i].(x)))
end
Axis(p)
``````

I get the following error:

``````ERROR: LoadError: MethodError: no method matching Axis(::Array{Any,1})
``````

But if I replace `Axis(p)` by `Axis([p, p])`, it actually plots the two curves. Moreover, adding `println([p, p] == p)` it actually prints `true` as the answer.

So, if `[p, p] == p`, why do I get an error with `Axis(p)`? I can’t really understand this behavior.

This isn’t actually a PGFPlots specific issue, but rather to do with the way you construct your arrays:

``````julia> p = []  # No type information supplied, hence our array is of type Any
0-element Array{Any,1}

julia> for i ∈ 1:2
push!(p, 5)
end

julia> p
2-element Array{Any,1}:   # Type stays Array{Any} as this is what was defined above
5
5

julia> [p, p]
2-element Array{Int64,1}:  # Here we are constructing a new Array, the type of which is inferred from the elements and is therefore Array{Int64,1}
5
5

julia> [p, p] == p   # This compares the contents of the Arrays
true

julia> typeof(p) == typeof([p, p])  # This compares the types - they differ, as the array comprehension infers the type for us. This causes your issue in dispatch.
false

# You should be doing the equivalent of this:
julia> q = Array{Int64, 1}() # Instantiate the Array with the type you want
0-element Array{Int64,1}

julia> for i ∈ 1:2
push!(q, 5)
end

julia> typeof(q) == typeof([p, p])
true
``````

I don’t have PGFPlots installed on this machine, but you’ll want to check `typeof(p)` and then replace `p = []` with `p = Array{ result_of_typeof[p] , 1}()` to ensure `p` has the right type for the call to `Axis` to work.

1 Like

There is a simpler and more convenient way of creating empty typed arrays. Rather than writing `Array{T,1}()` or `Vector{T}()`, you just write `T[]`. E.g.

``````julia> Float64[]
0-element Array{Float64,1}
``````

Sometimes it might be a bit hard to get `T` right, though, so it is perhaps easier to do something like this:

``````p = [plot(x, fun.(x)) for fun in (sin, cos)]
``````

(I couldn’t find any function `Plots.Linear` in either `Plots` or `PGFPlots`.)

1 Like

Thank you very much for all your advice. I’ve changed the code as follows and it works fine:

``````using PGFPlots
p = Array{PGFPlots.Plots.Linear}(undef, 2)
fun = [sin, cos]
x = 0:10
for i = 1:2
p[i] = Plots.Linear(x, fun[i].(x))
end
Axis(p)
``````

It’s up to you, of course, but to me it looks a bit overly complicated and verbose. The comprehension relieves you of having to specify complex types, having to repeat yourself, and potentially getting it subtly wrong.

Whenever I can leave type stuff to the compiler, I tend to find that the resulting code is cleaner and more generic.

1 Like

That’s my matlabish background working. My code is slightly more complicated and it was a bit of a challenge to code it as a comprehension. It looks very neat now. Thank you again for your help.