pyplot display fixes for #308; setxyz fix; generic png conversion from pdf; pgfplots pdf output

This commit is contained in:
Thomas Breloff 2016-06-09 17:13:16 -04:00
parent 2a3029edb4
commit 514284e784
4 changed files with 49 additions and 75 deletions

View File

@ -299,9 +299,18 @@ function _writemime(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend
writemime(io, mime, plt.o) writemime(io, mime, plt.o)
end end
function _writemime(io::IO, mime::MIME"image/png", plt::Plot{PGFPlotsBackend}) function _writemime(io::IO, mime::MIME"application/pdf", plt::Plot{PGFPlotsBackend})
_make_pgf_plot!(plt) _make_pgf_plot!(plt)
writemime(io, mime, plt.o)
# prepare the object
pgfplt = PGFPlots.plot(plt.o)
# save a pdf
fn = tempname()*".pdf"
PGFPlots.save(PGFPlots.PDF(fn), pgfplt)
# read it into io
write(io, readall(open(fn)))
end end
function _display(plt::Plot{PGFPlotsBackend}) function _display(plt::Plot{PGFPlotsBackend})

View File

@ -57,6 +57,9 @@ subplotSupported(::PyPlotBackend) = true
function _initialize_backend(::PyPlotBackend) function _initialize_backend(::PyPlotBackend)
@eval begin @eval begin
# see: https://github.com/tbreloff/Plots.jl/issues/308
ENV["OVERRIDE_PYPLOT_DISPLAY"] = true
import PyPlot import PyPlot
export PyPlot export PyPlot
const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors")) const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors"))
@ -70,22 +73,8 @@ function _initialize_backend(::PyPlotBackend)
const pytransforms = PyPlot.pywrap(PyPlot.pyimport("matplotlib.transforms")) const pytransforms = PyPlot.pywrap(PyPlot.pyimport("matplotlib.transforms"))
end end
# we don't want every command to update the figure
PyPlot.ioff() PyPlot.ioff()
# if !isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
# PyPlot.ioff() # stops wierd behavior of displaying incomplete graphs in IJulia
# # # TODO: how the hell can I use PyQt4??
# # "pyqt4"=>:qt_pyqt4
# # PyPlot.backend[1] = "pyqt4"
# # PyPlot.gui[1] = :qt_pyqt4
# # PyPlot.switch_backend("Qt4Agg")
# # only turn on the gui if we want it
# if PyPlot.gui != :none
# PyPlot.pygui(true)
# end
# end
end end
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
@ -301,12 +290,6 @@ drawax(ax) = ax[:draw](renderer(ax[:get_figure]()))
# get a vector [left, right, bottom, top] in PyPlot coords (origin is bottom-left!) # get a vector [left, right, bottom, top] in PyPlot coords (origin is bottom-left!)
get_extents(obj) = obj[:get_window_extent]()[:get_points]() get_extents(obj) = obj[:get_window_extent]()[:get_points]()
# # bounding box of the figure
# function py_bbox_fig(fig)
# fl, fr, fb, ft = get_extents(fig)
# BoundingBox(0px, 0px, (fr-fl)*px, (ft-fb)*px)
# end
# py_bbox_fig(plt::Plot) = py_bbox_fig(plt.o)
# compute a bounding box (with origin top-left), however pyplot gives coords with origin bottom-left # compute a bounding box (with origin top-left), however pyplot gives coords with origin bottom-left
function py_bbox(obj) function py_bbox(obj)
@ -359,24 +342,15 @@ end
function _create_backend_figure(plt::Plot{PyPlotBackend}) function _create_backend_figure(plt::Plot{PyPlotBackend})
w,h = map(px2inch, plt[:size]) w,h = map(px2inch, plt[:size])
# reuse the current figure? # # reuse the current figure?
fig = if plt[:overwrite_figure] fig = if plt[:overwrite_figure]
PyPlot.gcf() PyPlot.gcf()
else else
PyPlot.figure() PyPlot.figure()
end end
# # update the specs
# fig[:set_size_inches](w, h, forward = true)
# fig[:set_facecolor](getPyPlotColor(plt[:background_color_outside]))
# fig[:set_dpi](DPI)
# # fig[:set_tight_layout](true)
# clear the figure # clear the figure
PyPlot.clf() PyPlot.clf()
# # resize the window
# PyPlot.plt[:get_current_fig_manager]()[:resize](plt[:size]...)
fig fig
end end
@ -1099,13 +1073,6 @@ function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
# gotta do this to ensure both axes are included # gotta do this to ensure both axes are included
labels = [] labels = []
handles = [] handles = []
# for series in plt.series_list
# if get_subplot(series) === sp &&
# series.d[:label] != "" &&
# !(series.d[:seriestype] in (
# :hexbin,:histogram2d,:hline,:vline,
# :contour,:contour3d,:surface,:wireframe,
# :heatmap,:path3d,:scatter3d, :pie, :image))
for series in series_list(sp) for series in series_list(sp)
if should_add_to_legend(series) if should_add_to_legend(series)
# add a line/marker and a label # add a line/marker and a label
@ -1144,30 +1111,6 @@ end
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# # add legend, update colors and positions, then draw
# function finalizePlot(plt::Plot{PyPlotBackend})
# # for sp in plt.subplots
# # # ax = getLeftAxis(plt)
# # ax = getAxis(sp)
# # ax == nothing && continue
# # addPyPlotLegend(plt, sp, ax)
# # for asym in (:xaxis, :yaxis, :zaxis)
# # updateAxisColors(ax, sp.attr[asym])
# # end
# # end
# drawfig(plt.o)
# # plt.layout.bbox = py_bbox_fig(plt)
#
# # TODO: these should be called outside of pyplot... how?
# update_child_bboxes!(plt.layout)
# _update_position!(plt.layout)
#
# PyPlot.draw()
# end
# function _before_layout_calcs(plt::Plot{PyPlotBackend})
# drawfig(plt.o)
# end
# Use the bounding boxes (and methods left/top/right/bottom/width/height) `sp.bbox` and `sp.plotarea` to # Use the bounding boxes (and methods left/top/right/bottom/width/height) `sp.bbox` and `sp.plotarea` to
# position the subplot in the backend. # position the subplot in the backend.
@ -1175,7 +1118,6 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
for sp in plt.subplots for sp in plt.subplots
ax = sp.o ax = sp.o
ax == nothing && return ax == nothing && return
# figw, figh = size(py_bbox_fig(sp.plt))
figw, figh = sp.plt[:size] figw, figh = sp.plt[:size]
figw, figh = figw*px, figh*px figw, figh = figw*px, figh*px
pcts = bbox_to_pcts(sp.plotarea, figw, figh) pcts = bbox_to_pcts(sp.plotarea, figw, figh)
@ -1197,14 +1139,7 @@ end
# display/output # display/output
function _display(plt::Plot{PyPlotBackend}) function _display(plt::Plot{PyPlotBackend})
# if isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
# display(plt.o)
# end
# PyPlot.ion()
# PyPlot.pygui(false)
plt.o[:show]() plt.o[:show]()
# PyPlot.pygui(true)
# PyPlot.ioff()
end end

View File

@ -151,6 +151,36 @@ for mime in keys(_mimeformats)
end end
end end
# ---------------------------------------------------------
# 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 begin
import FileIO
function _writemime(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
end
# function html_output_format(fmt) # function html_output_format(fmt)
# if fmt == "png" # if fmt == "png"
# @eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot) # @eval function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)

View File

@ -508,9 +508,9 @@ function setxyz!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer)
series = plt.series_list[i] series = plt.series_list[i]
series.d[:x], series.d[:y], series.d[:z] = xyz series.d[:x], series.d[:y], series.d[:z] = xyz
sp = series.d[:subplot] sp = series.d[:subplot]
expand_extrema!(sp.attr[:xaxis], xy[1]) expand_extrema!(sp.attr[:xaxis], xyz[1])
expand_extrema!(sp.attr[:yaxis], xy[2]) expand_extrema!(sp.attr[:yaxis], xyz[2])
expand_extrema!(sp.attr[:zaxis], xy[3]) expand_extrema!(sp.attr[:zaxis], xyz[3])
_series_updated(plt, series) _series_updated(plt, series)
end end