From c8ed611c9c06f40bfd2734fbcea792b890e41157 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Wed, 15 Jun 2016 01:45:13 -0400 Subject: [PATCH] unicodeplots cleanup: ijulia output fixes, ascii canvas --- src/backends/unicodeplots.jl | 235 ++++++++--------------------------- src/output.jl | 6 +- 2 files changed, 58 insertions(+), 183 deletions(-) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 35975b2e..ba447cf6 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -4,12 +4,12 @@ supported_args(::UnicodePlotsBackend) = merge_with_base_supported([ :label, :legend, - :seriescolor, :seriesalpha, + :seriescolor, + :seriesalpha, :linestyle, :markershape, :bins, :title, - :window_title, :guide, :lims, ]) supported_types(::UnicodePlotsBackend) = [ @@ -28,19 +28,19 @@ warnOnUnsupported_args(pkg::UnicodePlotsBackend, d::KW) = nothing # -------------------------------------------------------------------------------------- function _initialize_backend(::UnicodePlotsBackend; kw...) - @eval begin - import UnicodePlots - export UnicodePlots - end + @eval begin + import UnicodePlots + export UnicodePlots + end end # ------------------------------- -# convert_size_from_pixels(sz) = # do all the magic here... build it all at once, since we need to know about all the series at the very beginning function rebuildUnicodePlot!(plt::Plot) plt.o = [] + for sp in plt.subplots xaxis = sp[:xaxis] yaxis = sp[:yaxis] @@ -58,12 +58,14 @@ function rebuildUnicodePlot!(plt::Plot) # create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds width, height = plt[:size] - o = UnicodePlots.Plot(x, y; + canvas_type = isijulia() ? UnicodePlots.AsciiCanvas : UnicodePlots.BrailleCanvas + o = UnicodePlots.Plot(x, y, canvas_type; width = width, height = height, title = sp[:title], xlim = xlim, - ylim = ylim + ylim = ylim, + border = isijulia() ? :ascii : :solid ) # set the axis labels @@ -80,213 +82,82 @@ function rebuildUnicodePlot!(plt::Plot) end end -# # do all the magic here... build it all at once, since we need to know about all the series at the very beginning -# function rebuildUnicodePlot!(plt::Plot) -# -# # figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax] -# sargs = plt.seriesargs -# iargs = plt.attr -# -# # get the x/y limits -# if get(iargs, :xlims, :auto) == :auto -# xlim = [Inf, -Inf] -# for d in sargs -# _expand_limits(xlim, d[:x]) -# end -# else -# xmin, xmax = iargs[:xlims] -# xlim = [xmin, xmax] -# end -# -# if get(iargs, :ylims, :auto) == :auto -# ylim = [Inf, -Inf] -# for d in sargs -# _expand_limits(ylim, d[:y]) -# end -# else -# ymin, ymax = iargs[:ylims] -# ylim = [ymin, ymax] -# end -# -# # we set x/y to have a single point, since we need to create the plot with some data. -# # since this point is at the bottom left corner of the plot, it shouldn't actually be shown -# x = Float64[xlim[1]] -# y = Float64[ylim[1]] -# -# # create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds -# width, height = iargs[:size] -# o = UnicodePlots.Plot(x, y; width = width, -# height = height, -# title = iargs[:title], -# # labels = iargs[:legend], -# xlim = xlim, -# ylim = ylim) -# -# # set the axis labels -# UnicodePlots.xlabel!(o, iargs[:xguide]) -# UnicodePlots.ylabel!(o, iargs[:yguide]) -# -# # now use the ! functions to add to the plot -# for d in sargs -# addUnicodeSeries!(o, d, iargs[:legend] != :none, xlim, ylim) -# end -# -# # save the object -# plt.o = o -# end - # add a single series function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) - # get the function, or special handling for step/bar/hist st = d[:seriestype] - - # handle hline/vline separately - if st in (:hline,:vline) - for yi in d[:y] - if st == :hline - UnicodePlots.lineplot!(o, xlim, [yi,yi]) - else - UnicodePlots.lineplot!(o, [yi,yi], ylim) - end - end - return - - # elseif st == :bar - # UnicodePlots.barplot!(o, d[:x], d[:y]) - # return - - # elseif st == :histogram - # UnicodePlots.histogram!(o, d[:y], bins = d[:bins]) - # return - - elseif st == :histogram2d + if st == :histogram2d UnicodePlots.densityplot!(o, d[:x], d[:y]) return - end - stepstyle = :post - if st == :path - func = UnicodePlots.lineplot! - elseif st == :scatter || d[:markershape] != :none - func = UnicodePlots.scatterplot! - elseif st == :steppost - func = UnicodePlots.stairs! - elseif st == :steppre - func = UnicodePlots.stairs! - stepstyle = :pre - else - error("Linestyle $st not supported by UnicodePlots") - end + if st == :path + func = UnicodePlots.lineplot! + elseif st == :scatter || d[:markershape] != :none + func = UnicodePlots.scatterplot! + else + error("Linestyle $st not supported by UnicodePlots") + end - # get the series data and label - x, y = [collect(float(d[s])) for s in (:x, :y)] - label = addlegend ? d[:label] : "" + # get the series data and label + x, y = [collect(float(d[s])) for s in (:x, :y)] + label = addlegend ? d[:label] : "" - # if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide - color = d[:linecolor] in UnicodePlots.color_cycle ? d[:linecolor] : :auto + # if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide + color = d[:linecolor] in UnicodePlots.color_cycle ? d[:linecolor] : :auto - # add the series - func(o, x, y; color = color, name = label, style = stepstyle) + # add the series + func(o, x, y; color = color, name = label) end - -# function handlePlotColors(::UnicodePlotsBackend, d::KW) -# # TODO: something special for unicodeplots, since it doesn't take kindly to people messing with its color palette -# d[:color_palette] = [RGB(0,0,0)] -# end - -# ------------------------------- - - -# function _create_plot(pkg::UnicodePlotsBackend, d::KW) - # plt = Plot(nothing, pkg, 0, d, KW[]) - -function _create_backend_figure(plt::Plot{UnicodePlotsBackend}) - # do we want to give a new default size? - # if !haskey(plt.attr, :size) || plt.attr[:size] == default(:size) - # plt.attr[:size] = (60,20) - # end - w, h = plt[:size] - plt.attr[:size] = div(w, 10), div(h, 20) - plt.attr[:color_palette] = [RGB(0,0,0)] - nothing - - # plt -end - -# function _series_added(plt::Plot{UnicodePlotsBackend}, series::Series) -# d = series.d -# # TODO don't need these once the "bar" series recipe is done -# if d[:seriestype] in (:sticks, :bar) -# d = barHack(; d...) -# elseif d[:seriestype] == :histogram -# d = barHack(; histogramHack(; d...)...) -# end -# # push!(plt.seriesargs, d) -# # plt -# end -# -# -# function _update_plot_object(plt::Plot{UnicodePlotsBackend}, d::KW) -# for k in (:title, :xguide, :yguide, :xlims, :ylims) -# if haskey(d, k) -# plt.attr[k] = d[k] -# end -# end -# end - - # ------------------------------- # since this is such a hack, it's only callable using `png`... should error during normal `writemime` function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString) - fn = addExtension(fn, "png") + fn = addExtension(fn, "png") - # make some whitespace and show the plot - println("\n\n\n\n\n\n") - gui(plt) + # make some whitespace and show the plot + println("\n\n\n\n\n\n") + gui(plt) - # @osx_only begin - @compat @static if is_apple() - # BEGIN HACK + # @osx_only begin + @compat @static if is_apple() + # BEGIN HACK - # wait while the plot gets drawn - sleep(0.5) + # wait while the plot gets drawn + sleep(0.5) - # use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?) - # TODO: compute size of plot to adjust these numbers (or maybe implement something good??) - run(`screencapture -R50,600,700,420 $fn`) + # use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?) + # TODO: compute size of plot to adjust these numbers (or maybe implement something good??) + run(`screencapture -R50,600,700,420 $fn`) - # END HACK (phew) - return - end + # END HACK (phew) + return + end - error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)") + error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)") end # ------------------------------- # we don't do very much for subplots... just stack them vertically -# function _create_subplot(subplt::Subplot{UnicodePlotsBackend}, isbefore::Bool) -# isbefore && return false -# true -# end - - -function _display(plt::Plot{UnicodePlotsBackend}) +function _update_plot_object(plt::Plot{UnicodePlotsBackend}) + w, h = plt[:size] + plt.attr[:size] = div(w, 10), div(h, 20) + plt.attr[:color_palette] = [RGB(0,0,0)] rebuildUnicodePlot!(plt) +end + +function _writemime(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) map(show, plt.o) nothing end +function _display(plt::Plot{UnicodePlotsBackend}) + map(show, plt.o) + nothing +end -# function Base.display(::PlotsDisplay, subplt::Subplot{UnicodePlotsBackend}) -# for plt in subplt.plts -# gui(plt) -# end -# end diff --git a/src/output.jl b/src/output.jl index 2de9315b..55dab85d 100644 --- a/src/output.jl +++ b/src/output.jl @@ -119,11 +119,13 @@ const _mimeformats = Dict( "application/pdf" => "pdf", "image/png" => "png", "application/postscript" => "ps", - "image/svg+xml" => "svg" + "image/svg+xml" => "svg", + "text/plain" => "txt", ) const _best_html_output_type = KW( :pyplot => :png, + :unicodeplots => :txt, ) # a backup for html... passes to svg or png depending on the html_output_format arg @@ -138,6 +140,8 @@ function Base.writemime(io::IO, ::MIME"text/html", plt::Plot) elseif output_type == :svg # info("writing svg to html output") writemime(io, MIME("image/svg+xml"), plt) + elseif output_type == :txt + writemime(io, MIME("text/plain"), plt) else error("only png or svg allowed. got: $output_type") end