split plotly into 2 different backends: plotly and plotlyjs

This commit is contained in:
Thomas Breloff 2016-02-05 15:44:27 -05:00
parent a319c0c94a
commit ac3c041d6d
5 changed files with 192 additions and 60 deletions

View File

@ -27,11 +27,11 @@ function _initialize_backend(::PlotlyPackage; kw...)
# end borrowing (thanks :) # end borrowing (thanks :)
########################### ###########################
try # try
include(joinpath(Pkg.dir("Plots"), "src", "backends", "plotly_blink.jl")) # include(joinpath(Pkg.dir("Plots"), "src", "backends", "plotly_blink.jl"))
catch err # catch err
warn("Error including PlotlyJS: $err\n Note: Will fall back to built-in display.") # warn("Error including PlotlyJS: $err\n Note: Will fall back to built-in display.")
end # end
end end
# TODO: other initialization # TODO: other initialization
end end

View File

@ -1,55 +0,0 @@
# override some methods to use PlotlyJS/Blink
import PlotlyJS
function _create_plot(pkg::PlotlyPackage; kw...)
d = Dict(kw)
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
# TODO: initialize the plot... title, xlabel, bgcolor, etc
o = PlotlyJS.Plot(PlotlyJS.GenericTrace[], PlotlyJS.Layout(),
Base.Random.uuid4(), PlotlyJS.ElectronDisplay())
Plot(o, pkg, 0, d, Dict[])
end
function _add_series(::PlotlyPackage, plt::Plot; kw...)
d = Dict(kw)
# add to the data array
pdict = plotly_series(d)
typ = pop!(pdict, :type)
gt = PlotlyJS.GenericTrace(typ; pdict...)
push!(plt.o.data, gt)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.addtraces!(plt.o, gt)
end
push!(plt.seriesargs, d)
plt
end
# TODO: override this to update plot items (title, xlabel, etc) after creation
function _update_plot(plt::Plot{PlotlyPackage}, d::Dict)
pdict = plotly_layout(d)
plt.o.layout = PlotlyJS.Layout(pdict)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.relayout!(plt.o; pdict...)
end
end
function Base.display(::PlotsDisplay, plt::Plot{PlotlyPackage})
dump(plt.o)
display(plt.o)
end
function Base.display(::PlotsDisplay, plt::Subplot{PlotlyPackage})
error()
end
for (mime, fmt) in PlotlyJS._mimeformats
@eval Base.writemime(io::IO, m::MIME{symbol($mime)}, p::Plot{PlotlyPackage}) =
writemime(io, m, p.o)
end

116
src/backends/plotlyjs.jl Normal file
View File

@ -0,0 +1,116 @@
# https://github.com/spencerlyon2/PlotlyJS.jl
function _initialize_backend(::PlotlyJSPackage; kw...)
@eval begin
import PlotlyJS
export PlotlyJS
end
for (mime, fmt) in PlotlyJS._mimeformats
@eval Base.writemime(io::IO, m::MIME{symbol($mime)}, p::Plot{PlotlyJSPackage}) =
writemime(io, m, p.o)
end
end
# ---------------------------------------------------------------------------
function _create_plot(pkg::PlotlyJSPackage; kw...)
d = Dict(kw)
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
# TODO: initialize the plot... title, xlabel, bgcolor, etc
o = PlotlyJS.Plot(PlotlyJS.GenericTrace[], PlotlyJS.Layout(),
Base.Random.uuid4(), PlotlyJS.ElectronDisplay())
Plot(o, pkg, 0, d, Dict[])
end
function _add_series(::PlotlyJSPackage, plt::Plot; kw...)
d = Dict(kw)
# add to the data array
pdict = plotly_series(d)
typ = pop!(pdict, :type)
gt = PlotlyJS.GenericTrace(typ; pdict...)
push!(plt.o.data, gt)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.addtraces!(plt.o, gt)
end
push!(plt.seriesargs, d)
plt
end
# ---------------------------------------------------------------------------
function _add_annotations{X,Y,V}(plt::Plot{PlotlyJSPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
# set or add to the annotation_list
if haskey(plt.plotargs, :annotation_list)
append!(plt.plotargs[:annotation_list], anns)
else
plt.plotargs[:annotation_list] = anns
end
end
# ----------------------------------------------------------------
function _before_update_plot(plt::Plot{PlotlyJSPackage})
end
# TODO: override this to update plot items (title, xlabel, etc) after creation
function _update_plot(plt::Plot{PlotlyJSPackage}, d::Dict)
pdict = plotly_layout(d)
plt.o.layout = PlotlyJS.Layout(pdict)
if PlotlyJS.isactive(plt.o._display)
PlotlyJS.relayout!(plt.o; pdict...)
end
end
function _update_plot_pos_size(plt::PlottingObject{PlotlyJSPackage}, d::Dict)
end
# ----------------------------------------------------------------
# accessors for x/y data
function Base.getindex(plt::Plot{PlotlyJSPackage}, i::Int)
d = plt.seriesargs[i]
d[:x], d[:y]
end
function Base.setindex!(plt::Plot{PlotlyJSPackage}, xy::Tuple, i::Integer)
d = plt.seriesargs[i]
d[:x], d[:y] = xy
plt
end
# ----------------------------------------------------------------
function _create_subplot(subplt::Subplot{PlotlyJSPackage}, isbefore::Bool)
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
true
end
function _expand_limits(lims, plt::Plot{PlotlyJSPackage}, isx::Bool)
# TODO: call expand limits for each plot data
end
function _remove_axis(plt::Plot{PlotlyJSPackage}, isx::Bool)
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
end
# ----------------------------------------------------------------
function Base.display(::PlotsDisplay, plt::Plot{PlotlyJSPackage})
dump(plt.o)
display(plt.o)
end
function Base.display(::PlotsDisplay, plt::Subplot{PlotlyJSPackage})
error()
end

View File

@ -568,6 +568,75 @@ subplotSupported(::PlotlyPackage) = true
stringsSupported(::PlotlyPackage) = true stringsSupported(::PlotlyPackage) = true
# --------------------------------------------------------------------------------------
supportedArgs(::PlotlyJSPackage) = [
:annotation,
# :axis,
:background_color,
:color_palette,
:fillrange,
:fillcolor,
:fillalpha,
:foreground_color,
:group,
:label,
:layout,
:legend,
:linecolor,
:linestyle,
:linetype,
:linewidth,
:linealpha,
:markershape,
:markercolor,
:markersize,
:markeralpha,
:markerstrokewidth,
:markerstrokecolor,
:markerstrokestyle,
:n,
:nbins,
:nc,
:nr,
# :pos,
# :smooth,
:show,
:size,
:title,
:windowtitle,
:x,
:xlabel,
:xlims,
:xticks,
:y,
:ylabel,
:ylims,
# :yrightlabel,
:yticks,
:xscale,
:yscale,
:xflip,
:yflip,
:z,
:zcolor,
:tickfont,
:guidefont,
:legendfont,
:grid,
:levels,
]
supportedAxes(::PlotlyJSPackage) = [:auto, :left]
supportedTypes(::PlotlyJSPackage) = [:none, :line, :path, :scatter, :steppre, :steppost,
:heatmap, :hist, :density, :bar, :contour, :surface, :path3d, :scatter3d,
:pie] #,, :sticks, :hexbin, :hline, :vline]
supportedStyles(::PlotlyJSPackage) = [:auto, :solid, :dash, :dot, :dashdot]
supportedMarkers(::PlotlyJSPackage) = [:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross,
:pentagon, :hexagon, :octagon, :vline, :hline] #vcat(_allMarkers, Shape)
supportedScales(::PlotlyJSPackage) = [:identity, :log10] #, :ln, :log2, :log10, :asinh, :sqrt]
subplotSupported(::PlotlyJSPackage) = true
stringsSupported(::PlotlyJSPackage) = true
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
supportedArgs(::GLVisualizePackage) = [ supportedArgs(::GLVisualizePackage) = [

View File

@ -34,10 +34,12 @@ end
@init_plotting_pkg Winston @init_plotting_pkg Winston
@init_plotting_pkg Bokeh @init_plotting_pkg Bokeh
@init_plotting_pkg Plotly @init_plotting_pkg Plotly
@init_plotting_pkg PlotlyJS
@init_plotting_pkg GR @init_plotting_pkg GR
@init_plotting_pkg GLVisualize @init_plotting_pkg GLVisualize
@init_plotting_pkg PGFPlots @init_plotting_pkg PGFPlots
include("backends/web.jl")
include("backends/supported.jl") include("backends/supported.jl")
# --------------------------------------------------------- # ---------------------------------------------------------