Skip to content

Commit 1a8a2f8

Browse files
author
Christopher Doris
committed
simplify display of matplotlib figures
1 parent 5e4e8e0 commit 1a8a2f8

File tree

2 files changed

+87
-26
lines changed

2 files changed

+87
-26
lines changed

src/compat/matplotlib.jl

Lines changed: 86 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,108 @@
1+
struct PyPlotFigure
2+
py::Py
3+
end
4+
export PyPlotFigure
5+
6+
ispy(::PyPlotFigure) = true
7+
getpy(fig::PyPlotFigure) = fig.py
8+
9+
Base.show(io::IO, mime::MIME"image/png", fig::PyPlotFigure) = _pyplot_show(io, mime, fig, "png")
10+
Base.show(io::IO, mime::MIME"image/jpeg", fig::PyPlotFigure) = _pyplot_show(io, mime, fig, "jpeg")
11+
Base.show(io::IO, mime::MIME"image/tiff", fig::PyPlotFigure) = _pyplot_show(io, mime, fig, "tiff")
12+
Base.show(io::IO, mime::MIME"image/svg+xml", fig::PyPlotFigure) = _pyplot_show(io, mime, fig, "svg")
13+
Base.show(io::IO, mime::MIME"application/pdf", fig::PyPlotFigure) = _pyplot_show(io, mime, fig, "pdf")
14+
15+
Base.showable(::MIME"image/png", fig::PyPlotFigure) = _pyplot_showable(fig, "png")
16+
Base.showable(::MIME"image/jpeg", fig::PyPlotFigure) = _pyplot_showable(fig, "jpeg")
17+
Base.showable(::MIME"image/tiff", fig::PyPlotFigure) = _pyplot_showable(fig, "tiff")
18+
Base.showable(::MIME"image/svg+xml", fig::PyPlotFigure) = _pyplot_showable(fig, "svg")
19+
Base.showable(::MIME"application/pdf", fig::PyPlotFigure) = _pyplot_showable(fig, "pdf")
20+
21+
function _pyplot_bytes(fig::Py, format::String)
22+
buf = pyimport("io").BytesIO()
23+
fig.savefig(buf, format=format)
24+
return pyconvert(Vector{UInt8}, buf.getvalue())
25+
end
26+
27+
function _pyplot_show(io::IO, mime::MIME, fig::PyPlotFigure, format::String)
28+
try
29+
write(io, _pyplot_bytes(fig.py, format))
30+
return
31+
catch exc
32+
if exc isa PyException
33+
throw(MethodError(show, (io, mime, fig)))
34+
else
35+
rethrow()
36+
end
37+
end
38+
end
39+
40+
function _pyplot_showable(fig::PyPlotFigure, format::String)
41+
try
42+
_pyplot_bytes(fig.py, format)
43+
return true
44+
catch exc
45+
if exc isa PyException
46+
return false
47+
else
48+
rethrow()
49+
end
50+
end
51+
end
52+
53+
"""
54+
pyplot_gcf(; close=true)
55+
56+
Get the current matplotlib/pyplot/seaborn/etc figure as an object displayable by Julia's display mechanism.
57+
58+
If `close` is true, the figure is also closed.
59+
"""
60+
function pyplot_gcf(; close::Bool=true)
61+
plt = pyimport("matplotlib.pyplot")
62+
fig = plt.gcf()
63+
close && plt.close(fig)
64+
PyPlotFigure(fig)
65+
end
66+
export pyplot_gcf
67+
168
"""
269
pyplot_show([fig]; close=true, [format])
370
4-
Show the matplotlib/pyplot/seaborn/etc figure `fig`, or all open figures if not given, using Julia's display mechanism.
71+
Show the matplotlib/pyplot/seaborn/etc figure `fig` using Julia's display mechanism.
72+
73+
If `fig` is not given, then all open figures are shown.
574
675
If `close` is true, the figure is also closed.
776
877
The `format` specifies the file format of the generated image.
9-
By default this is `pyplot.rcParams["savefig.format"]` or `"png"`.
10-
It can be one of `"png"`, `"jpg"`, `"jpeg"`, `"tif"`, `"tiff"`, `"svg"` or `"pdf"`.
78+
If not given, it is decided by the display.
1179
"""
12-
function pyplot_show(fig; close::Bool = true, format::String = "")
80+
function pyplot_show(fig; close::Bool = true, format::Union{String,Nothing} = nothing)
1381
plt = pyimport("matplotlib.pyplot")
14-
io = pyimport("io")
82+
fig = Py(fig)
1583
if !pyisinstance(fig, plt.Figure)
1684
fig = plt.figure(fig)
1785
end
18-
buf = io.BytesIO()
19-
if isempty(format)
20-
format = pyconvert(String, plt.rcParams.get("savefig.format", "png"))
21-
end
22-
if format ("png", "jpg", "jpeg", "tif", "tiff", "svg", "pdf")
23-
error("invalid format: $format")
24-
end
25-
fig.savefig(buf, format=format)
26-
data = pyconvert(Vector{UInt8}, buf.getvalue())
27-
if close
28-
plt.close(fig)
29-
end
30-
if format == "png"
31-
display(MIME("image/png"), data)
86+
fig = PyPlotFigure(fig)
87+
if format === nothing
88+
display(fig)
89+
elseif format == "png"
90+
display(MIME("image/png"), fig)
3291
elseif format in ("jpg", "jpeg")
33-
display(MIME("image/jpeg"), data)
92+
display(MIME("image/jpeg"), fig)
3493
elseif format in ("tif", "tiff")
35-
display(MIME("image/tiff"), data)
94+
display(MIME("image/tiff"), fig)
3695
elseif format == "svg"
37-
display(MIME("image/svg+xml"), String(data))
96+
display(MIME("image/svg+xml"), fig)
3897
elseif format == "pdf"
39-
display(MIME("application/pdf"), data)
98+
display(MIME("application/pdf"), fig)
4099
else
41-
@assert false
100+
error("invalid format: $format")
42101
end
43-
nothing
102+
close && plt.close(fig)
103+
return
44104
end
105+
45106
function pyplot_show(; opts...)
46107
plt = pysysmodule.modules.get("matplotlib.pyplot", nothing)
47108
if !pyisnone(plt)

src/compat/multimedia.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,5 @@ end
113113
function init_pyshow()
114114
pyshow_add_rule(pyshow_rule_mimebundle)
115115
pyshow_add_rule(pyshow_rule_repr)
116-
pyshow_add_rule(pyshow_rule_savefig)
116+
# pyshow_add_rule(pyshow_rule_savefig)
117117
end

0 commit comments

Comments
 (0)