Makie.jl: [feature request] support multi-column y with automatic legend

Created on 26 Feb 2019  路  7Comments  路  Source: JuliaPlots/Makie.jl

e.g. when x of size n and one has calculated/read in y as a n*m matrix; Plots.jl allows for something like

using Plots
x = 1:10; y = rand(10,2)
plot(x,y)

to plot the columns of y against x, then label them as y1...yn in the legend; I can use a loop to plot lines!(x,y[:,i]) manually but something like lines(x,y) where y can be a multi-column matrix can be helpful/make the code look cleaner. Thanks!

enhancement

Most helpful comment

Right now, looks like it'll be simpler to define a new function (although it feels like the "makie" way is to handle it through recipes and not by defining/overloading functions), e.g.

using Makie
using AbstractPlotting
using Colors

fs = [sin, cos, sinc]
xspan = 0:.01:2*pi
y = [fs[i](x) for x in xspan, i in 1:size(fs,1)]


function plot2d(x::Union{AbstractRange,AbstractArray{<: AbstractFloat, 1}}, y::AbstractArray{<: AbstractFloat, 2};legend_desc=[], kwargs...)
    scene = Scene()
    ny = size(y,2)
    colors = distinguishable_colors(ny+1,[RGB(1,1,1)])[2:end]
    if size(legend_desc,1) != ny
        legend_desc = ["data $i" for i in 1:ny]
    end
    p = []
    for i in 1:ny
            pli = lines!(scene, x, y[:,i], color = colors[i];kwargs...)
            push!(p,pli[end])
    end
    ls = legend(p, legend_desc, camera = campixel!, raw = true)

    # scene
    vbox(scene, ls)
end

plot2d(xspan, y, linewidth = 2)

# with user-supplied legend string 
plot2d(xspan, y, linewidth = 2, legend_desc = string.(fs))

however, currently the legends are printed backwards, i.e. from the last column of y to the 1st. Maybe fixed when we have better documentation of legend: https://github.com/JuliaPlots/Makie.jl/issues/308

screen shot 2019-03-04 at 5 28 17 pm

screen shot 2019-03-04 at 5 27 18 pm

All 7 comments

sorry, I have no idea what you are requesting

@mkborregaard It's quite common when the plot data is a matrix, each column of which corresponding to a line to be plotted. For example, using Plots:

using Plots
xspan = 0:.01:2*pi
fs = [sin, cos, sinc]
y = [fs[i](x) for x in xspan, i in 1:size(fs,1)]
plot(xspan,y)

plots all columns of y against xspan, automatically using different colors and plot labels

screen shot 2019-02-26 at 12 19 20 pm

in Makie, to achieve the same thing, there needs to be additional codes for color, and a loop to go through all columns:

using Makie

fs = [sin, cos, sinc]
colors = [:red, :green, :blue]

xspan = 0:.01:2*pi
y = [fs[i](x) for x in xspan, i in 1:size(fs,1)]

scene = Scene()

for i in 1:size(fs,1)
    lines!(scene,xspan,y[:,i],color=colors[i])
end

scene

screen shot 2019-02-26 at 12 24 42 pm

I'm requesting something like lines(xspan,y) to iterate through all columns of y, with default different colors for each line, and optional automatic/user-provided legends.
This is somewhat related to #8: many of the julia tutorials make examples using Plots and it would be nice for makie to be a drop-in replacement for plots.

Thanks!

Could you use convert_arguments? See https://github.com/JuliaPlots/Makie.jl/issues/307#issuecomment-469116279 for now, but we should have the docs up as soon as JuliaPlots/MakieGallery.jl#13 is merged.

@asinghvi17 thanks! can you give a more concrete example, e.g. an example for the figures above? not sure how to use convert_arguments to do the loop,

using Makie

fs = [sin, cos, sinc]
colors = [:red, :green, :blue]

xspan = 0:.01:2*pi
y = [fs[i](x) for x in xspan, i in 1:size(fs,1)]

scene = Scene()

for i in 1:size(fs,1)
    lines!(scene,xspan,y[:,i],color=colors[i])
end

scene

I think a full recipe is needed, however, the documentation does not include a concrete example, and code below fails:

@recipe(MyPlot2d, x, y)do scene
    Theme(
    )
    end

xy_type = Tuple{<:AbstractRange,<:AbstractArray{<: AbstractFloat, 2}}
xy_data = MyPlot2d{xy_type}

function plot!(plot::xy_data)
    # normal plotting code, building on any previously defined recipes
    # or atomic plotting operations, and adding to the combined `plot`:
    x = plot_object[:arg1]
    y = plot_object[:arg2]
    for i in 1:size(y,2)
        lines!(plot,x,y[:,i])
    end
    plot
end


myplot2d(xspan,y)

returns

Plotting for the arguments (::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Array{Float64,2}) not defined for myplot2d. If you want to support those arguments, overload plot!(plot::myplot2d{ <: Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,2}}})

whereas typeof((xspan,y)) <: xy_type is true.

You're right that it needs a recipe, I think I was thinking of the old transform_arguments (which no longer exists) when I said that. Sorry!

I'm not sure why exactly the recipe is failing, but I'll definitely look into it tomorrow.

Right now, looks like it'll be simpler to define a new function (although it feels like the "makie" way is to handle it through recipes and not by defining/overloading functions), e.g.

using Makie
using AbstractPlotting
using Colors

fs = [sin, cos, sinc]
xspan = 0:.01:2*pi
y = [fs[i](x) for x in xspan, i in 1:size(fs,1)]


function plot2d(x::Union{AbstractRange,AbstractArray{<: AbstractFloat, 1}}, y::AbstractArray{<: AbstractFloat, 2};legend_desc=[], kwargs...)
    scene = Scene()
    ny = size(y,2)
    colors = distinguishable_colors(ny+1,[RGB(1,1,1)])[2:end]
    if size(legend_desc,1) != ny
        legend_desc = ["data $i" for i in 1:ny]
    end
    p = []
    for i in 1:ny
            pli = lines!(scene, x, y[:,i], color = colors[i];kwargs...)
            push!(p,pli[end])
    end
    ls = legend(p, legend_desc, camera = campixel!, raw = true)

    # scene
    vbox(scene, ls)
end

plot2d(xspan, y, linewidth = 2)

# with user-supplied legend string 
plot2d(xspan, y, linewidth = 2, legend_desc = string.(fs))

however, currently the legends are printed backwards, i.e. from the last column of y to the 1st. Maybe fixed when we have better documentation of legend: https://github.com/JuliaPlots/Makie.jl/issues/308

screen shot 2019-03-04 at 5 28 17 pm

screen shot 2019-03-04 at 5 27 18 pm

Perhaps the MultiplePlot feature could be of use here?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AlexisRenchon picture AlexisRenchon  路  3Comments

mohamed82008 picture mohamed82008  路  6Comments

mschauer picture mschauer  路  4Comments

tshort picture tshort  路  5Comments

phlavenk picture phlavenk  路  6Comments