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") writemime(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) # ---------------------------------------------------------------- const _savemap = Dict( "png" => png, "svg" => svg, "pdf" => pdf, "ps" => ps, "eps" => eps, "tex" => tex, ) 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 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(plt::Plot = current()) = display(PlotsDisplay(), plt) 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) # --------------------------------------------------------- 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", ) 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{B}(io::IO, m, plt::Plot{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{B}(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) prepare_output(plt) _show(io, m, plt) end end 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, readall(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"] function setup_ijulia() # override IJulia inline display if isijulia() @eval begin import IJulia 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 end set_ijulia_output("text/html") end end # --------------------------------------------------------- # Atom PlotPane # --------------------------------------------------------- function setup_atom() if isatom() @eval import Atom, Media Media.media(Plot, Media.Plot) # default text/plain so it doesn't complain function Base.show{B}(io::IO, ::MIME"text/plain", plt::Plot{B}) print(io, "Plot{$B}()") end function Media.render(e::Atom.Editor, plt::Plot) Media.render(e, nothing) end if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") # this is like "display"... sends an html div with the plot to the PlotPane function Media.render(pane::Atom.PlotPane, plt::Plot) # temporarily overwrite size to be Atom.plotsize sz = plt[:size] plt[:size] = Juno.plotsize() Media.render(pane, Atom.div(".fill", Atom.HTML(stringmime(MIME("text/html"), plt)))) plt[:size] = sz end else # function Media.render(pane::Atom.PlotPane, plt::Plot) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." Media.render(pane, Atom.div(Atom.HTML(s))) end end # special handling for plotly... use PlotsDisplay function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend}) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. The plotly and plotlyjs backends cannot render in the PlotPane due to javascript issues." Media.render(pane, Atom.div(Atom.HTML(s))) end # special handling for PlotlyJS to pass through to that render method function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyJSBackend}) Plots.prepare_output(plt) Media.render(pane, plt.o) end end end