UnicodePlots: enhance display / show (#4021)
This commit is contained in:
parent
37a5df1464
commit
dbef591457
@ -970,7 +970,10 @@ const _unicodeplots_marker = [
|
|||||||
const _unicodeplots_scale = [:identity, :ln, :log2, :log10]
|
const _unicodeplots_scale = [:identity, :ln, :log2, :log10]
|
||||||
|
|
||||||
# Additional constants
|
# Additional constants
|
||||||
const _canvas_type = Ref(:auto)
|
const _unicodeplots_canvas = Ref(:auto)
|
||||||
|
const _unicodeplots_border = Ref(:auto)
|
||||||
|
const _unicodeplots_height = Ref(15)
|
||||||
|
const _unicodeplots_width = Ref(40)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# hdf5
|
# hdf5
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
# https://github.com/JuliaPlots/UnicodePlots.jl
|
# https://github.com/JuliaPlots/UnicodePlots.jl
|
||||||
|
|
||||||
# don't warn on unsupported... there's just too many warnings!!
|
# don't warn on unsupported... there's just too many warnings !
|
||||||
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes) = nothing
|
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes) = nothing
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------
|
||||||
const _canvas_map = (
|
const _canvas_map = (
|
||||||
ascii = UnicodePlots.AsciiCanvas,
|
|
||||||
block = UnicodePlots.BlockCanvas,
|
|
||||||
braille = UnicodePlots.BrailleCanvas,
|
braille = UnicodePlots.BrailleCanvas,
|
||||||
density = UnicodePlots.DensityCanvas,
|
density = UnicodePlots.DensityCanvas,
|
||||||
dot = UnicodePlots.DotCanvas,
|
|
||||||
heatmap = UnicodePlots.HeatmapCanvas,
|
heatmap = UnicodePlots.HeatmapCanvas,
|
||||||
lookup = UnicodePlots.LookupCanvas,
|
lookup = UnicodePlots.LookupCanvas,
|
||||||
|
ascii = UnicodePlots.AsciiCanvas,
|
||||||
|
block = UnicodePlots.BlockCanvas,
|
||||||
|
dot = UnicodePlots.DotCanvas,
|
||||||
)
|
)
|
||||||
|
|
||||||
# do all the magic here... build it all at once,
|
# do all the magic here... build it all at once,
|
||||||
@ -25,19 +25,25 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
|
|||||||
xlim = collect(axis_limits(sp, :x))
|
xlim = collect(axis_limits(sp, :x))
|
||||||
ylim = collect(axis_limits(sp, :y))
|
ylim = collect(axis_limits(sp, :y))
|
||||||
|
|
||||||
# we set x/y to have a single point,
|
# We set x/y to have a single point,
|
||||||
# since we need to create the plot with some data.
|
# since we need to create the plot with some data.
|
||||||
# since this point is at the bottom left corner of the plot,
|
# Since this point is at the bottom left corner of the plot,
|
||||||
# it shouldn't actually be shown
|
# it should be hidden by consecutive plotting commands.
|
||||||
x = Float64[xlim[1]]
|
x = Float64[xlim[1]]
|
||||||
y = Float64[ylim[1]]
|
y = Float64[ylim[1]]
|
||||||
|
|
||||||
# create a plot window with xlim/ylim set,
|
# create a plot window with xlim/ylim set,
|
||||||
# but the X/Y vectors are outside the bounds
|
# but the X/Y vectors are outside the bounds
|
||||||
canvas_type = if (ct = _canvas_type[]) == :auto
|
canvas = if (up_c = _unicodeplots_canvas[]) == :auto
|
||||||
isijulia() ? :ascii : :braille
|
isijulia() ? :ascii : :braille
|
||||||
else
|
else
|
||||||
ct
|
up_c
|
||||||
|
end
|
||||||
|
|
||||||
|
border = if (up_b = _unicodeplots_border[]) == :auto
|
||||||
|
isijulia() ? :ascii : :solid
|
||||||
|
else
|
||||||
|
up_b
|
||||||
end
|
end
|
||||||
|
|
||||||
kw = (
|
kw = (
|
||||||
@ -45,14 +51,16 @@ function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
|
|||||||
title = texmath2unicode(sp[:title]),
|
title = texmath2unicode(sp[:title]),
|
||||||
xlabel = texmath2unicode(xaxis[:guide]),
|
xlabel = texmath2unicode(xaxis[:guide]),
|
||||||
ylabel = texmath2unicode(yaxis[:guide]),
|
ylabel = texmath2unicode(yaxis[:guide]),
|
||||||
|
height = _unicodeplots_height[],
|
||||||
|
width = _unicodeplots_width[],
|
||||||
xscale = xaxis[:scale],
|
xscale = xaxis[:scale],
|
||||||
yscale = yaxis[:scale],
|
yscale = yaxis[:scale],
|
||||||
border = isijulia() ? :ascii : :solid,
|
border = border,
|
||||||
xlim = xlim,
|
xlim = xlim,
|
||||||
ylim = ylim,
|
ylim = ylim,
|
||||||
)
|
)
|
||||||
|
|
||||||
o = UnicodePlots.Plot(x, y, _canvas_map[canvas_type]; kw...)
|
o = UnicodePlots.Plot(x, y, _canvas_map[canvas]; kw...)
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
o = addUnicodeSeries!(sp, o, kw, series, sp[:legend_position] != :none)
|
o = addUnicodeSeries!(sp, o, kw, series, sp[:legend_position] != :none)
|
||||||
end
|
end
|
||||||
@ -190,62 +198,70 @@ end
|
|||||||
Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt)
|
Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt)
|
||||||
Base.show(io::IO, plt::Plot{UnicodePlotsBackend}) = _show(io, MIME("text/plain"), 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)
|
||||||
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
|
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
|
||||||
unicodeplots_rebuild(plt)
|
unicodeplots_rebuild(plt)
|
||||||
nr, nc = size(plt.layout)
|
nr, nc = size(plt.layout)
|
||||||
lines_colored = Array{Union{Nothing,Vector{String}}}(undef, nr, nc)
|
if nr == 1 && nc == 1 # fast path
|
||||||
lines_uncolored = copy(lines_colored)
|
n = length(plt.o)
|
||||||
l_max = zeros(Int, nr)
|
for (i, p) in enumerate(plt.o)
|
||||||
w_max = zeros(Int, nc)
|
show(io, p)
|
||||||
buf = IOBuffer()
|
i < n && println(io)
|
||||||
cbuf = IOContext(buf, :color => true)
|
|
||||||
re_col = r"\x1B\[[0-9;]*[a-zA-Z]"
|
|
||||||
sps = 0
|
|
||||||
for r in 1:nr
|
|
||||||
lmax = 0
|
|
||||||
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 !"
|
|
||||||
else
|
|
||||||
if get(l.attr, :blank, false)
|
|
||||||
lines_colored[r, c] = lines_uncolored[r, c] = nothing
|
|
||||||
else
|
|
||||||
sp = plt.o[sps += 1]
|
|
||||||
show(cbuf, sp)
|
|
||||||
colored = String(take!(buf))
|
|
||||||
uncolored = replace(colored, re_col => "")
|
|
||||||
lines_colored[r, c] = lc = split(colored, "\n")
|
|
||||||
lines_uncolored[r, c] = lu = split(uncolored, "\n")
|
|
||||||
lmax = max(length(lc), lmax)
|
|
||||||
w_max[c] = max(maximum(length.(lu)), w_max[c])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
l_max[r] = lmax
|
else
|
||||||
end
|
re_col = r"\e\[[0-9;]*m" # m: color, [a-zA-Z]: all escape sequences
|
||||||
empty = String[' '^w for w in w_max]
|
have_color = Base.get_have_color()
|
||||||
for r in 1:nr
|
buf = IOContext(PipeBuffer(), :color => have_color)
|
||||||
for n in 1:l_max[r]
|
lines_colored = Array{Union{Nothing,Vector{String}}}(undef, nr, nc)
|
||||||
|
lines_uncolored = have_color ? similar(lines_colored) : lines_colored
|
||||||
|
l_max = zeros(Int, nr)
|
||||||
|
w_max = zeros(Int, nc)
|
||||||
|
sps = 0
|
||||||
|
for r in 1:nr
|
||||||
|
lmax = 0
|
||||||
for c in 1:nc
|
for c in 1:nc
|
||||||
pre = c == 1 ? '\0' : ' '
|
l = plt.layout[r, c]
|
||||||
lc = lines_colored[r, c]
|
if l isa GridLayout && size(l) != (1, 1)
|
||||||
if lc === nothing || length(lc) < n
|
@error "UnicodePlots: complex nested layout is currently unsupported !"
|
||||||
print(io, pre, empty[c])
|
|
||||||
else
|
else
|
||||||
lu = lines_uncolored[r, c]
|
if get(l.attr, :blank, false)
|
||||||
print(io, pre, lc[n], ' '^(w_max[c] - length(lu[n])))
|
lines_colored[r, c] = lines_uncolored[r, c] = nothing
|
||||||
|
else
|
||||||
|
sp = plt.o[sps += 1]
|
||||||
|
show(buf, sp)
|
||||||
|
colored = read(buf, String)
|
||||||
|
lines_colored[r, c] = lu = lc = split(colored, '\n')
|
||||||
|
if have_color
|
||||||
|
uncolored = replace(colored, re_col => '\0')
|
||||||
|
lines_uncolored[r, c] = lu = split(uncolored, '\n')
|
||||||
|
end
|
||||||
|
lmax = max(length(lc), lmax)
|
||||||
|
w_max[c] = max(maximum(length.(lu)), w_max[c])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
println(io)
|
l_max[r] = lmax
|
||||||
|
end
|
||||||
|
empty = String[' '^w for w in w_max]
|
||||||
|
for r in 1:nr
|
||||||
|
for n in 1:l_max[r]
|
||||||
|
for c in 1:nc
|
||||||
|
pre = c == 1 ? '\0' : ' '
|
||||||
|
lc = lines_colored[r, c]
|
||||||
|
if lc === nothing || length(lc) < n
|
||||||
|
print(io, pre, empty[c])
|
||||||
|
else
|
||||||
|
lu = lines_uncolored[r, c]
|
||||||
|
print(io, pre, lc[n], ' '^(w_max[c] - length(lu[n])))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
n < l_max[r] && println(io)
|
||||||
|
end
|
||||||
|
r < nr && println(io)
|
||||||
end
|
end
|
||||||
r < nr && println(io)
|
|
||||||
end
|
end
|
||||||
nothing
|
nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
function _display(plt::Plot{UnicodePlotsBackend})
|
# we only support MIME"text/plain", hence display(...) falls back to plain-text on stdout
|
||||||
unicodeplots_rebuild(plt)
|
_display(plt::Plot{UnicodePlotsBackend}) = (show(stdout, plt); println(stdout))
|
||||||
map(display, plt.o)
|
|
||||||
nothing
|
|
||||||
end
|
|
||||||
|
|||||||
@ -89,7 +89,6 @@ function __init__()
|
|||||||
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
|
@require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
|
||||||
if IJulia.inited
|
if IJulia.inited
|
||||||
_init_ijulia_plotting()
|
_init_ijulia_plotting()
|
||||||
|
|
||||||
IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt)
|
IJulia.display_dict(plt::Plot) = _ijulia_display_dict(plt)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -217,6 +217,8 @@ for mime in (
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Base.showable(::MIME"text/html", plt::Plot{UnicodePlotsBackend}) = false # Pluto
|
||||||
|
|
||||||
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
|
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
|
||||||
showjuno(io, MIME("text/html"), plt)
|
showjuno(io, MIME("text/html"), plt)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user