diff --git a/README.md b/README.md index 7e8db9bf..0bce60b6 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Please add wishlist items, bugs, or any other comments/questions to the issues l - [UnicodePlots.jl](docs/unicodeplots_examples.md) - [PyPlot.jl](docs/pyplot_examples.md) - [Immerse.jl](docs/immerse_examples.md) +- [Winston.jl](docs/winston_examples.md) ## Installation @@ -32,6 +33,7 @@ Pkg.add("Immerse") Pkg.add("UnicodePlots") Pkg.add("PyPlot") # requires python and matplotlib Pkg.clone("https://github.com/tbreloff/Qwt.jl.git") # requires pyqt and pyqwt +Pkg.add("Winston") ``` ## Use @@ -255,7 +257,7 @@ plot(rand(100,2); colors = [:red, RGB(.5,.5,0)], - [x] PyPlot.jl - [x] UnicodePlots.jl - [x] Qwt.jl -- [ ] Winston.jl +- [x] Winston.jl - [ ] GLPlot.jl - [ ] Bokeh.jl - [ ] Vega.jl diff --git a/docs/example_generation.jl b/docs/example_generation.jl index 2a02021a..e889ff65 100644 --- a/docs/example_generation.jl +++ b/docs/example_generation.jl @@ -188,6 +188,7 @@ end # generate_markdown(:gadfly) # generate_markdown(:pyplot) # generate_markdown(:immerse) +# generate_markdown(:winston) end # module diff --git a/src/backends/winston.jl b/src/backends/winston.jl index 96872fa1..db904eb7 100644 --- a/src/backends/winston.jl +++ b/src/backends/winston.jl @@ -1,7 +1,7 @@ # https://github.com/nolta/Winston.jl -# credit goes to https://github.com/jverzani for the first draft of this backend implementation +# credit goes to https://github.com/jverzani for contributing to the first draft of this backend implementation immutable WinstonPackage <: PlottingPackage end @@ -35,39 +35,68 @@ const winston_marker = Dict(:none=>".", supportedArgs(::WinstonPackage) = ARGS supportedAxes(::WinstonPackage) = [:auto, :left] supportedTypes(::WinstonPackage) = [:none, :line, :sticks, :scatter, :hist, :bar] -supportedStyles(::WinstonPackage) = vcat(:auto, keys(winston_linestyle)) -supportedMarkers(::WinstonPackage) = vcat(:auto, collect(keys(winston_marker))) +supportedStyles(::WinstonPackage) = unshift!(collect(keys(winston_linestyle)), :auto) # vcat(:auto, keys(winston_linestyle)) +supportedMarkers(::WinstonPackage) = unshift!(collect(keys(winston_marker)), :auto) # vcat(:auto, collect(keys(winston_marker))) subplotSupported(::WinstonPackage) = false # --------------------------------------------------------------------------- + +# function createWinstonFigure(d::Dict) +# # println("Creating immerse figure: ", d) +# w,h = d[:size] +# figidx = Winston.figure(; name = d[:windowtitle], width = w, height = h) +# Winston.Figure(figidx) +# end + + + function plot(pkg::WinstonPackage; kw...) d = Dict(kw) - # TODO: create the window/canvas/context that is the plot within the backend (call it `o`) - # TODO: initialize the plot... title, xlabel, bgcolor, etc - o = Winston.FramedPlot() + # bgcolor - # add the title, axis labels, and theme - Winston.setattr(o, "xlabel", d[:xlabel]) - Winston.setattr(o, "ylabel", d[:ylabel]) - Winston.setattr(o, "title", d[:title]) + # create a new window + # the call to figure does a few things here: + # get a new unique id + # create a new GtkWindow (or Tk?) + w,h = d[:size] + figidx = Winston.figure(; name = d[:windowtitle], width = w, height = h) - # TODO: add the legend? + # skip the current fig stuff... just grab the fig directly + fig = Winston._display.figs[figidx] - Plot(o, pkg, 0, d, Dict[]) + # overwrite the placeholder FramedPlot with our own + fig.plot = Winston.FramedPlot(title = d[:title], xlabel = d[:xlabel], ylabel = d[:ylabel]) + + # # using the figure index returned from Winston.figure, make this plot current and get the + # # Figure object (fields: window::GtkWindow and plot::FramedPlot) + # Winston.switchfig(Winston._display, figidx) + # fig = Winston.curfig(Winston._display) + # Winston._pwinston = fig.plot + + + + # Winston.setattr(fig.plot, "xlabel", d[:xlabel]) + # Winston.setattr(fig.plot, "ylabel", d[:ylabel]) + # Winston.setattr(fig.plot, "title", d[:title]) + + Plot((fig, figidx), pkg, 0, d, Dict[]) end copy_remove(d::Dict, s::Symbol) = delete!(copy(d), s) function addRegressionLineWinston(d::Dict) xs, ys = regressionXY(d[:x], d[:y]) - Winston.add(plt.o, Winston.Curve(xs, ys, kind="dotted")) + Winston.add(plt.o.plot, Winston.Curve(xs, ys, kind="dotted")) end function plot!(::WinstonPackage, plt::Plot; kw...) d = Dict(kw) - # TODO: add one series to the underlying package + + # make this figure current + fig, figidx = plt.o + Winston.switchfig(Winston._display, figidx) # until we call it normally, do the hack if d[:linetype] == :bar @@ -94,10 +123,15 @@ function plot!(::WinstonPackage, plt::Plot; kw...) ## lintype :line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hexbin, :hist, :bar if d[:linetype] == :none - Winston.add(plt.o, Winston.Points(d[:x], d[:y]; copy_remove(e, :kind)...)) + Winston.add(fig.plot, Winston.Points(d[:x], d[:y]; copy_remove(e, :kind)...)) elseif d[:linetype] == :line - Winston.add(plt.o, Winston.Curve(d[:x], d[:y]; e...)) + Winston.add(fig.plot, Winston.Curve(d[:x], d[:y]; e...)) + + elseif d[:linetype] == :scatter + if d[:marker] == :none + d[:marker] = :ellipse + end # elseif d[:linetype] == :step # fn = Winston.XXX @@ -106,7 +140,7 @@ function plot!(::WinstonPackage, plt::Plot; kw...) # fn = Winston.XXX elseif d[:linetype] == :sticks - Winston.add(plt.o, Winston.Stems(d[:x], d[:y]; e...)) + Winston.add(fig.plot, Winston.Stems(d[:x], d[:y]; e...)) # elseif d[:linetype] == :dots # fn = Winston.XXX @@ -119,17 +153,20 @@ function plot!(::WinstonPackage, plt::Plot; kw...) elseif d[:linetype] == :hist hst = hist(d[:y], d[:nbins]) - Winston.add(plt.o, Winston.Histogram(hst...; copy_remove(e, :nbins)...)) + Winston.add(fig.plot, Winston.Histogram(hst...; copy_remove(e, :nbins)...)) # elseif d[:linetype] == :bar # # fn = Winston.XXX + else + error("linetype $(d[:linetype]) not supported by Winston.") + end # marker if d[:marker] != :none - Winston.add(plt.o, Winston.Points(d[:x], d[:y]; copy_remove(e, :kind)...)) + Winston.add(fig.plot, Winston.Points(d[:x], d[:y]; copy_remove(e, :kind)...)) end @@ -137,19 +174,32 @@ function plot!(::WinstonPackage, plt::Plot; kw...) d[:reg] && d[:linetype] != :hist && addRegressionLineWinston(d) push!(plt.seriesargs, d) + println("DONE HERE ", figidx) plt end function Base.display(::WinstonPackage, plt::Plot) - Winston.display(plt.o) + # recreate the legend + fig, figidx = plt.o + println("before legend") + Winston.legend(fig.plot, [sd[:label] for sd in plt.seriesargs]) + println("after legend") + + # display the Figure + display(fig) + + # display(plt.o.window) + + # # show it + # Winston.display(plt.o.plot) end # ------------------------------- function savepng(::WinstonPackage, plt::PlottingObject, fn::String; kw...) f = open(fn, "w") - writemime(f, "image/png", plt.o) + writemime(f, "image/png", plt.o.plot) close(f) end diff --git a/src/plotter.jl b/src/plotter.jl index 0aecaeb5..86cf6c95 100644 --- a/src/plotter.jl +++ b/src/plotter.jl @@ -5,6 +5,7 @@ include("backends/gadfly.jl") include("backends/unicodeplots.jl") include("backends/pyplot.jl") include("backends/immerse.jl") +include("backends/winston.jl") # --------------------------------------------------------- @@ -21,7 +22,7 @@ Base.display(pkg::PlottingPackage, subplt::Subplot) = error("display($pkg, subpl # --------------------------------------------------------- -const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse] +const BACKENDS = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse, :winston] const INITIALIZED_BACKENDS = Set{Symbol}() backends() = BACKENDS @@ -32,6 +33,7 @@ function backend(sym::Symbol) sym == :unicodeplots && return UnicodePlotsPackage() sym == :pyplot && return PyPlotPackage() sym == :immerse && return ImmersePackage() + sym == :winston && return WinstonPackage() error("Unsupported backend $sym") end @@ -65,6 +67,10 @@ function pickDefaultBackend() Pkg.installed("UnicodePlots") return CurrentBackend(:unicodeplots) end + try + Pkg.installed("Winston") + return CurrentBackend(:winston) + end warn("You don't have any of the supported backends installed! Chose from ", backends()) return CurrentBackend(:gadfly) end @@ -124,6 +130,14 @@ function plotter() error("Couldn't import Immerse. Install it with: Pkg.add(\"Immerse\")") end + elseif currentBackendSymbol == :winston + try + @eval import Winston + @eval export Winston + catch + error("Couldn't import Winston. Install it with: Pkg.add(\"Winston\")") + end + else error("Unknown plotter $currentBackendSymbol. Choose from: $BACKENDS") end @@ -150,6 +164,8 @@ function plotter!(modname) CURRENT_BACKEND.pkg = PyPlotPackage() elseif modname == :immerse CURRENT_BACKEND.pkg = ImmersePackage() + elseif modname == :winston + CURRENT_BACKEND.pkg = WinstonPackage() else error("Unknown plotter $modname. Choose from: $BACKENDS") end