working on display/writemime overhaul
This commit is contained in:
parent
f8fb473981
commit
eced15b712
31
src/Plots.jl
31
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, "<p>")
|
||||
# png = MIME("image/png")
|
||||
# print(io, "<img src=\"data:image/png; base64,", base64encode(writemime, png), "\" />")
|
||||
# end
|
||||
|
||||
|
||||
# override the REPL display
|
||||
Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::PlottingObject) = display(PlotsDisplay(), plt)
|
||||
|
||||
|
||||
function __init__()
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
14
src/types.jl
14
src/types.jl
@ -2,12 +2,14 @@
|
||||
typealias AVec AbstractVector
|
||||
typealias AMat AbstractMatrix
|
||||
|
||||
abstract PlottingObject
|
||||
abstract PlottingPackage
|
||||
immutable PlotsDisplay <: Display end
|
||||
|
||||
type Plot <: PlottingObject
|
||||
abstract PlottingPackage
|
||||
abstract PlottingObject{T<:PlottingPackage}
|
||||
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user