From 2207ae6617dff6d9495341d7a737840bcb53b9bf Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Mon, 14 Sep 2015 12:35:24 -0400 Subject: [PATCH] working on immerse --- README.md | 6 +- docs/example_generation.jl | 9 +-- src/Plots.jl | 3 +- src/args.jl | 1 + src/backends/gadfly.jl | 122 ++++++++++++++++++++++++++++++------- src/backends/immerse.jl | 68 +++++++++++++++++++++ src/plotter.jl | 23 ++++++- 7 files changed, 201 insertions(+), 31 deletions(-) create mode 100644 src/backends/immerse.jl diff --git a/README.md b/README.md index 0c3f151c..b0ebf320 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Please add wishlist items, bugs, or any other comments/questions to the issues l - [Gadfly.jl](docs/gadfly_examples.md) - [UnicodePlots.jl](docs/unicodeplots_examples.md) - [PyPlot.jl](docs/pyplot_examples.md) +- [Immerse.jl](docs/immerse_examples.md) ## Installation @@ -30,6 +31,7 @@ Pkg.add("Gadfly") Pkg.clone("https://github.com/tbreloff/Qwt.jl.git") # requires pyqt and pyqwt Pkg.add("UnicodePlots") Pkg.add("PyPlot") # requires python and matplotlib +Pkg.add("Immerse") ``` ## Use @@ -206,9 +208,9 @@ xlabel = "" ylabel = "" yrightlabel = "" reg = false -size = (800,600) +size = (600,400) pos = (0,0) -windowtitle = "" +windowtitle = "Plots.jl" screen = 1 show = true ``` diff --git a/docs/example_generation.jl b/docs/example_generation.jl index b19c8861..604256b8 100644 --- a/docs/example_generation.jl +++ b/docs/example_generation.jl @@ -131,10 +131,11 @@ end # run it! # note: generate separately so it's easy to comment out -generate_markdown(:qwt) -generate_markdown(:gadfly) -@osx_only generate_markdown(:unicodeplots) -generate_markdown(:pyplot) +# generate_markdown(:qwt) +# generate_markdown(:gadfly) +# @osx_only generate_markdown(:unicodeplots) +# generate_markdown(:pyplot) +generate_markdown(:immerse) end # module diff --git a/src/Plots.jl b/src/Plots.jl index 3e687b13..158d7083 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -33,7 +33,8 @@ export qwt!, gadfly!, unicodeplots!, - pyplot! + pyplot!, + immerse! # --------------------------------------------------------- diff --git a/src/args.jl b/src/args.jl index cda92a69..7626fcfc 100644 --- a/src/args.jl +++ b/src/args.jl @@ -40,6 +40,7 @@ PLOT_DEFAULTS[:legend] = true PLOT_DEFAULTS[:xticks] = true PLOT_DEFAULTS[:yticks] = true PLOT_DEFAULTS[:size] = (600,400) +PLOT_DEFAULTS[:windowtitle] = "Plots.jl" PLOT_DEFAULTS[:args] = [] # additional args to pass to the backend PLOT_DEFAULTS[:kwargs] = [] # additional keyword args to pass to the backend diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl index 7a292500..8eacc574 100644 --- a/src/backends/gadfly.jl +++ b/src/backends/gadfly.jl @@ -6,32 +6,56 @@ immutable GadflyPackage <: PlottingPackage end gadfly!() = plotter!(:gadfly) -# create a blank Gadfly.Plot object -function plot(pkg::GadflyPackage; kw...) +# # create a blank Gadfly.Plot object +# function plot(pkg::GadflyPackage; kw...) +# @eval import DataFrames + +# plt = Gadfly.Plot() +# plt.mapping = Dict() +# plt.data_source = DataFrames.DataFrame() +# plt.layers = plt.layers[1:0] + +# # add the title, axis labels, and theme +# d = Dict(kw) + +# plt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]), +# Gadfly.Guide.ylabel(d[:ylabel]), +# Gadfly.Guide.title(d[:title])] + +# # add the legend? +# if d[:legend] +# unshift!(plt.guides, Gadfly.Guide.manual_color_key("", AbstractString[], Color[])) +# end + +# plt.theme = Gadfly.Theme(background_color = (haskey(d, :background_color) ? d[:background_color] : colorant"white")) + +# Plot(plt, pkg, 0, d, Dict[]) +# end + +function createGadflyPlotObject(d::Dict) @eval import DataFrames - plt = Gadfly.Plot() - plt.mapping = Dict() - plt.data_source = DataFrames.DataFrame() - plt.layers = plt.layers[1:0] + gplt = Gadfly.Plot() + gplt.mapping = Dict() + gplt.data_source = DataFrames.DataFrame() + gplt.layers = gplt.layers[1:0] # add the title, axis labels, and theme - d = Dict(kw) - plt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]), + gplt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]), Gadfly.Guide.ylabel(d[:ylabel]), Gadfly.Guide.title(d[:title])] # add the legend? if d[:legend] - unshift!(plt.guides, Gadfly.Guide.manual_color_key("", AbstractString[], Color[])) + unshift!(gplt.guides, Gadfly.Guide.manual_color_key("", AbstractString[], Color[])) end - plt.theme = Gadfly.Theme(background_color = (haskey(d, :background_color) ? d[:background_color] : colorant"white")) - - Plot(plt, pkg, 0, d, Dict[]) + gplt.theme = Gadfly.Theme(background_color = (haskey(d, :background_color) ? d[:background_color] : colorant"white")) + gplt end + function getGeomFromLineType(linetype::Symbol, nbins::Int) linetype == :line && return Gadfly.Geom.line linetype == :dots && return Gadfly.Geom.point @@ -64,10 +88,7 @@ function getGeoms(linetype::Symbol, marker::Symbol, nbins::Int) end -# plot one data series -function plot!(::GadflyPackage, plt::Plot; kw...) - d = Dict(kw) - +function addGadflySeries!(gplt, d::Dict) gfargs = [] # add the Geoms @@ -88,23 +109,80 @@ function plot!(::GadflyPackage, plt::Plot; kw...) x = d[d[:linetype] == :hist ? :y : :x] # add to the legend - if length(plt.o.guides) > 0 && isa(plt.o.guides[1], Gadfly.Guide.ManualColorKey) - push!(plt.o.guides[1].labels, d[:label]) - push!(plt.o.guides[1].colors, d[:color]) + if length(gplt.guides) > 0 && isa(gplt.guides[1], Gadfly.Guide.ManualColorKey) + push!(gplt.guides[1].labels, d[:label]) + push!(gplt.guides[1].colors, d[:color]) end if d[:axis] != :left warn("Gadly only supports one y axis") end - # save the kw args - push!(plt.seriesargs, d) # add the layer to the Gadfly.Plot - prepend!(plt.o.layers, Gadfly.layer(unique(gfargs)..., d[:args]...; x = x, y = d[:y], d[:kwargs]...)) + prepend!(gplt.layers, Gadfly.layer(unique(gfargs)..., d[:args]...; x = x, y = d[:y], d[:kwargs]...)) + nothing +end + +# --------------------------------------------------------------------------- + +# create a blank Gadfly.Plot object +function plot(pkg::GadflyPackage; kw...) + d = Dict(kw) + gplt = createGadflyPlotObject(d) + Plot(gplt, pkg, 0, d, Dict[]) +end + + +# plot one data series +function plot!(::GadflyPackage, plt::Plot; kw...) + d = Dict(kw) + addGadflySeries!(plt.o, d) + push!(plt.seriesargs, d) plt end +# # plot one data series +# function plot!(::GadflyPackage, plt::Plot; kw...) +# d = Dict(kw) + +# gfargs = [] + +# # add the Geoms +# append!(gfargs, getGeoms(d[:linetype], d[:marker], d[:nbins])) + +# # set color, line width, and point size +# theme = Gadfly.Theme(default_color = d[:color], +# line_width = d[:width] * Gadfly.px, +# default_point_size = d[:markersize] * Gadfly.px) +# push!(gfargs, theme) + +# # add a regression line? +# if d[:reg] +# push!(gfargs, Gadfly.Geom.smooth(method=:lm)) +# end + +# # for histograms, set x=y +# x = d[d[:linetype] == :hist ? :y : :x] + +# # add to the legend +# if length(plt.o.guides) > 0 && isa(plt.o.guides[1], Gadfly.Guide.ManualColorKey) +# push!(plt.o.guides[1].labels, d[:label]) +# push!(plt.o.guides[1].colors, d[:color]) +# end + +# if d[:axis] != :left +# warn("Gadly only supports one y axis") +# end + +# # save the kw args +# push!(plt.seriesargs, d) + +# # add the layer to the Gadfly.Plot +# prepend!(plt.o.layers, Gadfly.layer(unique(gfargs)..., d[:args]...; x = x, y = d[:y], d[:kwargs]...)) +# plt +# end + function Base.display(::GadflyPackage, plt::Plot) display(plt.o) end diff --git a/src/backends/immerse.jl b/src/backends/immerse.jl new file mode 100644 index 00000000..a4f45187 --- /dev/null +++ b/src/backends/immerse.jl @@ -0,0 +1,68 @@ + +# https://github.com/JuliaGraphics/Immerse.jl + +immutable ImmersePackage <: PlottingPackage end + +immerse!() = plotter!(:immerse) + + + +# create a blank Gadfly.Plot object +function plot(pkg::ImmersePackage; kw...) + d = Dict(kw) + + # create the underlying Gadfly.Plot object + gplt = createGadflyPlotObject(d) + + # create the figure. Immerse just returns the index of the Figure in the GadflyDisplay... call Figure(figidx) to get the object + w,h = d[:size] + figidx = Immerse.figure(; name = d[:windowtitle], width = w, height = h) + fig = Immerse.Figure(figidx) + + # save both the Immerse.Figure and the Gadfly.Plot + Plot((fig,gplt), pkg, 0, d, Dict[]) +end + + +# plot one data series +function plot!(::ImmersePackage, plt::Plot; kw...) + d = Dict(kw) + addGadflySeries!(plt.o[2], d) + push!(plt.seriesargs, d) + plt +end + +function Base.display(::ImmersePackage, plt::Plot) + display(plt.o[2]) +end + +# ------------------------------- + +function savepng(::ImmersePackage, plt::PlottingObject, fn::String; + w = 6 * Immerse.inch, + h = 4 * Immerse.inch) + Immerse.draw(Immerse.PNG(fn, w, h), plt.o) +end + + +# ------------------------------- + +# create the underlying object (each backend will do this differently) +function buildSubplotObject!(::ImmersePackage, subplt::Subplot) + i = 0 + rows = [] + for rowcnt in subplt.layout.rowcounts + push!(rows, Gadfly.hstack([plt.o[2] for plt in subplt.plts[(1:rowcnt) + i]]...)) + i += rowcnt + end + gctx = Gadfly.vstack(rows...) + + figidx = Immerse.figure() + fig = Immerse.Figure(figidx) + (fig, gctx) +end + + +function Base.display(::ImmersePackage, subplt::Subplot) + display(subplt.o[2]) +end diff --git a/src/plotter.jl b/src/plotter.jl index c62a0636..ce14809d 100644 --- a/src/plotter.jl +++ b/src/plotter.jl @@ -4,7 +4,7 @@ include("backends/qwt.jl") include("backends/gadfly.jl") include("backends/unicodeplots.jl") include("backends/pyplot.jl") - +include("backends/immerse.jl") # --------------------------------------------------------- @@ -21,7 +21,7 @@ Base.display(pkg::PlottingPackage, subplt::Subplot) = error("display($pkg, subpl # --------------------------------------------------------- -const AVAILABLE_PACKAGES = [:qwt, :gadfly, :unicodeplots, :pyplot] +const AVAILABLE_PACKAGES = [:qwt, :gadfly, :unicodeplots, :pyplot, :immerse] const INITIALIZED_PACKAGES = Set{Symbol}() backends() = AVAILABLE_PACKAGES @@ -31,6 +31,7 @@ function getPlottingPackage(sym::Symbol) sym == :gadfly && return GadflyPackage() sym == :unicodeplots && return UnicodePlotsPackage() sym == :pyplot && return PyPlotPackage() + sym == :immerse && return ImmersePackage() error("Unsupported backend $sym") end @@ -44,6 +45,10 @@ CurrentPackage(sym::Symbol) = CurrentPackage(sym, getPlottingPackage(sym)) # --------------------------------------------------------- function pickDefaultBackend() + try + Pkg.installed("Immerse") + return CurrentPackage(:immerse) + end try Pkg.installed("Qwt") return CurrentPackage(:qwt) @@ -85,24 +90,36 @@ function plotter() catch error("Couldn't import Qwt. Install it with: Pkg.clone(\"https://github.com/tbreloff/Qwt.jl.git\")\n (Note: also requires pyqt and pyqwt)") end + elseif currentPackageSymbol == :gadfly try @eval import Gadfly catch error("Couldn't import Gadfly. Install it with: Pkg.add(\"Gadfly\")") end + elseif currentPackageSymbol == :unicodeplots try @eval import UnicodePlots catch error("Couldn't import UnicodePlots. Install it with: Pkg.add(\"UnicodePlots\")") end + elseif currentPackageSymbol == :pyplot try @eval import PyPlot catch error("Couldn't import PyPlot. Install it with: Pkg.add(\"PyPlot\")") end + + elseif currentPackageSymbol == :immerse + try + @eval import Immerse + @eval import Gadfly + catch + error("Couldn't import Immerse. Install it with: Pkg.add(\"Immerse\")") + end + else error("Unknown plotter $currentPackageSymbol. Choose from: $AVAILABLE_PACKAGES") end @@ -127,6 +144,8 @@ function plotter!(modname) CURRENT_PACKAGE.pkg = UnicodePlotsPackage() elseif modname == :pyplot CURRENT_PACKAGE.pkg = PyPlotPackage() + elseif modname == :immerse + CURRENT_PACKAGE.pkg = ImmersePackage() else error("Unknown plotter $modname. Choose from: $AVAILABLE_PACKAGES") end