Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base.vect(ps::Plot...) = vcat(ps...) is a very strange and unintuitive overload #31

Closed
waralex opened this issue Sep 18, 2020 · 6 comments

Comments

@waralex
Copy link

waralex commented Sep 18, 2020

When using the array creation syntax, it is very strange to get this result:

julia>p = Plot(....)
julia>typeof([p, p])
Plot{Array{AbstractTrace,1},Layout{Dict{Symbol,Any}},Array{PlotlyFrame,1}

Concatenation of elements is not what the user expects to see when creating an array.
From a practical point of view, this leads to problems in Dash. In Dash, the user may need to return an array of Plots from the callback. Moreover, even if the user returns a single Plot, for technical reasons, it is wrapped in an array of one element. And all this doesn't work because of this function overload. And it does not work in a way that puts the novice in a complete dead end. I wrote a workaround for the part that wraps a single element in an array here (now it explicitly does T[el] instead of [el]). Apparently I will need to write about this issue in the user documentation. But ideally, it would be better to remove this overload, because its behavior clearly contradicts the meaning of the vect function

@waralex waralex changed the title Base.vect(ps::Plot...) = vcat(ps...) is a very strange and unintuitive preload Base.vect(ps::Plot...) = vcat(ps...) is a very strange and unintuitive overload Sep 18, 2020
@hhaensel
Copy link
Collaborator

hhaensel commented Jul 14, 2021

I must say that I also stumbled here.

What confused me the most was Julia's internal mechanism of array and matrix construction. I was not aware that [p, p] and [p1 p2; p3] are not direct Vector or Matrix constructors. Instead, they translate to cat-operations:

  • [p1, p2] translates to vcat(p, p)
  • [p1 p2] translates to hcat(p, p)
  • [p1 p2; p3] translates to hvcat((2,1), p1, p2, p3)

(@waralex, @sglyon: I know that you know this, but others might not 😉)

The last line introduces quite a convenient syntax to define a plot with subplots, particularly when allowing different numbers of subplots in each row, which I recently added, cf. #51.

So defining Base.vect(p1, p2) to produce the same as result as [p1, p2] is somehow understandable. But I agree, it is probably better to provide a transparent documentation that vcat(p1, p2) (EDIT: or vcat(pp...) if pp is a true vector of Plots) is the favoured syntax for building subplots and leaving Base.vect() for array construction.

I started digging deeper, when I realised that comprehensions did not produce subplots ...

@sglyon
Copy link
Owner

sglyon commented Jul 15, 2021

@hhaensel thanks for the writeup and the contribution in #51

What do you suggest as a less obtrusive overload that still gives us the nice [p1 p2; p3] synax? Is there a solution that could work?

@waralex
Copy link
Author

waralex commented Jul 15, 2021

  • [p1, p2] translates to vcat(p, p)

There's a small typo here - [p1; p2] translates to vcat, but [p1, p2] translates to vect:

julia> a = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> b = [4, 5, 6]
3-element Vector{Int64}:
 4
 5
 6

julia> [a, b]
2-element Vector{Vector{Int64}}:
 [1, 2, 3]
 [4, 5, 6]

julia> [a; b]
6-element Vector{Int64}:
 1
 2
 3
 4
 5
 6

@sglyon
Copy link
Owner

sglyon commented Jul 15, 2021

Hmm, does this mean we can get what we are looking for without vect and only overloading vcat and hvcat?

In paricular, if we remove thevect overload will we still get [p1; p2] for a 2 x 1 plot and [p1 p2] for a 1 x 2 plot?

@waralex
Copy link
Author

waralex commented Jul 15, 2021

In paricular, if we remove thevect overload will we still get [p1; p2] for a 2 x 1 plot and [p1 p2] for a 1 x 2 plot?

Yes, my original issue would say that when I write [a; b] or [a b] the result can be anything and that's fine. But when I write [a,b,c] as a result I expect only Vector{Union{A, B, C}} and nothing else

@sglyon sglyon closed this as completed in a6251e0 Jul 16, 2021
@hhaensel
Copy link
Collaborator

hhaensel commented Jul 17, 2021

@waralex Thanks for correcting my error above. I thought, I would have tested correctly, but I was probably mislead due to the existing definition Base.vect(ps::Plot...) = vcat(ps...)
Anyhow, I think, with removing that very definition, we did the right thing ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants