diff --git a/src/Plots.jl b/src/Plots.jl index ce643933..1e4858e7 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -36,6 +36,10 @@ export ohlc, ohlc!, + title!, + xlabel!, + ylabel!, + savepng, backends, @@ -86,12 +90,35 @@ ohlc(args...; kw...) = plot(args...; kw..., linetype = :ohlc) ohlc!(args...; kw...) = plot!(args...; kw..., linetype = :ohlc) +title!(s::AbstractString) = plot!(title = s) +xlabel!(s::AbstractString) = plot!(xlabel = s) +ylabel!(s::AbstractString) = plot!(ylabel = s) + +title!(plt::Plot, s::AbstractString) = plot!(plt; title = s) +xlabel!(plt::Plot, s::AbstractString) = plot!(plt; xlabel = s) +ylabel!(plt::Plot, s::AbstractString) = plot!(plt; ylabel = s) + + # --------------------------------------------------------- savepng(args...; kw...) = savepng(currentPlot(), args...; kw...) -savepng(plt::PlottingObject, args...; kw...) = savepng(plt.plotter, plt, args...; kw...) -savepng(::PlottingPackage, plt::PlottingObject, fn::AbstractString, args...) = error("unsupported") # fallback so multiple dispatch doesn't get confused if it's missing +savepng(plt::PlottingObject, fn::AbstractString; kw...) = (io = open(fn); writemime(io, MIME"image/png", plt); close(io)) +# savepng(plt::PlottingObject, args...; kw...) = savepng(plt.plotter, plt, args...; kw...) +# savepng(::PlottingPackage, plt::PlottingObject, fn::AbstractString, args...) = error("unsupported") # fallback so multiple dispatch doesn't get confused if it's missing + +# function Base.writemime(io::IO, ::MIME"image/png", plt::Plot) + + +# function Base.writemime(io::IO, ::MIME"text/html", plt::Plot) +# # print(io, "
")
+# png = MIME("image/png")
+# print(io, "")
+# end
+
+
+# override the REPL display
+Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::PlottingObject) = display(PlotsDisplay(), plt)
function __init__()
diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl
index 46156778..8099597d 100644
--- a/src/backends/gadfly.jl
+++ b/src/backends/gadfly.jl
@@ -210,24 +210,52 @@ function plot!(::GadflyPackage, plt::Plot; kw...)
plt
end
+
+function findGuideAndSet(plt::Plot, t::DataType, s::AbstractString)
+ for guide in plt.o.guides
+ if isa(guide, t)
+ guide.label = s
+ end
+ end
+end
+
+function updatePlotItems(::GadflyPackage, plt::Plot, d::Dict)
+ haskey(d, :title) && findGuideAndSet(plt, Gadfly.Guide.title, d[:title])
+ haskey(d, :xlabel) && findGuideAndSet(plt, Gadfly.Guide.xlabel, d[:xlabel])
+ haskey(d, :ylabel) && findGuideAndSet(plt, Gadfly.Guide.ylabel, d[:ylabel])
+end
+
function setGadflyDisplaySize(w,h)
Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
end
-function Base.display(::GadflyPackage, plt::Plot)
+# function Base.display(::GadflyPackage, plt::Plot)
+# # function Base.writemime(io::IO, ::MIME")
+# setGadflyDisplaySize(plt.initargs[:size]...)
+# display(plt.o)
+# end
+
+function Base.display(::PlotsDisplay, plt::Plot{GadflyPackage})
setGadflyDisplaySize(plt.initargs[:size]...)
display(plt.o)
end
# -------------------------------
-function savepng(::GadflyPackage, plt::PlottingObject, fn::AbstractString;
- w = plt.initargs[:size][1] * Gadfly.px, # 6 * Gadfly.inch,
- h = plt.initargs[:size][2] * Gadfly.px) # 4 * Gadfly.inch)
- o = getGadflyContext(plt.plotter, plt)
- Gadfly.draw(Gadfly.PNG(fn, w, h), o)
-end
+# function savepng(::GadflyPackage, plt::PlottingObject, fn::AbstractString;
+# w = plt.initargs[:size][1] * Gadfly.px, # 6 * Gadfly.inch,
+# h = plt.initargs[:size][2] * Gadfly.px) # 4 * Gadfly.inch)
+# o = getGadflyContext(plt.plotter, plt)
+# Gadfly.draw(Gadfly.PNG(fn, w, h), o)
+# end
+function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{GadflyPackage})
+ # w = plt.initargs[:size][1] * Gadfly.px, # 6 * Gadfly.inch,
+ # h = plt.initargs[:size][2] * Gadfly.px) # 4 * Gadfly.inch)
+ gplt = getGadflyContext(plt.plotter, plt)
+ setGadflyDisplaySize(plt.initargs[:size]...)
+ Gadfly.draw(Gadfly.PNG(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt)
+end
# -------------------------------
@@ -246,12 +274,12 @@ function buildGadflySubplotContext(subplt::Subplot)
end
# create the underlying object (each backend will do this differently)
-function buildSubplotObject!(::GadflyPackage, subplt::Subplot)
+function buildSubplotObject!(subplt::Subplot{GadflyPackage})
subplt.o = nothing
end
-function Base.display(::GadflyPackage, subplt::Subplot)
+function Base.display(::PlotsDisplay, subplt::Subplot{GadflyPackage})
setGadflyDisplaySize(plt.initargs[:size]...)
display(buildGadflySubplotContext(subplt))
end
diff --git a/src/backends/immerse.jl b/src/backends/immerse.jl
index 7344a56b..1ff505d3 100644
--- a/src/backends/immerse.jl
+++ b/src/backends/immerse.jl
@@ -75,7 +75,7 @@ end
# -------------------------------
-function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
+function buildSubplotObject!(subplt::Subplot{ImmersePackage})
# create the Gtk window with vertical box vsep
d = subplt.initargs[1]
@@ -120,12 +120,6 @@ function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
end
-# # create the underlying object
-# function buildSubplotObject!(::ImmersePackage, subplt::Subplot)
-# subplt.o = (nothing, nothing)
-# end
-
-
function Base.display(::ImmersePackage, subplt::Subplot)
# display the plots by creating a fresh Immerse.Figure object from the GtkCanvas and Gadfly.Plot
diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl
index 60e768d2..8121039d 100644
--- a/src/backends/pyplot.jl
+++ b/src/backends/pyplot.jl
@@ -94,8 +94,7 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
# return linetype == :hist ? PyPlot.plt[:hist] : (linetype in (:sticks,:bar) ? PyPlot.bar : (linetype in (:heatmap,:hexbin) ? PyPlot.hexbin : PyPlot.plot))
end
-function updateAxisColors(o, fgcolor)
- ax = o[:axes][1]
+function updateAxisColors(ax, fgcolor)
for loc in ("bottom", "top", "left", "right")
ax[:spines][loc][:set_color](fgcolor)
end
@@ -108,6 +107,8 @@ function updateAxisColors(o, fgcolor)
ax[:title][:set_color](fgcolor)
end
+makePlotCurrent(plt::Plot) = PyPlot.figure(plt.o[1].o[:number])
+
# ------------------------------------------------------------------
# TODO:
@@ -125,13 +126,10 @@ function plot(pkg::PyPlotPackage; kw...)
d = Dict(kw)
w,h = map(px2inch, d[:size])
bgcolor = getPyPlotColor(d[:background_color])
- o = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96)
+ fig = PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = 96)
- PyPlot.title(d[:title])
- PyPlot.xlabel(d[:xlabel])
- PyPlot.ylabel(d[:ylabel])
-
- plt = Plot(o, pkg, 0, d, Dict[])
+ num = fig.o[:number]
+ plt = Plot((fig, num), pkg, 0, d, Dict[])
plt
end
@@ -139,6 +137,10 @@ end
function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
d = Dict(kw)
+ fig, num = plt.o
+ # PyPlot.figure(num) # makes this current
+ makePlotCurrent(plt)
+
if !(d[:linetype] in supportedTypes(pkg))
error("linetype $(d[:linetype]) is unsupported in PyPlot. Choose from: $(supportedTypes(pkg))")
end
@@ -207,13 +209,21 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
d[:serieshandle] = plotfunc(d[:x], d[:y]; extraargs...)[1]
end
- # this sets the bg color inside the grid (plt.o.o == matplotlib.Figure)
- plt.o.o[:axes][1][:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
+ # this sets the bg color inside the grid
+ fig.o[:axes][1][:set_axis_bgcolor](getPyPlotColor(plt.initargs[:background_color]))
push!(plt.seriesargs, d)
plt
end
+
+function updatePlotItems(::PyPlotPackage, plt::Plot, d::Dict)
+ makePlotCurrent(plt)
+ haskey(d, :title) && PyPlot.title(d[:title])
+ haskey(d, :xlabel) && PyPlot.xlabel(d[:xlabel])
+ haskey(d, :ylabel) && PyPlot.ylabel(d[:ylabel])
+end
+
function addPyPlotLegend(plt::Plot)
# add a legend?
# try
@@ -230,40 +240,34 @@ function addPyPlotLegend(plt::Plot)
end
function Base.display(::PyPlotPackage, plt::Plot)
+ fig, num = plt.o
+ # PyPlot.figure(num) # makes this current
+ makePlotCurrent(plt)
addPyPlotLegend(plt)
- updateAxisColors(plt.o.o, getPyPlotColor(plt.initargs[:foreground_color]))
- display(plt.o)
+ ax = fig.o[:axes][1]
+ updateAxisColors(ax, getPyPlotColor(plt.initargs[:foreground_color]))
+ display(fig)
end
# -------------------------------
function savepng(::PyPlotPackage, plt::PlottingObject, fn::AbstractString, args...)
+ fig, num = plt.o
addPyPlotLegend(plt)
f = open(fn, "w")
- writemime(f, "image/png", plt.o)
+ writemime(f, "image/png", fig)
close(f)
end
# -------------------------------
# create the underlying object (each backend will do this differently)
-function buildSubplotObject!(::PyPlotPackage, subplt::Subplot)
- # i = 0
- # rows = []
- # for rowcnt in subplt.layout.rowcounts
- # push!(rows, Qwt.hsplitter([plt.o for plt in subplt.plts[(1:rowcnt) + i]]...))
- # i += rowcnt
- # end
- # subplt.o = Qwt.vsplitter(rows...)
+function buildSubplotObject!(subplt::Subplot{PyPlotPackage})
error("unsupported")
end
function Base.display(::PyPlotPackage, subplt::Subplot)
- # for plt in subplt.plts
- # Qwt.refresh(plt.o)
- # end
- # Qwt.showwidget(subplt.o)
display(subplt.o)
end
diff --git a/src/backends/qwt.jl b/src/backends/qwt.jl
index 1d51f7b9..a5f1649f 100644
--- a/src/backends/qwt.jl
+++ b/src/backends/qwt.jl
@@ -57,6 +57,12 @@ function plot!(::QwtPackage, plt::Plot; kw...)
plt
end
+function updatePlotItems(::QwtPackage, plt::Plot, d::Dict)
+ haskey(d, :title) && Qwt.title(plt.o, d[:title])
+ haskey(d, :xlabel) && Qwt.xlabel(plt.o, d[:xlabel])
+ haskey(d, :ylabel) && Qwt.ylabel(plt.o, d[:ylabel])
+end
+
function Base.display(::QwtPackage, plt::Plot)
Qwt.refresh(plt.o)
Qwt.showwidget(plt.o)
@@ -69,7 +75,7 @@ savepng(::QwtPackage, plt::PlottingObject, fn::AbstractString, args...) = Qwt.sa
# -------------------------------
# create the underlying object (each backend will do this differently)
-function buildSubplotObject!(::QwtPackage, subplt::Subplot)
+function buildSubplotObject!(subplt::Subplot{QwtPackage})
i = 0
rows = []
for rowcnt in subplt.layout.rowcounts
diff --git a/src/backends/template.jl b/src/backends/template.jl
index 4f4d61fd..794ac94c 100644
--- a/src/backends/template.jl
+++ b/src/backends/template.jl
@@ -35,24 +35,42 @@ function plot!(::[PkgName]Package, plt::Plot; kw...)
end
-function Base.display(::[PkgName]Package, plt::Plot)
+# TODO: override this to update plot items (title, xlabel, etc) after creation
+function updatePlotItems(plt::Plot{[PkgName]Package}, d::Dict)
+end
+
+
+# function Base.display(::[PkgName]Package, plt::Plot)
+# # TODO: display/show the plot
+# end
+
+function Base.display(::PlotsDisplay, plt::Plot{[PkgName]Package})
# TODO: display/show the plot
end
+
# -------------------------------
-function savepng(::[PkgName]Package, plt::PlottingObject, fn::AbstractString; kw...)
- # TODO: save a PNG of the underlying plot/subplot object
+# function savepng(::[PkgName]Package, plt::PlottingObject, fn::AbstractString; kw...)
+# # TODO: save a PNG of the underlying plot/subplot object
+# end
+
+
+function Base.writemime(io::IO, ::MIME"image/png", plt::PlottingObject{[PkgName]Package})
+ # TODO: write a png to io
end
-
# -------------------------------
-function buildSubplotObject!(::[PkgName]Package, subplt::Subplot)
+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 Base.display(::[PkgName]Package, subplt::Subplot)
- # TODO: display/show the Subplot object
+# function Base.display(::[PkgName]Package, subplt::Subplot)
+# # TODO: display/show the Subplot object
+# end
+
+function Base.display(::PlotsDisplay, plt::Subplot{[PkgName]Package})
+ # TODO: display/show the subplot
end
diff --git a/src/plot.jl b/src/plot.jl
index d3c4996f..07e7c6c2 100644
--- a/src/plot.jl
+++ b/src/plot.jl
@@ -93,6 +93,7 @@ function plot!(plt::Plot, args...; kw...)
plot!(plt.plotter, plt; d...)
end
+ updatePlotItems(plt.plotter, plt, d)
currentPlot!(plt)
# NOTE: lets ignore the show param and effectively use the semicolon at the end of the REPL statement
@@ -104,10 +105,10 @@ function plot!(plt::Plot, args...; kw...)
plt
end
-# show/update the plot
-function Base.display(plt::PlottingObject)
- display(plt.plotter, plt)
-end
+# # show/update the plot
+# function Base.display(plt::PlottingObject)
+# display(plt.plotter, plt)
+# end
# --------------------------------------------------------------------
diff --git a/src/plotter.jl b/src/plotter.jl
index e86b2037..dcf97b7e 100644
--- a/src/plotter.jl
+++ b/src/plotter.jl
@@ -13,11 +13,12 @@ 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")
-Base.display(pkg::PlottingPackage, plt::Plot) = error("display($pkg, plt) 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")
+# Base.display(pkg::PlottingPackage, subplt::Subplot) = error("display($pkg, subplt) is not implemented")
# ---------------------------------------------------------
diff --git a/src/subplot.jl b/src/subplot.jl
index ca9591c8..8876a5fe 100644
--- a/src/subplot.jl
+++ b/src/subplot.jl
@@ -132,7 +132,7 @@ function subplot!(subplt::Subplot, args...; kw...)
# create the underlying object (each backend will do this differently)
if !subplt.initialized
- buildSubplotObject!(subplt.plotter, subplt)
+ buildSubplotObject!(subplt)
subplt.initialized = true
end
diff --git a/src/types.jl b/src/types.jl
index ef085251..68002ab4 100644
--- a/src/types.jl
+++ b/src/types.jl
@@ -2,12 +2,14 @@
typealias AVec AbstractVector
typealias AMat AbstractMatrix
-abstract PlottingObject
+immutable PlotsDisplay <: Display end
+
abstract PlottingPackage
+abstract PlottingObject{T<:PlottingPackage}
-type Plot <: PlottingObject
+type Plot{T<:PlottingPackage} <: PlottingObject{T}
o # the underlying object
- plotter::PlottingPackage
+ plotter::T
n::Int # number of series
# store these just in case
@@ -22,10 +24,10 @@ type SubplotLayout
end
-type Subplot <: PlottingObject
+type Subplot{T<:PlottingPackage} <: PlottingObject{T}
o # the underlying object
plts::Vector{Plot} # the individual plots
- plotter::PlottingPackage
+ plotter::T
p::Int # number of plots
n::Int # number of series
layout::SubplotLayout