Merge pull request #1561 from daschw/size

Fix size and dpi for GR and PyPlot
This commit is contained in:
Daniel Schwabeneder 2018-06-23 09:14:52 +02:00 committed by GitHub
commit 4f064d7c02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 21 deletions

View File

@ -65,6 +65,7 @@ const _arg_desc = KW(
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.",
:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.",
:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides",

View File

@ -301,6 +301,7 @@ const _plot_defaults = KW(
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
# the parent layout and the relative bounding box of inset subplots
:dpi => DPI, # dots per inch for images, etc
:thickness_scaling => 1,
:display_type => :auto,
:extra_kwargs => KW(),
)

View File

@ -383,7 +383,7 @@ end
function gr_set_line(lw, style, c) #, a)
GR.setlinetype(gr_linetype[style])
w, h = gr_plot_size
GR.setlinewidth(max(0, lw / ((w + h) * 0.001)))
GR.setlinewidth(_gr_thickness_scaling[1] * max(0, lw / ((w + h) * 0.001)))
gr_set_linecolor(c) #, a)
end
@ -396,6 +396,7 @@ end
# this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses)
const _gr_point_mult = 0.0018 * ones(1)
const _gr_thickness_scaling = ones(1)
# set the font attributes... assumes _gr_point_mult has been populated already
function gr_set_font(f::Font; halign = f.halign, valign = f.valign,
@ -542,6 +543,9 @@ end
function gr_display(plt::Plot, fmt="")
GR.clearws()
_gr_thickness_scaling[1] = plt[:thickness_scaling]
dpi_factor = plt[:dpi] / Plots.DPI
# collect some monitor/display sizes in meters and pixels
display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize()
display_width_ratio = display_width_meters / display_width_px
@ -550,14 +554,6 @@ function gr_display(plt::Plot, fmt="")
# compute the viewport_canvas, normalized to the larger dimension
viewport_canvas = Float64[0,1,0,1]
w, h = plt[:size]
if !haskey(ENV, "PLOTS_TEST")
dpi_factor = plt[:dpi] / DPI
if fmt == "png"
dpi_factor *= 6
end
else
dpi_factor = 1
end
gr_plot_size[:] = [w, h]
if w > h
ratio = float(h) / w
@ -580,7 +576,7 @@ function gr_display(plt::Plot, fmt="")
# update point mult
px_per_pt = px / pt
_gr_point_mult[1] = 1.5 * px_per_pt / max(h,w)
_gr_point_mult[1] = 1.5 * _gr_thickness_scaling[1] * px_per_pt / max(h,w)
# subplots:
for sp in plt.subplots
@ -626,13 +622,14 @@ function gr_get_ticks_size(ticks, i)
end
function _update_min_padding!(sp::Subplot{GRBackend})
dpi = sp.plt[:thickness_scaling]
if !haskey(ENV, "GKSwstype")
if isijulia() || (isdefined(Main, :Juno) && Juno.isactive())
ENV["GKSwstype"] = "svg"
end
end
# Add margin given by the user
leftpad = 2mm + sp[:left_margin]
leftpad = 4mm + sp[:left_margin]
toppad = 2mm + sp[:top_margin]
rightpad = 4mm + sp[:right_margin]
bottompad = 2mm + sp[:bottom_margin]
@ -668,7 +665,7 @@ function _update_min_padding!(sp::Subplot{GRBackend})
if sp[:yaxis][:guide] != ""
leftpad += 4mm
end
sp.minpad = (leftpad, toppad, rightpad, bottompad)
sp.minpad = Tuple(dpi * [leftpad, toppad, rightpad, bottompad])
end
function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
@ -775,7 +772,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# draw the axes
gr_set_font(tickfont(xaxis))
GR.setlinewidth(1)
GR.setlinewidth(sp.plt[:thickness_scaling])
if is3d(sp)
zmin, zmax = gr_lims(zaxis, true)

View File

@ -395,14 +395,14 @@ function py_bbox_title(ax)
end
function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz)
ptsz * plt[:dpi] / DPI
ptsz
end
# ---------------------------------------------------------------------------
# Create the window/figure for this backend.
function _create_backend_figure(plt::Plot{PyPlotBackend})
w,h = map(px2inch, plt[:size])
w,h = map(px2inch, Tuple(s * plt[:dpi] / Plots.DPI for s in plt[:size]))
# # reuse the current figure?
fig = if plt[:overwrite_figure]
@ -955,10 +955,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
w, h = plt[:size]
fig = plt.o
fig[:clear]()
dpi = plt[:dpi]
fig[:set_size_inches](w/dpi, h/dpi, forward = true)
dpi = plt[:thickness_scaling] * plt[:dpi]
fig[:set_size_inches](w/DPI/plt[:thickness_scaling], h/DPI/plt[:thickness_scaling], forward = true)
fig[set_facecolor_sym](py_color(plt[:background_color_outside]))
fig[:set_dpi](dpi)
fig[:set_dpi](plt[:dpi])
# resize the window
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
@ -1209,7 +1209,9 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
rightpad += sp[:right_margin]
bottompad += sp[:bottom_margin]
sp.minpad = (leftpad, toppad, rightpad, bottompad)
dpi_factor = sp.plt[:thickness_scaling] * Plots.DPI / sp.plt[:dpi]
sp.minpad = Tuple(dpi_factor .* [leftpad, toppad, rightpad, bottompad])
end
@ -1358,7 +1360,7 @@ for (mime, fmt) in _pyplot_mimeformats
# figsize = map(px2inch, plt[:size]),
facecolor = fig[:get_facecolor](),
edgecolor = "none",
dpi = plt[:dpi]
dpi = plt[:dpi] * plt[:thickness_scaling]
)
end
end

View File

@ -324,13 +324,20 @@ end
function Juno.render(pane::Juno.PlotPane, plt::Plot)
# temporarily overwrite size to be Atom.plotsize
sz = plt[:size]
dpi = plt[:dpi]
thickness_scaling = plt[:thickness_scaling]
jsize = Juno.plotsize()
jsize[1] == 0 && (jsize[1] = 400)
jsize[2] == 0 && (jsize[2] = 500)
plt[:size] = jsize
scale = minimum(jsize[i] / sz[i] for i in 1:2)
plt[:size] = (s * scale for s in sz)
plt[:dpi] = Plots.DPI
plt[:thickness_scaling] *= scale
Juno.render(pane, HTML(stringmime(MIME("text/html"), plt)))
plt[:size] = sz
plt[:dpi] = dpi
plt[:thickness_scaling] = thickness_scaling
end
# special handling for PlotlyJS
function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend})