working on bokeh backend
This commit is contained in:
parent
cca263fb2b
commit
5f85ac01f7
103
src/backends/bokeh.jl
Normal file
103
src/backends/bokeh.jl
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
# https://github.com/bokeh/Bokeh.jl
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function plot(pkg::BokehPackage; kw...)
|
||||||
|
d = Dict(kw)
|
||||||
|
|
||||||
|
dumpdict(d, "plot", true)
|
||||||
|
|
||||||
|
# TODO: create the window/canvas/context that is the plot within the backend (call it `o`)
|
||||||
|
# TODO: initialize the plot... title, xlabel, bgcolor, etc
|
||||||
|
|
||||||
|
datacolumns = Bokeh.BokehDataSet[]
|
||||||
|
tools = Bokeh.tools()
|
||||||
|
filename = tempname() * ".html"
|
||||||
|
title = d[:title]
|
||||||
|
w, h = d[:size]
|
||||||
|
xaxis_type = :auto
|
||||||
|
yaxis_type = :auto
|
||||||
|
# legend = d[:legend] ? xxxx : nothing
|
||||||
|
legend = nothing
|
||||||
|
bplt = Bokeh.Plot(datacolumns, tools, filename, title, w, h, xaxis_type, yaxis_type, legend)
|
||||||
|
|
||||||
|
Plot(bplt, pkg, 0, d, Dict[])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function plot!(::BokehPackage, plt::Plot; kw...)
|
||||||
|
d = Dict(kw)
|
||||||
|
|
||||||
|
dumpdict(d, "plot!", true)
|
||||||
|
|
||||||
|
# TODO: add one series to the underlying package
|
||||||
|
|
||||||
|
|
||||||
|
push!(plt.seriesargs, d)
|
||||||
|
plt
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# TODO: override this to update plot items (title, xlabel, etc) after creation
|
||||||
|
function updatePlotItems(plt::Plot{BokehPackage}, d::Dict)
|
||||||
|
end
|
||||||
|
|
||||||
|
function updatePositionAndSize(plt::PlottingObject{BokehPackage}, d::Dict)
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# accessors for x/y data
|
||||||
|
|
||||||
|
function Base.getindex(plt::Plot{BokehPackage}, i::Int)
|
||||||
|
# TODO
|
||||||
|
# series = plt.o.lines[i]
|
||||||
|
# series.x, series.y
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.setindex!(plt::Plot{BokehPackage}, xy::Tuple, i::Integer)
|
||||||
|
# TODO
|
||||||
|
# series = plt.o.lines[i]
|
||||||
|
# series.x, series.y = xy
|
||||||
|
plt
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
function addAnnotations{X,Y,V}(plt::Plot{BokehPackage}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
|
for ann in anns
|
||||||
|
# TODO: add the annotation to the plot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
function buildSubplotObject!(subplt::Subplot{BokehPackage})
|
||||||
|
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function expandLimits!(lims, plt::Plot{BokehPackage}, isx::Bool)
|
||||||
|
# TODO: call expand limits for each plot data
|
||||||
|
end
|
||||||
|
|
||||||
|
function handleLinkInner(plt::Plot{BokehPackage}, isx::Bool)
|
||||||
|
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{BokehPackage})
|
||||||
|
# TODO: write a png to io
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.display(::PlotsDisplay, plt::Plot{BokehPackage})
|
||||||
|
# TODO: display/show the plot
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.display(::PlotsDisplay, plt::Subplot{BokehPackage})
|
||||||
|
# TODO: display/show the subplot
|
||||||
|
end
|
||||||
@ -233,10 +233,6 @@ function buildSubplotObject!(subplt::Subplot{QwtPackage}, isbefore::Bool)
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
function handleLinkInner(plt::Plot{QwtPackage}, isx::Bool)
|
|
||||||
warn("handleLinkInner isn't implemented for qwt")
|
|
||||||
end
|
|
||||||
|
|
||||||
function expandLimits!(lims, plt::Plot{QwtPackage}, isx::Bool)
|
function expandLimits!(lims, plt::Plot{QwtPackage}, isx::Bool)
|
||||||
for series in plt.o.lines
|
for series in plt.o.lines
|
||||||
expandLimits!(lims, isx ? series.x : series.y)
|
expandLimits!(lims, isx ? series.x : series.y)
|
||||||
|
|||||||
@ -310,4 +310,67 @@ supportedScales(::WinstonPackage) = [:identity, :log10]
|
|||||||
subplotSupported(::WinstonPackage) = false
|
subplotSupported(::WinstonPackage) = false
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
supportedArgs(::BokehPackage) = [
|
||||||
|
# :annotation,
|
||||||
|
# :axis,
|
||||||
|
# :background_color,
|
||||||
|
# :color,
|
||||||
|
# :color_palette,
|
||||||
|
# :fillrange,
|
||||||
|
# :fillcolor,
|
||||||
|
# :fillopacity,
|
||||||
|
# :foreground_color,
|
||||||
|
# :group,
|
||||||
|
# :label,
|
||||||
|
# :layout,
|
||||||
|
# :legend,
|
||||||
|
# :linestyle,
|
||||||
|
# :linetype,
|
||||||
|
# :linewidth,
|
||||||
|
# :lineopacity,
|
||||||
|
# :markershape,
|
||||||
|
# :markercolor,
|
||||||
|
# :markersize,
|
||||||
|
# :markeropacity,
|
||||||
|
# :n,
|
||||||
|
# :nbins,
|
||||||
|
# :nc,
|
||||||
|
# :nr,
|
||||||
|
# :pos,
|
||||||
|
# :smooth,
|
||||||
|
# :show,
|
||||||
|
# :size,
|
||||||
|
# :title,
|
||||||
|
# :windowtitle,
|
||||||
|
# :x,
|
||||||
|
# :xlabel,
|
||||||
|
# :xlims,
|
||||||
|
# :xticks,
|
||||||
|
# :y,
|
||||||
|
# :ylabel,
|
||||||
|
# :ylims,
|
||||||
|
# :yrightlabel,
|
||||||
|
# :yticks,
|
||||||
|
# :xscale,
|
||||||
|
# :yscale,
|
||||||
|
# :xflip,
|
||||||
|
# :yflip,
|
||||||
|
# :z,
|
||||||
|
# :tickfont,
|
||||||
|
# :guidefont,
|
||||||
|
# :legendfont,
|
||||||
|
# :grid,
|
||||||
|
# :surface,
|
||||||
|
# :nlevels,
|
||||||
|
]
|
||||||
|
supportedAxes(::BokehPackage) = [:auto, :left]
|
||||||
|
supportedTypes(::BokehPackage) = [:none] #, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :contour]
|
||||||
|
supportedStyles(::BokehPackage) = [:auto, :solid] #, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
|
supportedMarkers(::BokehPackage) = [:none, :auto] #vcat(_allMarkers, Shape)
|
||||||
|
supportedScales(::BokehPackage) = [:identity] #, :log, :log2, :log10, :asinh, :sqrt]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -83,12 +83,46 @@ end
|
|||||||
function updatePlotItems(plt::Plot{[PkgName]Package}, d::Dict)
|
function updatePlotItems(plt::Plot{[PkgName]Package}, d::Dict)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function updatePositionAndSize(plt::PlottingObject{[PkgName]Package}, d::Dict)
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# accessors for x/y data
|
||||||
|
|
||||||
|
function Base.getindex(plt::Plot{[PkgName]Package}, i::Int)
|
||||||
|
series = plt.o.lines[i]
|
||||||
|
series.x, series.y
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.setindex!(plt::Plot{[PkgName]Package}, xy::Tuple, i::Integer)
|
||||||
|
series = plt.o.lines[i]
|
||||||
|
series.x, series.y = xy
|
||||||
|
plt
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
function addAnnotations{X,Y,V}(plt::Plot{[PkgName]Package}, anns::AVec{@compat(Tuple{X,Y,V})})
|
||||||
|
for ann in anns
|
||||||
|
# TODO: add the annotation to the plot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function buildSubplotObject!(subplt::Subplot{[PkgName]Package})
|
function buildSubplotObject!(subplt::Subplot{[PkgName]Package})
|
||||||
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
# TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function expandLimits!(lims, plt::Plot{[PkgName]Package}, isx::Bool)
|
||||||
|
# TODO: call expand limits for each plot data
|
||||||
|
end
|
||||||
|
|
||||||
|
function handleLinkInner(plt::Plot{[PkgName]Package}, isx::Bool)
|
||||||
|
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
||||||
|
end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{[PkgName]Package})
|
function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{[PkgName]Package})
|
||||||
|
|||||||
@ -6,6 +6,7 @@ immutable PyPlotPackage <: PlottingPackage end
|
|||||||
immutable QwtPackage <: PlottingPackage end
|
immutable QwtPackage <: PlottingPackage end
|
||||||
immutable UnicodePlotsPackage <: PlottingPackage end
|
immutable UnicodePlotsPackage <: PlottingPackage end
|
||||||
immutable WinstonPackage <: PlottingPackage end
|
immutable WinstonPackage <: PlottingPackage end
|
||||||
|
immutable BokehPackage <: PlottingPackage end
|
||||||
|
|
||||||
typealias GadflyOrImmerse @compat(Union{GadflyPackage, ImmersePackage})
|
typealias GadflyOrImmerse @compat(Union{GadflyPackage, ImmersePackage})
|
||||||
|
|
||||||
@ -14,7 +15,8 @@ export
|
|||||||
immerse,
|
immerse,
|
||||||
pyplot,
|
pyplot,
|
||||||
qwt,
|
qwt,
|
||||||
unicodeplots
|
unicodeplots,
|
||||||
|
bokeh
|
||||||
# winston
|
# winston
|
||||||
|
|
||||||
gadfly() = backend(:gadfly)
|
gadfly() = backend(:gadfly)
|
||||||
@ -22,6 +24,7 @@ immerse() = backend(:immerse)
|
|||||||
pyplot() = backend(:pyplot)
|
pyplot() = backend(:pyplot)
|
||||||
qwt() = backend(:qwt)
|
qwt() = backend(:qwt)
|
||||||
unicodeplots() = backend(:unicodeplots)
|
unicodeplots() = backend(:unicodeplots)
|
||||||
|
bokeh() = backend(:bokeh)
|
||||||
# winston() = backend(:winston)
|
# winston() = backend(:winston)
|
||||||
|
|
||||||
backend_name(::GadflyPackage) = :gadfly
|
backend_name(::GadflyPackage) = :gadfly
|
||||||
@ -29,6 +32,7 @@ backend_name(::ImmersePackage) = :immerse
|
|||||||
backend_name(::PyPlotPackage) = :pyplot
|
backend_name(::PyPlotPackage) = :pyplot
|
||||||
backend_name(::UnicodePlotsPackage) = :unicodeplots
|
backend_name(::UnicodePlotsPackage) = :unicodeplots
|
||||||
backend_name(::QwtPackage) = :qwt
|
backend_name(::QwtPackage) = :qwt
|
||||||
|
backend_name(::BokehPackage) = :bokeh
|
||||||
|
|
||||||
include("backends/supported.jl")
|
include("backends/supported.jl")
|
||||||
|
|
||||||
@ -38,6 +42,7 @@ include("backends/unicodeplots.jl")
|
|||||||
include("backends/pyplot.jl")
|
include("backends/pyplot.jl")
|
||||||
include("backends/immerse.jl")
|
include("backends/immerse.jl")
|
||||||
include("backends/winston.jl")
|
include("backends/winston.jl")
|
||||||
|
include("backends/bokeh.jl")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
@ -57,7 +62,7 @@ subplot!(pkg::PlottingPackage, subplt::Subplot; kw...) = error("subplot!($pkg, s
|
|||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse]
|
const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse, :bokeh]
|
||||||
const INITIALIZED_BACKENDS = Set{Symbol}()
|
const INITIALIZED_BACKENDS = Set{Symbol}()
|
||||||
backends() = BACKENDS
|
backends() = BACKENDS
|
||||||
|
|
||||||
@ -69,6 +74,7 @@ function backendInstance(sym::Symbol)
|
|||||||
sym == :pyplot && return PyPlotPackage()
|
sym == :pyplot && return PyPlotPackage()
|
||||||
sym == :immerse && return ImmersePackage()
|
sym == :immerse && return ImmersePackage()
|
||||||
sym == :winston && return WinstonPackage()
|
sym == :winston && return WinstonPackage()
|
||||||
|
sym == :bokeh && return BokehPackage()
|
||||||
error("Unsupported backend $sym")
|
error("Unsupported backend $sym")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -107,6 +113,11 @@ function pickDefaultBackend()
|
|||||||
return CurrentBackend(:unicodeplots)
|
return CurrentBackend(:unicodeplots)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
try
|
||||||
|
if Pkg.installed("Bokeh") != nothing
|
||||||
|
return CurrentBackend(:bokeh)
|
||||||
|
end
|
||||||
|
end
|
||||||
try
|
try
|
||||||
if Pkg.installed("Winston") != nothing
|
if Pkg.installed("Winston") != nothing
|
||||||
return CurrentBackend(:winston)
|
return CurrentBackend(:winston)
|
||||||
@ -115,8 +126,6 @@ function pickDefaultBackend()
|
|||||||
warn("You don't have any of the supported backends installed! Chose from ", backends())
|
warn("You don't have any of the supported backends installed! Chose from ", backends())
|
||||||
return CurrentBackend(:gadfly)
|
return CurrentBackend(:gadfly)
|
||||||
end
|
end
|
||||||
# const CURRENT_BACKEND = pickDefaultBackend()
|
|
||||||
# println("[Plots.jl] Default backend: ", CURRENT_BACKEND.sym)
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
@ -125,7 +134,6 @@ end
|
|||||||
Returns the current plotting package name. Initializes package on first call.
|
Returns the current plotting package name. Initializes package on first call.
|
||||||
"""
|
"""
|
||||||
function backend()
|
function backend()
|
||||||
# error()
|
|
||||||
|
|
||||||
currentBackendSymbol = CURRENT_BACKEND.sym
|
currentBackendSymbol = CURRENT_BACKEND.sym
|
||||||
if !(currentBackendSymbol in INITIALIZED_BACKENDS)
|
if !(currentBackendSymbol in INITIALIZED_BACKENDS)
|
||||||
@ -199,6 +207,15 @@ function backend()
|
|||||||
rethrow(err)
|
rethrow(err)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif currentBackendSymbol == :bokeh
|
||||||
|
try
|
||||||
|
@eval import Bokeh
|
||||||
|
@eval export Bokeh
|
||||||
|
catch err
|
||||||
|
warn("Couldn't import Bokeh. Install it with: Pkg.add(\"Bokeh\").")
|
||||||
|
rethrow(err)
|
||||||
|
end
|
||||||
|
|
||||||
elseif currentBackendSymbol == :winston
|
elseif currentBackendSymbol == :winston
|
||||||
warn("Winston support is deprecated and broken. Try another backend: $BACKENDS")
|
warn("Winston support is deprecated and broken. Try another backend: $BACKENDS")
|
||||||
try
|
try
|
||||||
@ -243,6 +260,8 @@ function backend(modname)
|
|||||||
CURRENT_BACKEND.pkg = ImmersePackage()
|
CURRENT_BACKEND.pkg = ImmersePackage()
|
||||||
elseif modname == :winston
|
elseif modname == :winston
|
||||||
CURRENT_BACKEND.pkg = WinstonPackage()
|
CURRENT_BACKEND.pkg = WinstonPackage()
|
||||||
|
elseif modname == :bokeh
|
||||||
|
CURRENT_BACKEND.pkg = BokehPackage()
|
||||||
else
|
else
|
||||||
error("Unknown backend $modname. Choose from: $BACKENDS")
|
error("Unknown backend $modname. Choose from: $BACKENDS")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -283,8 +283,8 @@ end
|
|||||||
debugshow(x) = show(x)
|
debugshow(x) = show(x)
|
||||||
debugshow(x::AbstractArray) = print(summary(x))
|
debugshow(x::AbstractArray) = print(summary(x))
|
||||||
|
|
||||||
function dumpdict(d::Dict, prefix = "")
|
function dumpdict(d::Dict, prefix = "", alwaysshow = false)
|
||||||
_debugMode.on || return
|
_debugMode.on || alwaysshow || return
|
||||||
println()
|
println()
|
||||||
if prefix != ""
|
if prefix != ""
|
||||||
println(prefix, ":")
|
println(prefix, ":")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user