diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 30d0c05c..474efb68 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -922,17 +922,7 @@ end # ---------------------------------------------------------------- -function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend}) - # show_png_from_html(io, plt) - error("png output from the plotly backend is not supported. Please use plotlyjs instead.") -end - -function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend}) - error("svg output from the plotly backend is not supported. Please use plotlyjs instead.") -end - -function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) - prepare_output(plt) +function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) write(io, html_head(plt) * html_body(plt)) end diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 1bcc3845..10213214 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -1,5 +1,5 @@ @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl")) end # https://github.com/spencerlyon2/PlotlyJS.jl @@ -88,8 +88,7 @@ end # ---------------------------------------------------------------- -function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) - prepare_output(plt) +function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) if isijulia() && !_use_remote[] write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o))) else diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 6b4e124d..f644966d 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -212,7 +212,7 @@ end function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) unicodeplots_rebuild(plt) - map(show, plt.o) + foreach(x -> show(io, x), plt.o) nothing end diff --git a/src/output.jl b/src/output.jl index 6344ba9c..3a88df8c 100644 --- a/src/output.jl +++ b/src/output.jl @@ -168,37 +168,11 @@ const _mimeformats = Dict( "application/x-tex" => "tex", ) -const _best_html_output_type = KW( - :pyplot => :png, - :unicodeplots => :txt, - :glvisualize => :png, - :plotlyjs => :html, - :plotly => :html -) - -# a backup for html... passes to svg or png depending on the html_output_format arg -function Base.show(io::IO, ::MIME"text/html", plt::Plot) - output_type = Symbol(plt.attr[:html_output_format]) - if output_type == :auto - output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) - end - if output_type == :png - # info("writing png to html output") - print(io, "") - elseif output_type == :svg - # info("writing svg to html output") - show(io, MIME("image/svg+xml"), plt) - elseif output_type == :txt - show(io, MIME("text/plain"), plt) - else - error("only png or svg allowed. got: $output_type") - end +# delegate mimewritable (showable on julia 0.7) to _show instead +function Base.mimewritable(m::M, plt::P) where {M<:MIME, P<:Plot} + return method_exists(_show, Tuple{IO, M, P}) end -function _show(io::IO, m, plt::Plot{B}) where B - # Base.show_backtrace(STDOUT, backtrace()) - warn("_show is not defined for this backend. m=", string(m)) -end function _display(plt::Plot) warn("_display is not defined for this backend.") end @@ -262,6 +236,14 @@ end # IJulia # --------------------------------------------------------- +const _best_IJulia_output_type = Dict( + PyPlotBackend => :png, + UnicodePlotsBackend => :txt, + GLVisualizeBackend => :png, + PlotlyJSBackend => :html, + PlotlyBackend => :html +) + @require IJulia begin if IJulia.inited @@ -286,31 +268,24 @@ end out end - function IJulia.display_dict(plt::Plot) - output_type = Symbol(plt.attr[:html_output_format]) - if output_type == :auto - output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) - end - out = Dict() - if output_type == :png - mime = "image/png" - out[mime] = base64encode(show, MIME(mime), plt) - elseif output_type == :svg - mime = "image/svg+xml" - out[mime] = sprint(show, MIME(mime), plt) - elseif output_type == :html - mime = "text/html" - out[mime] = sprint(show, MIME(mime), plt) - else - error("Unsupported output type $output_type") - end - _extra_mime_info!(plt, out) - out + # use mimewritable to "trick" IJulia to choose the right output type + # Union needed to avoid method overwrite from the non-IJulia definition of mimewritable + AllBackends = Union{PyPlotBackend, UnicodePlotsBackend, PlotlyBackend, PlotlyJSBackend, + GRBackend, GLVisualizeBackend, PGFPlotsBackend, InspectDRBackend, HDF5Backend} + function Base.mimewritable(mime::M, plt::Plot{P}) where {M<:MIME, P<:AllBackends} + sym = Symbol(plt.attr[:html_output_format]) + sym = sym === (:auto) ? get(_best_IJulia_output_type, P, :svg) : sym + sym === :txt && M === MIME"text/plain" && return invoke(mimewritable, Tuple{MIME,Plot}, mime, plt) + sym === :png && M === MIME"image/png" && return invoke(mimewritable, Tuple{MIME,Plot}, mime, plt) + sym === :svg && M === MIME"image/svg+xml" && return invoke(mimewritable, Tuple{MIME,Plot}, mime, plt) + sym === :html && M === MIME"text/html" && return invoke(mimewritable, Tuple{MIME,Plot}, mime, plt) + return false end - # default text/plain passes to html... handles Interact issues - function Base.show(io::IO, m::MIME"text/plain", plt::Plot) - show(io, MIME("text/html"), plt) + function IJulia.display_dict(plt::Plot) + out = invoke(IJulia.display_dict, Tuple{Any}, plt) + _extra_mime_info!(plt, out) + return out end ENV["MPLBACKEND"] = "Agg"