I’m plotting a series where I’d like to alternate colors for each point. This works fine via the
mc keyword, but I can’t get the legend to indicate the color coding scheme correctly:
a = rand(10); b = rand(10);
scatter(a, b, mc = [:navy, :crimson], label = ["odd", "even"])
How can I fix the legend?
Just plot the two sets separately?
This is fine in the two-color case, but suppose I wanted to code them based on their index mod 5.
You can do a
for loop over the 5 sets.
I think you need to transpose the label vector
@dpsanders Of course, if there’s no way to accomplish this via the
label keyword, one can write a for loop. But this is a rather inelegant solution, don’t you agree?
a = rand(100); b = rand(100);
idx_container = [i:5:100 for i in 1:5]
colors = [:navy, :crimson, :olivedrab, :rebeccapurple, :goldenrod]
labels = ["$i mod 5" for i in 1:5]
fig = plot()
for (i, idx) in enumerate(idx_container)
scatter!(fig, a[idx], b[idx], mc = colors[i], label=labels[i])
You have to create a one array (or
@view) for the 1st, 6th, 11th entries, another for the 2nd, 7th, and 12th, etc. This results in code far less legible than a list of labels, and calls
plot more times then seemingly necessary.
@nilshg Removing the comma from the label vector doesn’t work, unfortunately:
plots still regards the data as only one series, labeled “odd.”
The for loop doesn’t seem so bad to me, but you could reshape? Something like:
group_by_mod(x, n) = reshape(x, (n, :))'
x = repeat(1:5, outer=5)
y = repeat(1:5, inner=5)
scatter(group_by_mod.((x, y), 5)...)
Ah fair enough - I have to agree with
Plots, you are passing just one series. The best best is then probably reshaping as above or just passing two series:
julia> scatter([a[1:2:end], a[2:2:end]], [b[1:2:end], b[2:2:end]], mc = [:navy :crimson], label = ["odd" "even"])
But if you are looking to plot loads of series, reshape is the way to go I’d think.
That seems like a nice, clear solution to me.
group is probably what you want.
scatter(x, y, group=repeat('a':'e', 5))
This is exactly what I was hoping for! Thank you. Always pleasant not to have to reinvent the wheel for tasks like this.
The comprehension option below is compact enough and allows controlling the markers’ colors, sizes, shapes, etc.:
using Plots; gr()
N=100; a=rand(N); b=rand(N);
Nc=5; colors=[:navy, :crimson, :olivedrab, :rebeccapurple, :goldenrod]
mshape=[:circle, :rect, :star5, :diamond, :hexagon]
labels=["$i mod $Nc" for i in 1:Nc]
fig = plot(legend=:outertopright)
[scatter!(fig, a[j:Nc:end], b[j:Nc:end], mc=colors[j], label=labels[j], shape=mshape[j], ms=j+3) for j in 1:Nc]
Nice solution! I personally prefer to avoid array comprehensions containing functions with side effects and just write a for loop instead.