The reason for this is that @df is a macro, not a function, which means that it transforms the code you write into different code before any code is actually run. That is, it operates on the expression [Symbol(name) for name in names(df)[2:5]] before it actually gets evaluated (and thereby turned into [:SYN_MM_BM_5 ...].
To illustrate the difference, you can use @macroexpand (here in conjuction with prettify from MacroTools to make the output a bit more readable:
julia> using DataFrames, StatsPlots, MacroTools
julia> df = DataFrame(a = 1:10, b = 10 .* rand(10), c = 10 .* rand(10));
# Calling macro with symbols written out
julia> prettify(@macroexpand(@df df plot(:a, [:b, :c], colour = [:red :blue])))
:(((crane->begin
((rat, zebra, coyote, butterfly, starling), curlew) = (StatsPlots).extract_columns_and_names(crane, :a, :b, :c, :red, :blue)
(StatsPlots).add_label(["a", "[b, c]"], plot, rat, [zebra, coyote], colour = [butterfly starling])
end))(df))
# Calling macro with comprehension
julia> prettify(@macroexpand(@df df plot(:a, [x for x ∈ names(df)[2:3]], colour = [:red :blue])))
:(((crane->begin
((rat, zebra, coyote), butterfly) = (StatsPlots).extract_columns_and_names(crane, :a, :red, :blue)
(StatsPlots).add_label(["a", "[x for x = (names(df))[23]]"], plot, rat, [x for x = (names(df))[2:3]], colour = [zebra coyote])
end))(df))
As you see, the comprehension does not get picked up by the macro, and you therefore end up calling StatsPlots.extract_columns_and_names(df, :a, :red, :blue) instead of StatsPlots.extract_columns_and_names(df, :a, :b, :c, :red, :blue).
I see that Bogumil has already provided the solution to this as I was typing, looks like my StatsPlots was too slow to precompile :)