From ada146fe4e35dc931f952c4a22f74682eabe462d Mon Sep 17 00:00:00 2001 From: t-bltg Date: Wed, 12 Jan 2022 01:42:35 +0100 Subject: [PATCH 1/6] basic quiver support --- src/backends.jl | 2 ++ src/backends/unicodeplots.jl | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 87f0014bf..62d9d97b9 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -923,6 +923,8 @@ const _unicodeplots_attr = merge_with_base_supported([ :linecolor, :linestyle, :markershape, + :quiver, + :arrow, :seriesalpha, :seriescolor, :scale, diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 5f9314d22..ae18e10f5 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -123,11 +123,10 @@ function addUnicodeSeries!( return UnicodePlots.spy(series[:z].surf; kw...) end - series_kw = (;) - # now use the ! functions to add to the plot if st in (:path, :straightline, :shape) func = UnicodePlots.lineplot! + series_kw = (; head_tail = series[:arrow] isa Arrow ? series[:arrow].side : nothing) elseif st == :scatter || series[:markershape] != :none func = UnicodePlots.scatterplot! series_kw = (; marker = series[:markershape]) From cfc8e8e4923e12785c1b52058838038aae8841e3 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Wed, 12 Jan 2022 12:45:23 +0100 Subject: [PATCH 2/6] toggle grid --- src/backends/unicodeplots.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index ae18e10f5..187520bac 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -51,6 +51,7 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend}) title = texmath2unicode(sp[:title]), xlabel = texmath2unicode(xaxis[:guide]), ylabel = texmath2unicode(yaxis[:guide]), + grid = xaxis[:grid] && yaxis[:grid], height = _unicodeplots_height[], width = _unicodeplots_width[], xscale = xaxis[:scale], From 1effd45e8b21e81bdfc02302bede72ee6e708ab9 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Wed, 12 Jan 2022 16:09:29 +0100 Subject: [PATCH 3/6] add contour --- src/backends.jl | 1 + src/backends/unicodeplots.jl | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 62d9d97b9..a4857adcb 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -938,6 +938,7 @@ const _unicodeplots_seriestype = [ :shape, :histogram2d, :heatmap, + :contour, :spy, ] const _unicodeplots_style = [:auto, :solid] diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 187520bac..c88f5e28a 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -88,6 +88,11 @@ up_color(col::RGBA) = (c = convert(ARGB32, col); map(Int, (red(c).i, green(c).i, blue(c).i))) up_color(col) = :auto +function up_cmap(series) + rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis])) + [(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)] +end + # add a single series function addUnicodeSeries!( sp::Subplot{UnicodePlotsBackend}, @@ -112,16 +117,19 @@ function addUnicodeSeries!( kw[:xlim][:] .= kw[:ylim][:] .= 0 return UnicodePlots.densityplot(x, y; kw...) elseif st == :heatmap - rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis])) - cmap = [(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)] return UnicodePlots.heatmap( series[:z].surf; zlabel = sp[:colorbar_title], - colormap = cmap, + colormap = up_cmap(series), kw..., ) elseif st == :spy return UnicodePlots.spy(series[:z].surf; kw...) + elseif st == :contour + return UnicodePlots.contourplot( + x, y, series[:z].surf; + levels=series[:levels], colormap = up_cmap(series), kw... + ) end # now use the ! functions to add to the plot From 143c77334bcee44c67487d1b710759068a2726ed Mon Sep 17 00:00:00 2001 From: t-bltg Date: Wed, 12 Jan 2022 19:43:49 +0100 Subject: [PATCH 4/6] add colorbar --- src/backends/unicodeplots.jl | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index c88f5e28a..936e11762 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -104,39 +104,41 @@ function addUnicodeSeries!( st = series[:seriestype] # get the series data and label - x, y = if st == :straightline + x, y = if st === :straightline straightline_data(series) - elseif st == :shape + elseif st === :shape shape_data(series) else float(series[:x]), float(series[:y]) end # special handling (src/interface) - if st == :histogram2d + if st === :histogram2d kw[:xlim][:] .= kw[:ylim][:] .= 0 return UnicodePlots.densityplot(x, y; kw...) - elseif st == :heatmap - return UnicodePlots.heatmap( - series[:z].surf; + elseif st === :spy + return UnicodePlots.spy(series[:z].surf; kw...) + elseif st in (:contour, :heatmap) + kw_hm_ct = (; zlabel = sp[:colorbar_title], colormap = up_cmap(series), - kw..., - ) - elseif st == :spy - return UnicodePlots.spy(series[:z].surf; kw...) - elseif st == :contour - return UnicodePlots.contourplot( - x, y, series[:z].surf; - levels=series[:levels], colormap = up_cmap(series), kw... + colorbar = hascolorbar(sp), ) + if st === :contour + return UnicodePlots.contourplot( + x, y, series[:z].surf; + levels = series[:levels], kw_hm_ct..., kw... + ) + else + return UnicodePlots.heatmap(series[:z].surf; kw_hm_ct..., kw...) + end end # now use the ! functions to add to the plot if st in (:path, :straightline, :shape) func = UnicodePlots.lineplot! series_kw = (; head_tail = series[:arrow] isa Arrow ? series[:arrow].side : nothing) - elseif st == :scatter || series[:markershape] != :none + elseif st === :scatter || series[:markershape] != :none func = UnicodePlots.scatterplot! series_kw = (; marker = series[:markershape]) else From 2c35964879ae2ab3db0f3b6018592bd9e561b138 Mon Sep 17 00:00:00 2001 From: t-bltg Date: Thu, 13 Jan 2022 11:52:05 +0100 Subject: [PATCH 5/6] toggle contour example --- src/backends/unicodeplots.jl | 11 +++++++---- src/examples.jl | 1 - 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 936e11762..f71717ff4 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -117,6 +117,7 @@ function addUnicodeSeries!( kw[:xlim][:] .= kw[:ylim][:] .= 0 return UnicodePlots.densityplot(x, y; kw...) elseif st === :spy + kw = (; kw..., width = 0, height = 0) # w/h handled in UnicodePlots return UnicodePlots.spy(series[:z].surf; kw...) elseif st in (:contour, :heatmap) kw_hm_ct = (; @@ -125,11 +126,13 @@ function addUnicodeSeries!( colorbar = hascolorbar(sp), ) if st === :contour + isfilledcontour(series) && @warn "Plots(UnicodePlots): filled contour is not implemented" return UnicodePlots.contourplot( x, y, series[:z].surf; levels = series[:levels], kw_hm_ct..., kw... ) else + kw = (; kw..., width = 0, height = 0) # w/h handled in UnicodePlots return UnicodePlots.heatmap(series[:z].surf; kw_hm_ct..., kw...) end end @@ -142,7 +145,7 @@ function addUnicodeSeries!( func = UnicodePlots.scatterplot! series_kw = (; marker = series[:markershape]) else - error("Series type $st not supported by UnicodePlots") + error("Plots(UnicodePlots): series type $st not supported") end label = addlegend ? series[:label] : "" @@ -172,7 +175,7 @@ function addUnicodeSeries!( ) end - return up + up end # ------------------------------------------------------------------------------------------ @@ -208,7 +211,7 @@ end Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt) Base.show(io::IO, plt::Plot{UnicodePlotsBackend}) = _show(io, MIME("text/plain"), plt) -# NOTE: _show(..) must be kept for Base.showable (src/output.jl) +# NOTE: _show(...) must be kept for Base.showable (src/output.jl) function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) unicodeplots_rebuild(plt) nr, nc = size(plt.layout) @@ -232,7 +235,7 @@ function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) for c in 1:nc l = plt.layout[r, c] if l isa GridLayout && size(l) != (1, 1) - @error "UnicodePlots: complex nested layout is currently unsupported !" + @error "Plots(UnicodePlots): complex nested layout is currently unsupported" else if get(l.attr, :blank, false) lines_colored[r, c] = lines_uncolored[r, c] = nothing diff --git a/src/examples.jl b/src/examples.jl index 0c56bce97..1c148af85 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -1289,7 +1289,6 @@ _backend_skips = Dict( 6, # embedded images unsupported 16, # nested layout unsupported 21, # custom markers unsupported - 22, # contours unsupported 24, # 3D unsupported 26, # nested layout unsupported 27, # polar plots unsupported From 6afc45473fae66bda5c425025e1656130644cace Mon Sep 17 00:00:00 2001 From: t-bltg Date: Fri, 14 Jan 2022 14:55:00 +0100 Subject: [PATCH 6/6] rework keywords --- Project.toml | 2 +- src/backends.jl | 8 +++--- src/backends/unicodeplots.jl | 53 +++++++++++++++++++++++------------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Project.toml b/Project.toml index 49b453af5..342e1b52e 100644 --- a/Project.toml +++ b/Project.toml @@ -55,7 +55,7 @@ Scratch = "1" Showoff = "0.3.1, 1.0" StatsBase = "0.32 - 0.33" UnicodeFun = "0.4" -UnicodePlots = "2.4" +UnicodePlots = "2.6" Unzip = "0.1" julia = "1.6" diff --git a/src/backends.jl b/src/backends.jl index a4857adcb..5911f90a8 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -973,10 +973,10 @@ const _unicodeplots_marker = [ const _unicodeplots_scale = [:identity, :ln, :log2, :log10] # Additional constants -const _unicodeplots_canvas = Ref(:auto) -const _unicodeplots_border = Ref(:auto) -const _unicodeplots_height = Ref(15) -const _unicodeplots_width = Ref(40) +const _up_colormap = Ref(:none) +const _up_canvas = Ref(:auto) +const _up_border = Ref(:auto) +const _up_fix_ar = Ref(true) # ------------------------------------------------------------------------------ # hdf5 diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index f71717ff4..ef09268d6 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -24,36 +24,55 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend}) yaxis = sp[:yaxis] xlim = collect(axis_limits(sp, :x)) ylim = collect(axis_limits(sp, :y)) + F = float(eltype(xlim)) # 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 should be hidden by consecutive plotting commands. - x = Float64[xlim[1]] - y = Float64[ylim[1]] + x = F[xlim[1]] + y = F[ylim[1]] # create a plot window with xlim/ylim set, # but the X/Y vectors are outside the bounds - canvas = if (up_c = _unicodeplots_canvas[]) == :auto + canvas = if (up_c = _up_canvas[]) == :auto isijulia() ? :ascii : :braille else up_c end - border = if (up_b = _unicodeplots_border[]) == :auto + border = if (up_b = _up_border[]) == :auto isijulia() ? :ascii : :solid else up_b end + width, height = UnicodePlots.DEFAULT_WIDTH[], UnicodePlots.DEFAULT_HEIGHT[] + + grid = xaxis[:grid] && yaxis[:grid] + quiver = contour = false + for series in series_list(sp) + st = series[:seriestype] + quiver |= series[:arrow] isa Arrow # post-pipeline detection (:quiver -> :path) + contour |= st === :contour + if st === :histogram2d + xlim = ylim = (0, 0) + elseif st === :spy || st === :heatmap + width = height = 0 + grid = false + end + end + grid &= !contour && !quiver + kw = ( compact = true, title = texmath2unicode(sp[:title]), xlabel = texmath2unicode(xaxis[:guide]), ylabel = texmath2unicode(yaxis[:guide]), - grid = xaxis[:grid] && yaxis[:grid], - height = _unicodeplots_height[], - width = _unicodeplots_width[], + grid = grid, + blend = !(quiver || contour), + height = height, + width = width, xscale = xaxis[:scale], yscale = yaxis[:scale], border = border, @@ -114,26 +133,22 @@ function addUnicodeSeries!( # special handling (src/interface) if st === :histogram2d - kw[:xlim][:] .= kw[:ylim][:] .= 0 return UnicodePlots.densityplot(x, y; kw...) elseif st === :spy - kw = (; kw..., width = 0, height = 0) # w/h handled in UnicodePlots - return UnicodePlots.spy(series[:z].surf; kw...) + return UnicodePlots.spy(series[:z].surf; fix_ar = _up_fix_ar[], kw...) elseif st in (:contour, :heatmap) - kw_hm_ct = (; + kw = ( + kw..., zlabel = sp[:colorbar_title], - colormap = up_cmap(series), + colormap = (cm = _up_colormap[] === :none) ? up_cmap(series) : cm, colorbar = hascolorbar(sp), ) if st === :contour isfilledcontour(series) && @warn "Plots(UnicodePlots): filled contour is not implemented" - return UnicodePlots.contourplot( - x, y, series[:z].surf; - levels = series[:levels], kw_hm_ct..., kw... - ) - else - kw = (; kw..., width = 0, height = 0) # w/h handled in UnicodePlots - return UnicodePlots.heatmap(series[:z].surf; kw_hm_ct..., kw...) + return UnicodePlots.contourplot(x, y, series[:z].surf; kw..., levels = series[:levels]) + elseif st === :heatmap + return UnicodePlots.heatmap(series[:z].surf; fix_ar = _up_fix_ar[], kw...) + # zlim = collect(axis_limits(sp, :z)) end end