Merge pull request #2612 from daschw/savefig

fix savefig extensions
This commit is contained in:
Daniel Schwabeneder 2020-04-23 00:01:58 +02:00 committed by GitHub
commit 08c0f6d9a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 91 deletions

View File

@ -1,7 +1,7 @@
name = "Plots" name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"] author = ["Tom Breloff (@tbreloff)"]
version = "1.0.13" version = "1.0.14"
[deps] [deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

View File

@ -1,54 +1,51 @@
defaultOutputFormat(plt::Plot) = "png" defaultOutputFormat(plt::Plot) = "png"
function png(plt::Plot, fn::AbstractString) function png(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "png") fn = addExtension(fn, "png")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("image/png"), plt) show(io, MIME("image/png"), plt)
close(io) close(io)
end end
png(fn::AbstractString) = png(current(), fn) png(fn::AbstractString) = png(current(), fn)
function svg(plt::Plot, fn::AbstractString) function svg(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "svg") fn = addExtension(fn, "svg")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("image/svg+xml"), plt) show(io, MIME("image/svg+xml"), plt)
close(io) close(io)
end end
svg(fn::AbstractString) = svg(current(), fn) svg(fn::AbstractString) = svg(current(), fn)
function pdf(plt::Plot, fn::AbstractString) function pdf(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "pdf") fn = addExtension(fn, "pdf")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("application/pdf"), plt) show(io, MIME("application/pdf"), plt)
close(io) close(io)
end end
pdf(fn::AbstractString) = pdf(current(), fn) pdf(fn::AbstractString) = pdf(current(), fn)
function ps(plt::Plot, fn::AbstractString) function ps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "ps") fn = addExtension(fn, "ps")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("application/postscript"), plt) show(io, MIME("application/postscript"), plt)
close(io) close(io)
end end
ps(fn::AbstractString) = ps(current(), fn) ps(fn::AbstractString) = ps(current(), fn)
function eps(plt::Plot, fn::AbstractString) function eps(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "eps") fn = addExtension(fn, "eps")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("image/eps"), plt) show(io, MIME("image/eps"), plt)
close(io) close(io)
end end
eps(fn::AbstractString) = eps(current(), fn) eps(fn::AbstractString) = eps(current(), fn)
function tex(plt::Plot, fn::AbstractString) function tex(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "tex") fn = addExtension(fn, "tex")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("application/x-tex"), plt) show(io, MIME("application/x-tex"), plt)
close(io) close(io)
end end
tex(fn::AbstractString) = tex(current(), fn) tex(fn::AbstractString) = tex(current(), fn)
@ -69,48 +66,39 @@ end
html(fn::AbstractString) = html(current(), fn) html(fn::AbstractString) = html(current(), fn)
function txt(plt::Plot, fn::AbstractString) function txt(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "txt") fn = addExtension(fn, "txt")
io = open(fn, "w") io = open(fn, "w")
show(io, MIME("text/plain"), plt) show(io, MIME("text/plain"), plt)
close(io) close(io)
end end
txt(fn::AbstractString) = txt(current(), fn) txt(fn::AbstractString) = txt(current(), fn)
# ----------------------------------------------------------------
# ----------------------------------------------------------------
const _savemap = Dict( const _savemap = Dict(
"png" => png, "png" => png,
"svg" => svg, "svg" => svg,
"pdf" => pdf, "pdf" => pdf,
"ps" => ps, "ps" => ps,
"eps" => eps, "eps" => eps,
"tex" => tex, "tex" => tex,
"json" => json, "json" => json,
"html" => html, "html" => html,
"tikz" => tex, "tikz" => tex,
"txt" => txt, "txt" => txt,
) )
function getExtension(fn::AbstractString) const _extension_map = Dict("tikz" => "tex")
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) function addExtension(fn::AbstractString, ext::AbstractString)
try oldfn, oldext = splitext(fn)
oldext = getExtension(fn) oldext = chop(oldext, head = 1, tail = 0)
if string(_savemap[oldext]) == ext if get(_extension_map, oldext, oldext) == ext
return fn return fn
else else
return "$fn.$ext" return string(fn, ".", ext)
end end
catch
return "$fn.$ext"
end
end end
""" """
@ -121,27 +109,28 @@ type is inferred from the file extension. All backends support png and pdf
file types, some also support svg, ps, eps, html and tex. file types, some also support svg, ps, eps, html and tex.
""" """
function savefig(plt::Plot, fn::AbstractString) function savefig(plt::Plot, fn::AbstractString)
fn = abspath(expanduser(fn)) fn = abspath(expanduser(fn))
# 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 # get the extension
func = get(_savemap, ext) do fn, ext = splitext(fn)
error("Unsupported extension $ext with filename ", fn) ext = chop(ext, head = 1, tail = 0)
end if isempty(ext)
func(plt, fn) ext = defaultOutputFormat(plt)
end
# save it
if haskey(_savemap, ext)
func = _savemap[ext]
return func(plt, fn)
else
error("Invalid file extension: ", fn)
end
end end
savefig(fn::AbstractString) = savefig(current(), fn) savefig(fn::AbstractString) = savefig(current(), fn)
# --------------------------------------------------------- # ---------------------------------------------------------
""" """
gui([plot]) gui([plot])
@ -164,17 +153,13 @@ end
_do_plot_show(plt, showval::Bool) = showval && gui(plt) _do_plot_show(plt, showval::Bool) = showval && gui(plt)
function _do_plot_show(plt, showval::Symbol) function _do_plot_show(plt, showval::Symbol)
showval == :gui && gui(plt) showval == :gui && gui(plt)
showval in (:inline,:ijulia) && inline(plt) showval in (:inline, :ijulia) && inline(plt)
end end
# --------------------------------------------------------- # ---------------------------------------------------------
const _best_html_output_type = KW( const _best_html_output_type =
:pyplot => :png, KW(:pyplot => :png, :unicodeplots => :txt, :plotlyjs => :html, :plotly => :html)
:unicodeplots => :txt,
:plotlyjs => :html,
:plotly => :html
)
# a backup for html... passes to svg or png depending on the html_output_format arg # a backup for html... passes to svg or png depending on the html_output_format arg
function _show(io::IO, ::MIME"text/html", plt::Plot) function _show(io::IO, ::MIME"text/html", plt::Plot)
@ -184,7 +169,12 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end end
if output_type == :png if output_type == :png
# @info("writing png to html output") # @info("writing png to html output")
print(io, "<img src=\"data:image/png;base64,", base64encode(show, MIME("image/png"), plt), "\" />") print(
io,
"<img src=\"data:image/png;base64,",
base64encode(show, MIME("image/png"), plt),
"\" />",
)
elseif output_type == :svg elseif output_type == :svg
# @info("writing svg to html output") # @info("writing svg to html output")
show(io, MIME("image/svg+xml"), plt) show(io, MIME("image/svg+xml"), plt)
@ -196,7 +186,7 @@ function _show(io::IO, ::MIME"text/html", plt::Plot)
end end
# delegate showable to _show instead # delegate showable to _show instead
function Base.showable(m::M, plt::P) where {M<:MIME, P<:Plot} function Base.showable(m::M, plt::P) where {M <: MIME, P <: Plot}
return hasmethod(_show, Tuple{IO, M, P}) return hasmethod(_show, Tuple{IO, M, P})
end end
@ -205,21 +195,31 @@ function _display(plt::Plot)
end end
# for writing to io streams... first prepare, then callback # for writing to io streams... first prepare, then callback
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml", for mime in (
"application/eps", "application/pdf", "application/postscript", "text/plain",
"application/x-tex", "application/vnd.plotly.v1+json") "text/html",
"image/png",
"image/eps",
"image/svg+xml",
"application/eps",
"application/pdf",
"application/postscript",
"application/x-tex",
"application/vnd.plotly.v1+json",
)
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot) @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
if haskey(io, :juno_plotsize) if haskey(io, :juno_plotsize)
showjuno(io, m, plt) showjuno(io, m, plt)
else else
prepare_output(plt) prepare_output(plt)
_show(io, m, plt) _show(io, m, plt)
end end
return nothing return nothing
end end
end end
Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) = showjuno(io, MIME("text/html"), plt) Base.show(io::IO, m::MIME"application/prs.juno.plotpane+html", plt::Plot) =
showjuno(io, MIME("text/html"), plt)
# default text/plain for all backends # default text/plain for all backends
_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt) _show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt)
@ -258,25 +258,25 @@ function showjuno(io::IO, m, plt)
scale = minimum(jsize[i] / sz[i] for i in 1:2) scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = [s * scale for s in sz] plt[:size] = [s * scale for s in sz]
plt[:dpi] = jratio*Plots.DPI plt[:dpi] = jratio * Plots.DPI
plt[:thickness_scaling] *= scale plt[:thickness_scaling] *= scale
prepare_output(plt) prepare_output(plt)
try try
_showjuno(io, m, plt) _showjuno(io, m, plt)
finally finally
plt[:size] = sz plt[:size] = sz
plt[:dpi] = dpi plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling plt[:thickness_scaling] = thickness_scaling
end end
end end
function _showjuno(io::IO, m::MIME"image/svg+xml", plt) function _showjuno(io::IO, m::MIME"image/svg+xml", plt)
if Symbol(plt.attr[:html_output_format]) :svg if Symbol(plt.attr[:html_output_format]) :svg
throw(MethodError(show, (typeof(m), typeof(plt)))) throw(MethodError(show, (typeof(m), typeof(plt))))
else else
_show(io, m, plt) _show(io, m, plt)
end end
end end
Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = false Base.showable(::MIME"application/prs.juno.plotpane+html", plt::Plot) = false