diff --git a/src/Plots.jl b/src/Plots.jl index 00924e25..6dbde71b 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -104,9 +104,9 @@ export @animate, @gif, - PlotRecipe, + # PlotRecipe, spy, - arcdiagram, + # arcdiagram, chorddiagram, test_examples, diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index c45656b5..d04f3761 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -31,7 +31,7 @@ supported_args(::GLVisualizeBackend) = merge_with_base_supported([ ]) supported_types(::GLVisualizeBackend) = [:surface, :scatter, :scatter3d, :path, :path3d] supported_styles(::GLVisualizeBackend) = [:auto, :solid] -supported_markers(::GLVisualizeBackend) = vcat([:none, :auto, :circle], keys(_gl_marker_map)) +supported_markers(::GLVisualizeBackend) = vcat([:none, :auto, :circle], collect(keys(_gl_marker_map))) supported_scales(::GLVisualizeBackend) = [:identity] is_subplot_supported(::GLVisualizeBackend) = true @@ -62,6 +62,8 @@ function _create_backend_figure(plt::Plot{GLVisualizeBackend}) screen end +# --------------------------------------------------------------------------- + # size as a percentage of the window size function gl_relative_size(plt::Plot{GLVisualizeBackend}, msize::Number) winsz = min(plt[:size]...) @@ -92,10 +94,12 @@ function gl_marker(shape::Symbol, msize::Number, _3d::Bool) GeometryTypes.HyperSphere((_3d ? Point3f0 : Point2f0)(0), msize) end +gl_color(c::RGBA{Float32}) = c + # convert to RGBA -function gl_color(c, a) - c = convertColor(c, a)[1] - RGBA{Float32}(c) +function gl_color(c, a=nothing) + c = convertColor(c, a) + RGBA{Float32}(getColor(c)) end function gl_viewport(bb, rect) @@ -109,6 +113,74 @@ function gl_viewport(bb, rect) ) end +gl_make_points(x, y) = Point2f0[Point2f0(x[i], y[i]) for i=1:length(x)] +gl_make_points(x, y, z) = Point3f0[Point3f0(x[i], y[i], z[i]) for i=1:length(x)] + +function gl_draw_lines_2d(x, y, color, linewidth, sp_screen) + color = gl_color(color) + thickness = Float32(linewidth) + for rng in iter_segments(x, y) + n = length(rng) + n < 2 && continue + viz = GLVisualize.visualize( + gl_make_points(x[rng], y[rng]), + n==2 ? :linesegment : :lines, + color=color, + thickness = Float32(linewidth) + ) + GLVisualize.view(viz, sp_screen, camera=:orthographic_pixel) + end +end + +function gl_draw_lines_3d(x, y, z, color, linewidth, sp_screen) + color = gl_color(color) + thickness = Float32(linewidth) + for rng in iter_segments(x, y, z) + n = length(rng) + n < 2 && continue + viz = GLVisualize.visualize( + gl_make_points(x[rng], y[rng], z[rng]), + n==2 ? :linesegment : :lines, + color=color, + thickness = Float32(linewidth) + ) + GLVisualize.view(viz, sp_screen, camera=:perspective) + end +end + +# function gl_draw_lines_3d(x, y, z, color, linewidth, sp_screen) +# color = gl_color(color) +# thickness = Float32(linewidth) +# _3d = camera == :perspective +# xyz = _3d +# for rng in (_3d ? line_segments(x, y, z) : line_segments(x, y)) +# n = length(poi) +# n < 2 && continue +# viz = GLVisualize.visualize( +# gl_make_points(x, y, +# n==2 ? :linesegment : :lines, +# color=color, +# thickness = Float32(linewidth) +# ) +# GLVisualize.view(viz, sp_screen, camera=:perspective) +# end +# end + +function gl_draw_axes_2d(sp::Subplot{GLVisualizeBackend}, sp_screen) + xaxis = sp[:xaxis] + xmin, xmax = axis_limits(xaxis) + yaxis = sp[:yaxis] + ymin, ymax = axis_limits(yaxis) + + # x axis + gl_draw_lines_2d([xmin, xmax], [ymin, ymin], xaxis[:foreground_color_border], 1, sp_screen) + + # y axis + gl_draw_lines_2d([xmin, xmin], [ymin, ymax], yaxis[:foreground_color_border], 1, sp_screen) +end + +# --------------------------------------------------------------------------- + # draw everything function gl_display(plt::Plot{GLVisualizeBackend}) screen = plt.o @@ -116,6 +188,10 @@ function gl_display(plt::Plot{GLVisualizeBackend}) sw, sh = sw*px, sh*px for (name, sp) in plt.spmap + _3d = is3d(sp) + camera = _3d ? :perspective : :orthographic_pixel + # camera = :perspective + # initialize the sub-screen for this subplot # note: we create a lift function to update the size on resize rel_bbox = bbox_to_pcts(bbox(sp), sw, sh) @@ -126,6 +202,10 @@ function gl_display(plt::Plot{GLVisualizeBackend}) area = GLVisualize.const_lift(f, screen.area) ) + if !is3d(sp) + gl_draw_axes_2d(sp, sp_screen) + end + # loop over the series and add them to the subplot for series in series_list(sp) d = series.d @@ -134,6 +214,7 @@ function gl_display(plt::Plot{GLVisualizeBackend}) msize = gl_relative_size(plt, d[:markersize]) viz = if st == :surface + # TODO: can pass just the ranges and surface ismatrix(x) || (x = repmat(x', length(y), 1)) ismatrix(y) || (y = repmat(y, 1, length(x))) z = transpose_z(d, map(Float32, d[:z].surf), false) @@ -141,15 +222,20 @@ function gl_display(plt::Plot{GLVisualizeBackend}) GLVisualize.view(viz, sp_screen, camera = :perspective) else - _3d = is3d(st) - points = if _3d - z = map(Float32, d[:z]) - Point3f0[Point3f0(xi,yi,zi) for (xi,yi,zi) in zip(x, y, z)] - else - Point2f0[Point2f0(xi,yi) for (xi,yi) in zip(x, y)] - end + # paths and scatters - camera = _3d ? :perspective : :orthographic_pixel + _3d && (z = map(Float32, d[:z])) + + # paths? + lw = d[:linewidth] + if lw > 0 + c = gl_color(d[:linecolor], d[:linealpha]) + if _3d + gl_draw_lines_3d(x, y, z, c, lw, sp_screen) + else + gl_draw_lines_2d(x, y, c, lw, sp_screen) + end + end # markers? if st in (:scatter, :scatter3d) || d[:markershape] != :none @@ -167,6 +253,11 @@ function gl_display(plt::Plot{GLVisualizeBackend}) gl_marker(d[:markershape], msize, _3d) end + if !_3d + extrakw[:billboard] = true + end + + points = _3d ? gl_make_points(x,y,z) : gl_make_points(x,y) viz = GLVisualize.visualize( (marker, points); color = c, @@ -180,21 +271,9 @@ function gl_display(plt::Plot{GLVisualizeBackend}) # billboard=true #)) end - - # paths - lw = d[:linewidth] - if !(st in (:scatter, :scatter3d)) && lw > 0 - c = gl_color(d[:linecolor], d[:linealpha]) - viz = GLVisualize.visualize( - points, - :lines, - color = c, - thickness = Float32(lw) - ) - GLVisualize.view(viz, sp_screen, camera = camera) - end end end + GLAbstraction.center!(sp_screen, camera) end # TODO: render one frame at a time? (no renderloop) diff --git a/src/recipes.jl b/src/recipes.jl index 82f02f37..baf44955 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -98,14 +98,14 @@ end # ---------------------------------------------------------------------------------- -abstract PlotRecipe +# abstract PlotRecipe -getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[] -getRecipeArgs(recipe::PlotRecipe) = () +# getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[] +# getRecipeArgs(recipe::PlotRecipe) = () -plot(recipe::PlotRecipe, args...; kw...) = plot(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) -plot!(recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) -plot!(plt::Plot, recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) +# plot(recipe::PlotRecipe, args...; kw...) = plot(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) +# plot!(recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) +# plot!(plt::Plot, recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe)..., args...; getRecipeArgs(recipe)..., kw...) num_series(x::AMat) = size(x,2) num_series(x) = 1