Plots.jl/src/plotter.jl
2015-10-19 14:11:22 -04:00

227 lines
6.5 KiB
Julia

immutable GadflyPackage <: PlottingPackage end
immutable ImmersePackage <: PlottingPackage end
immutable PyPlotPackage <: PlottingPackage end
immutable QwtPackage <: PlottingPackage end
immutable UnicodePlotsPackage <: PlottingPackage end
immutable WinstonPackage <: PlottingPackage end
typealias GadflyOrImmerse @compat(Union{GadflyPackage, ImmersePackage})
export
gadfly,
immerse,
pyplot,
qwt,
unicodeplots,
winston
gadfly() = backend(:gadfly)
immerse() = backend(:immerse)
pyplot() = backend(:pyplot)
qwt() = backend(:qwt)
unicodeplots() = backend(:unicodeplots)
winston() = backend(:winston)
include("backends/supported.jl")
include("backends/qwt.jl")
include("backends/gadfly.jl")
include("backends/unicodeplots.jl")
include("backends/pyplot.jl")
include("backends/immerse.jl")
include("backends/winston.jl")
# ---------------------------------------------------------
plot(pkg::PlottingPackage; kw...) = error("plot($pkg; kw...) is not implemented")
plot!(pkg::PlottingPackage, plt::Plot; kw...) = error("plot!($pkg, plt; kw...) is not implemented")
updatePlotItems(pkg::PlottingPackage, plt::Plot, d::Dict) = error("updatePlotItems($pkg, plt, d) is not implemented")
# Base.display(pkg::PlottingPackage, plt::Plot) = error("display($pkg, plt) is not implemented")
subplot(pkg::PlottingPackage; kw...) = error("subplot($pkg; kw...) is not implemented")
subplot!(pkg::PlottingPackage, subplt::Subplot; kw...) = error("subplot!($pkg, subplt; kw...) is not implemented")
# Base.display(pkg::PlottingPackage, subplt::Subplot) = error("display($pkg, subplt) is not implemented")
# ---------------------------------------------------------
const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse, :winston]
const INITIALIZED_BACKENDS = Set{Symbol}()
backends() = BACKENDS
function backendInstance(sym::Symbol)
sym == :qwt && return QwtPackage()
sym == :gadfly && return GadflyPackage()
sym == :unicodeplots && return UnicodePlotsPackage()
sym == :pyplot && return PyPlotPackage()
sym == :immerse && return ImmersePackage()
sym == :winston && return WinstonPackage()
error("Unsupported backend $sym")
end
type CurrentBackend
sym::Symbol
pkg::PlottingPackage
end
CurrentBackend(sym::Symbol) = CurrentBackend(sym, backendInstance(sym))
# ---------------------------------------------------------
function pickDefaultBackend()
try
if Pkg.installed("Immerse") != nothing
return CurrentBackend(:immerse)
end
end
try
if Pkg.installed("Qwt") != nothing
return CurrentBackend(:qwt)
end
end
try
if Pkg.installed("PyPlot") != nothing
return CurrentBackend(:pyplot)
end
end
try
if Pkg.installed("Gadfly") != nothing
return CurrentBackend(:gadfly)
end
end
try
if Pkg.installed("UnicodePlots") != nothing
return CurrentBackend(:unicodeplots)
end
end
try
if Pkg.installed("Winston") != nothing
return CurrentBackend(:winston)
end
end
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)
# ---------------------------------------------------------
"""
Returns the current plotting package name. Initializes package on first call.
"""
function backend()
# error()
currentBackendSymbol = CURRENT_BACKEND.sym
if !(currentBackendSymbol in INITIALIZED_BACKENDS)
# initialize
println("[Plots.jl] Initializing backend: ", CURRENT_BACKEND.sym)
if currentBackendSymbol == :qwt
try
@eval import Qwt
@eval export Qwt
catch err
warn("Couldn't import Qwt. Install it with: Pkg.clone(\"https://github.com/tbreloff/Qwt.jl.git\")\n (Note: also requires pyqt and pyqwt).")
rethrow(err)
end
elseif currentBackendSymbol == :gadfly
try
@eval import Gadfly, Compose, DataFrames
@eval export Gadfly, Compose, DataFrames
@eval include(joinpath(Pkg.dir("Plots"), "src", "backends", "gadfly_shapes.jl"))
catch err
warn("Couldn't import Gadfly. Install it with: Pkg.add(\"Gadfly\").")
rethrow(err)
end
elseif currentBackendSymbol == :unicodeplots
try
@eval import UnicodePlots
@eval export UnicodePlots
catch err
warn("Couldn't import UnicodePlots. Install it with: Pkg.add(\"UnicodePlots\").")
rethrow(err)
end
elseif currentBackendSymbol == :pyplot
try
@eval import PyPlot
@eval export PyPlot
@eval const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors"))
if !isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
PyPlot.ioff()
end
catch err
warn("Couldn't import PyPlot. Install it with: Pkg.add(\"PyPlot\").")
rethrow(err)
end
elseif currentBackendSymbol == :immerse
try
@eval import Immerse, Gadfly, Compose, Gtk
@eval export Immerse, Gadfly, Compose, Gtk
@eval include(joinpath(Pkg.dir("Plots"), "src", "backends", "gadfly_shapes.jl"))
catch err
# error("Couldn't import Immerse. Install it with: Pkg.add(\"Immerse\").\n Error: ", err)
warn("Couldn't import Immerse. Install it with: Pkg.add(\"Immerse\").")
rethrow(err)
end
elseif currentBackendSymbol == :winston
try
@eval ENV["WINSTON_OUTPUT"] = "gtk"
@eval import Winston, Gtk
@eval export Winston, Gtk
catch err
warn("Couldn't import Winston. Install it with: Pkg.add(\"Winston\").")
rethrow(err)
end
else
error("Unknown backend $currentBackendSymbol. Choose from: $BACKENDS")
end
push!(INITIALIZED_BACKENDS, currentBackendSymbol)
end
CURRENT_BACKEND.pkg
end
"""
Set the plot backend. Choose from: :qwt, :gadfly, :unicodeplots
"""
function backend(modname)
# set the PlottingPackage
if modname == :qwt
CURRENT_BACKEND.pkg = QwtPackage()
elseif modname == :gadfly
CURRENT_BACKEND.pkg = GadflyPackage()
elseif modname == :unicodeplots
CURRENT_BACKEND.pkg = UnicodePlotsPackage()
elseif modname == :pyplot
CURRENT_BACKEND.pkg = PyPlotPackage()
elseif modname == :immerse
CURRENT_BACKEND.pkg = ImmersePackage()
elseif modname == :winston
CURRENT_BACKEND.pkg = WinstonPackage()
else
error("Unknown backend $modname. Choose from: $BACKENDS")
end
# update the symbol
CURRENT_BACKEND.sym = modname
# println("[Plots.jl] Switched to backend: ", modname)
# return the package
CURRENT_BACKEND.pkg
end