working on bokeh backend

This commit is contained in:
Thomas Breloff 2015-11-03 13:45:23 -05:00
parent cca263fb2b
commit 5f85ac01f7
6 changed files with 227 additions and 12 deletions

103
src/backends/bokeh.jl Normal file
View 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

View File

@ -233,10 +233,6 @@ function buildSubplotObject!(subplt::Subplot{QwtPackage}, isbefore::Bool)
true
end
function handleLinkInner(plt::Plot{QwtPackage}, isx::Bool)
warn("handleLinkInner isn't implemented for qwt")
end
function expandLimits!(lims, plt::Plot{QwtPackage}, isx::Bool)
for series in plt.o.lines
expandLimits!(lims, isx ? series.x : series.y)

View File

@ -311,3 +311,66 @@ 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]

View File

@ -83,12 +83,46 @@ end
function updatePlotItems(plt::Plot{[PkgName]Package}, d::Dict)
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})
# 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{[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})

View File

@ -6,6 +6,7 @@ immutable PyPlotPackage <: PlottingPackage end
immutable QwtPackage <: PlottingPackage end
immutable UnicodePlotsPackage <: PlottingPackage end
immutable WinstonPackage <: PlottingPackage end
immutable BokehPackage <: PlottingPackage end
typealias GadflyOrImmerse @compat(Union{GadflyPackage, ImmersePackage})
@ -14,7 +15,8 @@ export
immerse,
pyplot,
qwt,
unicodeplots
unicodeplots,
bokeh
# winston
gadfly() = backend(:gadfly)
@ -22,6 +24,7 @@ immerse() = backend(:immerse)
pyplot() = backend(:pyplot)
qwt() = backend(:qwt)
unicodeplots() = backend(:unicodeplots)
bokeh() = backend(:bokeh)
# winston() = backend(:winston)
backend_name(::GadflyPackage) = :gadfly
@ -29,6 +32,7 @@ backend_name(::ImmersePackage) = :immerse
backend_name(::PyPlotPackage) = :pyplot
backend_name(::UnicodePlotsPackage) = :unicodeplots
backend_name(::QwtPackage) = :qwt
backend_name(::BokehPackage) = :bokeh
include("backends/supported.jl")
@ -38,6 +42,7 @@ include("backends/unicodeplots.jl")
include("backends/pyplot.jl")
include("backends/immerse.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}()
backends() = BACKENDS
@ -69,6 +74,7 @@ function backendInstance(sym::Symbol)
sym == :pyplot && return PyPlotPackage()
sym == :immerse && return ImmersePackage()
sym == :winston && return WinstonPackage()
sym == :bokeh && return BokehPackage()
error("Unsupported backend $sym")
end
@ -107,6 +113,11 @@ function pickDefaultBackend()
return CurrentBackend(:unicodeplots)
end
end
try
if Pkg.installed("Bokeh") != nothing
return CurrentBackend(:bokeh)
end
end
try
if Pkg.installed("Winston") != nothing
return CurrentBackend(:winston)
@ -115,8 +126,6 @@ function pickDefaultBackend()
warn("You don't have any of the supported backends installed! Chose from ", backends())
return CurrentBackend(:gadfly)
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.
"""
function backend()
# error()
currentBackendSymbol = CURRENT_BACKEND.sym
if !(currentBackendSymbol in INITIALIZED_BACKENDS)
@ -199,6 +207,15 @@ function backend()
rethrow(err)
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
warn("Winston support is deprecated and broken. Try another backend: $BACKENDS")
try
@ -243,6 +260,8 @@ function backend(modname)
CURRENT_BACKEND.pkg = ImmersePackage()
elseif modname == :winston
CURRENT_BACKEND.pkg = WinstonPackage()
elseif modname == :bokeh
CURRENT_BACKEND.pkg = BokehPackage()
else
error("Unknown backend $modname. Choose from: $BACKENDS")
end

View File

@ -283,8 +283,8 @@ end
debugshow(x) = show(x)
debugshow(x::AbstractArray) = print(summary(x))
function dumpdict(d::Dict, prefix = "")
_debugMode.on || return
function dumpdict(d::Dict, prefix = "", alwaysshow = false)
_debugMode.on || alwaysshow || return
println()
if prefix != ""
println(prefix, ":")