defaultOutputFormat(plt::Plot) = "png" function png(plt::Plot, fn::AbstractString) fn = addExtension(fn, "png") io = open(fn, "w") show(io, MIME("image/png"), plt) close(io) end png(fn::AbstractString) = png(current(), fn) function svg(plt::Plot, fn::AbstractString) fn = addExtension(fn, "svg") io = open(fn, "w") show(io, MIME("image/svg+xml"), plt) close(io) end svg(fn::AbstractString) = svg(current(), fn) function pdf(plt::Plot, fn::AbstractString) fn = addExtension(fn, "pdf") io = open(fn, "w") show(io, MIME("application/pdf"), plt) close(io) end pdf(fn::AbstractString) = pdf(current(), fn) function ps(plt::Plot, fn::AbstractString) fn = addExtension(fn, "ps") io = open(fn, "w") show(io, MIME("application/postscript"), plt) close(io) end ps(fn::AbstractString) = ps(current(), fn) function eps(plt::Plot, fn::AbstractString) fn = addExtension(fn, "eps") io = open(fn, "w") show(io, MIME("image/eps"), plt) close(io) end eps(fn::AbstractString) = eps(current(), fn) function tex(plt::Plot, fn::AbstractString) fn = addExtension(fn, "tex") io = open(fn, "w") show(io, MIME("application/x-tex"), plt) close(io) end tex(fn::AbstractString) = tex(current(), fn) function html(plt::Plot, fn::AbstractString) fn = addExtension(fn, "html") io = open(fn, "w") _use_remote[] = true show(io, MIME("text/html"), plt) _use_remote[] = false close(io) end html(fn::AbstractString) = html(current(), fn) # ---------------------------------------------------------------- const _savemap = Dict( "png" => png, "svg" => svg, "pdf" => pdf, "ps" => ps, "eps" => eps, "tex" => tex, "html" => html, ) function getExtension(fn::AbstractString) pieces = split(fn, ".") length(pieces) > 1 || error("Can't extract file extension: ", fn) ext = pieces[end] haskey(_savemap, ext) || error("Invalid file extension: ", fn) ext end function addExtension(fn::AbstractString, ext::AbstractString) try oldext = getExtension(fn) if oldext == ext return fn else return "$fn.$ext" end catch return "$fn.$ext" end end """ savefig([plot,] filename) Save a Plot (the current plot if `plot` is not passed) to file. The file type is inferred from the file extension. All backends support png and pdf file types, some also support svg, ps, eps, html and tex. """ function savefig(plt::Plot, fn::AbstractString) # get the extension local ext try ext = getExtension(fn) catch # if we couldn't extract the extension, add the default ext = defaultOutputFormat(plt) fn = addExtension(fn, ext) end # save it func = get(_savemap, ext) do error("Unsupported extension $ext with filename ", fn) end func(plt, fn) end savefig(fn::AbstractString) = savefig(current(), fn) # --------------------------------------------------------- """ gui([plot]) Display a plot using the backends' gui window """ gui(plt::Plot = current()) = display(PlotsDisplay(), plt) # IJulia only... inline display function inline(plt::Plot = current()) isijulia() || error("inline() is IJulia-only") Main.IJulia.clear_output(true) display(Main.IJulia.InlineDisplay(), plt) end function Base.display(::PlotsDisplay, plt::Plot) prepare_output(plt) _display(plt) end # override the REPL display to open a gui window Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::Plot) = gui(plt) _do_plot_show(plt, showval::Bool) = showval && gui(plt) function _do_plot_show(plt, showval::Symbol) showval == :gui && gui(plt) showval in (:inline,:ijulia) && inline(plt) end # --------------------------------------------------------- const _mimeformats = Dict( "application/eps" => "eps", "image/eps" => "eps", "application/pdf" => "pdf", "image/png" => "png", "application/postscript" => "ps", "image/svg+xml" => "svg", "text/plain" => "txt", "application/x-tex" => "tex", ) const _best_html_output_type = KW( :pyplot => :png, :unicodeplots => :txt, :glvisualize => :png ) # 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 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 # for writing to io streams... first prepare, then callback for mime in keys(_mimeformats) @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) where B prepare_output(plt) _show(io, m, plt) end end "Close all open gui windows of the current backend" closeall() = closeall(backend()) # --------------------------------------------------------- # A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert if is_installed("FileIO") @eval import FileIO function _show(io::IO, ::MIME"image/png", plt::Plot) fn = tempname() # first save a pdf file pdf(plt, fn) # load that pdf into a FileIO Stream s = FileIO.load(fn * ".pdf") # save a png pngfn = fn * ".png" FileIO.save(pngfn, s) # now write from the file write(io, readstring(open(pngfn))) end end # function html_output_format(fmt) # if fmt == "png" # @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot) # print(io, "") # end # elseif fmt == "svg" # @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot) # show(io, MIME("image/svg+xml"), plt) # end # else # error("only png or svg allowed. got: $fmt") # end # end # # html_output_format("svg") # --------------------------------------------------------- # IJulia # --------------------------------------------------------- const _ijulia_output = String["text/html"] @require IJulia begin if IJulia.inited export set_ijulia_output function set_ijulia_output(mimestr::AbstractString) # info("Setting IJulia output format to $mimestr") global _ijulia_output _ijulia_output[1] = mimestr end function IJulia.display_dict(plt::Plot) global _ijulia_output Dict{String, String}(_ijulia_output[1] => sprint(show, _ijulia_output[1], plt)) 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) end ENV["MPLBACKEND"] = "Agg" set_ijulia_output("text/html") end end # --------------------------------------------------------- # Atom PlotPane # --------------------------------------------------------- @require Juno begin import Hiccup, Media if Juno.isactive() Media.media(Plot, Media.Plot) _show(io::IO, m::MIME"text/plain", plt::Plot{B}) where {B} = print(io, "Plot{$B}()") function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) end if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") function Juno.render(pane::Juno.PlotPane, plt::Plot) # temporarily overwrite size to be Atom.plotsize sz = plt[:size] jsize = Juno.plotsize() jsize[1] == 0 && (jsize[1] = 400) jsize[2] == 0 && (jsize[2] = 500) plt[:size] = jsize Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz end # special handling for PlotlyJS function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) display(Plots.PlotsDisplay(), plt) end else function Juno.render(pane::Juno.PlotPane, plt::Plot) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." Juno.render(pane, HTML(s)) end end # special handling for plotly... use PlotsDisplay function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend}) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." Juno.render(pane, HTML(s)) end end end