postpone match logic and add color_or_nothing; update pyplot for attr changes; move some pyplot logic later
This commit is contained in:
parent
52d325b446
commit
e129c29e2f
10
src/Plots.jl
10
src/Plots.jl
@ -25,8 +25,8 @@ export
|
|||||||
AVec,
|
AVec,
|
||||||
AMat,
|
AMat,
|
||||||
KW,
|
KW,
|
||||||
attr,
|
# attr,
|
||||||
attr!,
|
# attr!,
|
||||||
|
|
||||||
wrap,
|
wrap,
|
||||||
set_theme,
|
set_theme,
|
||||||
@ -118,9 +118,9 @@ export
|
|||||||
text,
|
text,
|
||||||
font,
|
font,
|
||||||
Axis,
|
Axis,
|
||||||
xaxis,
|
# xaxis,
|
||||||
yaxis,
|
# yaxis,
|
||||||
zaxis,
|
# zaxis,
|
||||||
stroke,
|
stroke,
|
||||||
brush,
|
brush,
|
||||||
Surface,
|
Surface,
|
||||||
|
|||||||
141
src/args.jl
141
src/args.jl
@ -798,19 +798,97 @@ function slice_arg!(d_in::KW, d_out::KW, k::Symbol, default_value, idx::Int = 1;
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# if the value is `:match` then we take whatever match_color is.
|
# -----------------------------------------------------------------------------
|
||||||
# this is mainly used for cascading defaults for foreground and background colors
|
|
||||||
function color_or_match!(d::KW, k::Symbol, match_color)
|
# # if the value is `:match` then we take whatever match_color is.
|
||||||
|
# # this is mainly used for cascading defaults for foreground and background colors
|
||||||
|
# function color_or_match!(d::KW, k::Symbol, match_color)
|
||||||
|
# v = d[k]
|
||||||
|
# d[k] = if v == :match
|
||||||
|
# match_color
|
||||||
|
# elseif v == nothing
|
||||||
|
# colorscheme(RGBA(0,0,0,0))
|
||||||
|
# else
|
||||||
|
# v
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
function color_or_nothing!(d::KW, k::Symbol)
|
||||||
v = d[k]
|
v = d[k]
|
||||||
d[k] = if v == :match
|
d[k] = if v == nothing
|
||||||
match_color
|
|
||||||
elseif v == nothing
|
|
||||||
colorscheme(RGBA(0,0,0,0))
|
colorscheme(RGBA(0,0,0,0))
|
||||||
else
|
else
|
||||||
v
|
v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# when a value can be `:match`, this is the key that should be used instead for value retrieval
|
||||||
|
const _match_map = KW(
|
||||||
|
:background_color_outside => :background_color,
|
||||||
|
:background_color_legend => :background_color_subplot,
|
||||||
|
:background_color_inside => :background_color_subplot,
|
||||||
|
:foreground_color_legend => :foreground_color_subplot,
|
||||||
|
:foreground_color_grid => :foreground_color_subplot,
|
||||||
|
:foreground_color_title => :foreground_color_subplot,
|
||||||
|
:left_margin => :margin,
|
||||||
|
:top_margin => :margin,
|
||||||
|
:right_margin => :margin,
|
||||||
|
:bottom_margin => :margin,
|
||||||
|
)
|
||||||
|
|
||||||
|
# these can match values from the parent container (axis --> subplot --> plot)
|
||||||
|
const _match_map2 = KW(
|
||||||
|
:background_color_subplot => :background_color,
|
||||||
|
:foreground_color_subplot => :foreground_color,
|
||||||
|
:foreground_color_axis => :foreground_color_subplot,
|
||||||
|
:foreground_color_border => :foreground_color_subplot,
|
||||||
|
:foreground_color_guide => :foreground_color_subplot,
|
||||||
|
:foreground_color_text => :foreground_color_subplot,
|
||||||
|
)
|
||||||
|
|
||||||
|
# properly retrieve from plt.attr, passing `:match` to the correct key
|
||||||
|
function Base.getindex(plt::Plot, k::Symbol)
|
||||||
|
v = plt.attr[k]
|
||||||
|
if v == :match
|
||||||
|
plt[_match_map[k]]
|
||||||
|
else
|
||||||
|
v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# properly retrieve from sp.attr, passing `:match` to the correct key
|
||||||
|
function Base.getindex(sp::Subplot, k::Symbol)
|
||||||
|
v = sp.attr[k]
|
||||||
|
if v == :match
|
||||||
|
if haskey(_match_map2, k)
|
||||||
|
sp.plt[_match_map2[k]]
|
||||||
|
else
|
||||||
|
sp[_match_map[k]]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# properly retrieve from axis.attr, passing `:match` to the correct key
|
||||||
|
function Base.getindex(axis::Axis, k::Symbol)
|
||||||
|
v = axis.d[k]
|
||||||
|
if v == :match
|
||||||
|
if haskey(_match_map2, k)
|
||||||
|
axis.sp[_match_map2[k]]
|
||||||
|
else
|
||||||
|
axis[_match_map[k]]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# update attr from an input dictionary
|
# update attr from an input dictionary
|
||||||
function _update_plot_args(plt::Plot, d_in::KW)
|
function _update_plot_args(plt::Plot, d_in::KW)
|
||||||
@ -827,7 +905,8 @@ function _update_plot_args(plt::Plot, d_in::KW)
|
|||||||
end
|
end
|
||||||
pargs[:background_color] = bg
|
pargs[:background_color] = bg
|
||||||
pargs[:foreground_color] = convertColor(fg)
|
pargs[:foreground_color] = convertColor(fg)
|
||||||
color_or_match!(pargs, :background_color_outside, bg)
|
# color_or_match!(pargs, :background_color_outside, bg)
|
||||||
|
color_or_nothing!(pargs, :background_color_outside)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -848,22 +927,30 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I
|
|||||||
end
|
end
|
||||||
|
|
||||||
# background colors
|
# background colors
|
||||||
bg = color_or_match!(spargs, :background_color_subplot, pargs[:background_color])
|
# bg = color_or_match!(spargs, :background_color_subplot, pargs[:background_color])
|
||||||
|
color_or_nothing!(spargs, :background_color_subplot)
|
||||||
|
bg = sp[:background_color_subplot]
|
||||||
spargs[:color_palette] = get_color_palette(spargs[:color_palette], bg, 30)
|
spargs[:color_palette] = get_color_palette(spargs[:color_palette], bg, 30)
|
||||||
color_or_match!(spargs, :background_color_legend, bg)
|
# color_or_match!(spargs, :background_color_legend, bg)
|
||||||
color_or_match!(spargs, :background_color_inside, bg)
|
color_or_nothing!(spargs, :background_color_legend)
|
||||||
|
# color_or_match!(spargs, :background_color_inside, bg)
|
||||||
|
color_or_nothing!(spargs, :background_color_inside)
|
||||||
|
|
||||||
# foreground colors
|
# foreground colors
|
||||||
fg = color_or_match!(spargs, :foreground_color_subplot, pargs[:foreground_color])
|
# fg = color_or_match!(spargs, :foreground_color_subplot, pargs[:foreground_color])
|
||||||
color_or_match!(spargs, :foreground_color_legend, fg)
|
color_or_nothing!(spargs, :foreground_color_subplot)
|
||||||
color_or_match!(spargs, :foreground_color_grid, fg)
|
# color_or_match!(spargs, :foreground_color_legend, fg)
|
||||||
color_or_match!(spargs, :foreground_color_title, fg)
|
color_or_nothing!(spargs, :foreground_color_legend)
|
||||||
|
# color_or_match!(spargs, :foreground_color_grid, fg)
|
||||||
|
color_or_nothing!(spargs, :foreground_color_grid)
|
||||||
|
# color_or_match!(spargs, :foreground_color_title, fg)
|
||||||
|
color_or_nothing!(spargs, :foreground_color_title)
|
||||||
|
|
||||||
for k in (:left_margin, :top_margin, :right_margin, :bottom_margin)
|
# for k in (:left_margin, :top_margin, :right_margin, :bottom_margin)
|
||||||
if spargs[k] == :match
|
# if spargs[k] == :match
|
||||||
spargs[k] = spargs[:margin]
|
# spargs[k] = spargs[:margin]
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
for letter in (:x, :y, :z)
|
for letter in (:x, :y, :z)
|
||||||
# get (maybe initialize) the axis
|
# get (maybe initialize) the axis
|
||||||
@ -871,7 +958,7 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I
|
|||||||
axis = if haskey(spargs, axissym)
|
axis = if haskey(spargs, axissym)
|
||||||
spargs[axissym]
|
spargs[axissym]
|
||||||
else
|
else
|
||||||
spargs[axissym] = Axis(letter)
|
spargs[axissym] = Axis(sp, letter)
|
||||||
end
|
end
|
||||||
|
|
||||||
# grab magic args (for example `xaxis = (:flip, :log)`)
|
# grab magic args (for example `xaxis = (:flip, :log)`)
|
||||||
@ -898,11 +985,15 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I
|
|||||||
# update the axis
|
# update the axis
|
||||||
update!(axis, args...; kw...)
|
update!(axis, args...; kw...)
|
||||||
|
|
||||||
# update the axis colors
|
# # update the axis colors
|
||||||
color_or_match!(axis.d, :foreground_color_axis, fg)
|
# color_or_match!(axis.d, :foreground_color_axis, fg)
|
||||||
color_or_match!(axis.d, :foreground_color_border, fg)
|
color_or_nothing!(axis.d, :foreground_color_axis)
|
||||||
color_or_match!(axis.d, :foreground_color_guide, fg)
|
# color_or_match!(axis.d, :foreground_color_border, fg)
|
||||||
color_or_match!(axis.d, :foreground_color_text, fg)
|
color_or_nothing!(axis.d, :foreground_color_border)
|
||||||
|
# color_or_match!(axis.d, :foreground_color_guide, fg)
|
||||||
|
color_or_nothing!(axis.d, :foreground_color_guide)
|
||||||
|
# color_or_match!(axis.d, :foreground_color_text, fg)
|
||||||
|
color_or_nothing!(axis.d, :foreground_color_text)
|
||||||
|
|
||||||
# TODO: need to handle linking here?
|
# TODO: need to handle linking here?
|
||||||
end
|
end
|
||||||
|
|||||||
12
src/axes.jl
12
src/axes.jl
@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
xaxis(args...; kw...) = Axis(:x, args...; kw...)
|
# xaxis(args...; kw...) = Axis(:x, args...; kw...)
|
||||||
yaxis(args...; kw...) = Axis(:y, args...; kw...)
|
# yaxis(args...; kw...) = Axis(:y, args...; kw...)
|
||||||
zaxis(args...; kw...) = Axis(:z, args...; kw...)
|
# zaxis(args...; kw...) = Axis(:z, args...; kw...)
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
function Axis(letter::Symbol, args...; kw...)
|
function Axis(sp::Subplot, letter::Symbol, args...; kw...)
|
||||||
# init with values from _plot_defaults
|
# init with values from _plot_defaults
|
||||||
d = KW(
|
d = KW(
|
||||||
:letter => letter,
|
:letter => letter,
|
||||||
@ -21,7 +21,7 @@ function Axis(letter::Symbol, args...; kw...)
|
|||||||
d[:discrete_values] = []
|
d[:discrete_values] = []
|
||||||
|
|
||||||
# update the defaults
|
# update the defaults
|
||||||
update!(Axis(d), args...; kw...)
|
update!(Axis(sp, d), args...; kw...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function process_axis_arg!(d::KW, arg, letter = "")
|
function process_axis_arg!(d::KW, arg, letter = "")
|
||||||
@ -89,7 +89,7 @@ end
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true)
|
Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true)
|
||||||
Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k)
|
# Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k)
|
||||||
Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...)
|
Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...)
|
||||||
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k)
|
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k)
|
||||||
Base.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
|
Base.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
|
||||||
|
|||||||
@ -138,7 +138,7 @@ function _update_plot_object(plt::Plot{PlotlyJSBackend})
|
|||||||
pdict = plotly_layout(plt)
|
pdict = plotly_layout(plt)
|
||||||
syncplot = plt.o
|
syncplot = plt.o
|
||||||
w,h = plt.attr[:size]
|
w,h = plt.attr[:size]
|
||||||
DD(pdict)
|
# DD(pdict)
|
||||||
PlotlyJS.relayout!(syncplot, pdict, width = w, height = h)
|
PlotlyJS.relayout!(syncplot, pdict, width = w, height = h)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -355,41 +355,35 @@ end
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function pyplot_figure(attr::KW)
|
# Create the window/figure for this backend.
|
||||||
w,h = map(px2inch, attr[:size])
|
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
||||||
|
w,h = map(px2inch, plt[:size])
|
||||||
|
|
||||||
# reuse the current figure?
|
# reuse the current figure?
|
||||||
fig = if attr[:overwrite_figure]
|
fig = if plt[:overwrite_figure]
|
||||||
PyPlot.gcf()
|
PyPlot.gcf()
|
||||||
else
|
else
|
||||||
PyPlot.figure()
|
PyPlot.figure()
|
||||||
end
|
end
|
||||||
|
|
||||||
# update the specs
|
# # update the specs
|
||||||
fig[:set_size_inches](w, h, forward = true)
|
# fig[:set_size_inches](w, h, forward = true)
|
||||||
fig[:set_facecolor](getPyPlotColor(attr[:background_color_outside]))
|
# fig[:set_facecolor](getPyPlotColor(plt[:background_color_outside]))
|
||||||
fig[:set_dpi](DPI)
|
# fig[:set_dpi](DPI)
|
||||||
# fig[:set_tight_layout](true)
|
# # fig[:set_tight_layout](true)
|
||||||
|
|
||||||
# clear the figure
|
# clear the figure
|
||||||
PyPlot.clf()
|
PyPlot.clf()
|
||||||
|
|
||||||
# resize the window
|
# # resize the window
|
||||||
PyPlot.plt[:get_current_fig_manager]()[:resize](attr[:size]...)
|
# PyPlot.plt[:get_current_fig_manager]()[:resize](plt[:size]...)
|
||||||
fig
|
fig
|
||||||
end
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Create the window/figure for this backend.
|
|
||||||
function _create_backend_figure(plt::Plot{PyPlotBackend})
|
|
||||||
pyplot_figure(plt.attr)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set up the subplot within the backend object.
|
# Set up the subplot within the backend object.
|
||||||
function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
|
function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
|
||||||
fig = plt.o
|
fig = plt.o
|
||||||
proj = sp.attr[:projection]
|
proj = sp[:projection]
|
||||||
proj = (proj in (nothing,:none) ? nothing : string(proj))
|
proj = (proj in (nothing,:none) ? nothing : string(proj))
|
||||||
|
|
||||||
# add a new axis, and force it to create a new one by setting a distinct label
|
# add a new axis, and force it to create a new one by setting a distinct label
|
||||||
@ -400,27 +394,7 @@ function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend
|
|||||||
)
|
)
|
||||||
sp.o = ax
|
sp.o = ax
|
||||||
end
|
end
|
||||||
#
|
|
||||||
# # Use the bounding boxes (and methods left/top/right/bottom/width/height) `sp.bbox` and `sp.plotarea` to
|
|
||||||
# # position the subplot in the backend.
|
|
||||||
# function _update_position!(sp::Subplot{PyPlotBackend})
|
|
||||||
# ax = sp.o
|
|
||||||
# ax == nothing && return
|
|
||||||
# # figw, figh = size(py_bbox_fig(sp.plt))
|
|
||||||
# figw, figh = sp.plt.attr[:size]
|
|
||||||
# figw, figh = figw*px, figh*px
|
|
||||||
# pcts = bbox_to_pcts(sp.plotarea, figw, figh)
|
|
||||||
# ax[:set_position](pcts)
|
|
||||||
#
|
|
||||||
# # set the cbar position if there is one
|
|
||||||
# if haskey(sp.attr, :cbar_ax)
|
|
||||||
# cbw = sp.attr[:cbar_width]
|
|
||||||
# # this is the bounding box of just the colors of the colorbar (not labels)
|
|
||||||
# cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox)+2mm, _cbar_width-1mm, height(sp.bbox)-4mm)
|
|
||||||
# pcts = bbox_to_pcts(cb_bbox, figw, figh)
|
|
||||||
# sp.attr[:cbar_ax][:set_position](pcts)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -747,7 +721,7 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
# if !(eltype(z) <: Number)
|
# if !(eltype(z) <: Number)
|
||||||
# z, discrete_colorbar_values = indices_and_unique_values(z)
|
# z, discrete_colorbar_values = indices_and_unique_values(z)
|
||||||
# end
|
# end
|
||||||
dvals = sp.attr[:zaxis][:discrete_values]
|
dvals = sp[:zaxis][:discrete_values]
|
||||||
if !isempty(dvals)
|
if !isempty(dvals)
|
||||||
discrete_colorbar_values = dvals
|
discrete_colorbar_values = dvals
|
||||||
end
|
end
|
||||||
@ -780,12 +754,6 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
handle = ax[:pie](y;
|
handle = ax[:pie](y;
|
||||||
# colors = # a vector of colors?
|
# colors = # a vector of colors?
|
||||||
labels = pie_labels(sp, series)
|
labels = pie_labels(sp, series)
|
||||||
# labels = if haskey(d,:x_discrete_indices)
|
|
||||||
# dvals = sp.attr[:xaxis].d[:discrete_values]
|
|
||||||
# [dvals[idx] for idx in d[:x_discrete_indices]]
|
|
||||||
# else
|
|
||||||
# d[:x]
|
|
||||||
# end
|
|
||||||
)
|
)
|
||||||
push!(handles, handle)
|
push!(handles, handle)
|
||||||
end
|
end
|
||||||
@ -796,14 +764,14 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
handleSmooth(plt, ax, d, d[:smooth])
|
handleSmooth(plt, ax, d, d[:smooth])
|
||||||
|
|
||||||
# add the colorbar legend
|
# add the colorbar legend
|
||||||
if needs_colorbar && sp.attr[:colorbar] != :none
|
if needs_colorbar && sp[:colorbar] != :none
|
||||||
# add keyword args for a discrete colorbar
|
# add keyword args for a discrete colorbar
|
||||||
handle = handles[end]
|
handle = handles[end]
|
||||||
kw = KW()
|
kw = KW()
|
||||||
if discrete_colorbar_values != nothing
|
if discrete_colorbar_values != nothing
|
||||||
locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
|
locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
|
||||||
# kw[:values] = 1:length(discrete_colorbar_values)
|
# kw[:values] = 1:length(discrete_colorbar_values)
|
||||||
kw[:values] = sp.attr[:zaxis][:continuous_values]
|
kw[:values] = sp[:zaxis][:continuous_values]
|
||||||
kw[:ticks] = locator
|
kw[:ticks] = locator
|
||||||
kw[:format] = formatter
|
kw[:format] = formatter
|
||||||
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
|
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
|
||||||
@ -817,9 +785,6 @@ function _series_added(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
sp.attr[:cbar_ax] = cbax
|
sp.attr[:cbar_ax] = cbax
|
||||||
end
|
end
|
||||||
|
|
||||||
# this sets the bg color inside the grid
|
|
||||||
ax[:set_axis_bgcolor](getPyPlotColor(d[:subplot].attr[:background_color_inside]))
|
|
||||||
|
|
||||||
# handle area filling
|
# handle area filling
|
||||||
fillrange = d[:fillrange]
|
fillrange = d[:fillrange]
|
||||||
if fillrange != nothing && st != :contour
|
if fillrange != nothing && st != :contour
|
||||||
@ -866,16 +831,9 @@ end
|
|||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
# get_axis and update_limits! should be moved to subplots.jl? or axes.jl?
|
|
||||||
|
|
||||||
get_axis(sp::Subplot, letter::Symbol) = sp.attr[Symbol(letter, :axis)]
|
|
||||||
|
|
||||||
function update_limits!(sp::Subplot{PyPlotBackend}, series::Series, letters)
|
function update_limits!(sp::Subplot{PyPlotBackend}, series::Series, letters)
|
||||||
for letter in letters
|
for letter in letters
|
||||||
# axis = get_axis(sp, letter)
|
setPyPlotLims(sp.o, sp[Symbol(letter, :axis)])
|
||||||
# expand_extrema!(axis, series.d[letter])
|
|
||||||
# set_lims!(sp, axis)
|
|
||||||
setPyPlotLims(sp.o, sp.attr[Symbol(letter, :axis)])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1000,21 +958,31 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
||||||
|
# update the specs
|
||||||
|
w, h = plt[:size]
|
||||||
|
fig = plt.o
|
||||||
|
fig[:set_size_inches](px2inch(w), px2inch(h), forward = true)
|
||||||
|
fig[:set_facecolor](getPyPlotColor(plt[:background_color_outside]))
|
||||||
|
fig[:set_dpi](DPI)
|
||||||
|
|
||||||
|
# resize the window
|
||||||
|
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
|
||||||
|
|
||||||
|
# update subplots
|
||||||
for sp in plt.subplots
|
for sp in plt.subplots
|
||||||
attr = sp.attr
|
|
||||||
ax = getAxis(sp)
|
ax = getAxis(sp)
|
||||||
if ax == nothing
|
if ax == nothing
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
|
|
||||||
# add the annotations
|
# add the annotations
|
||||||
for ann in attr[:annotations]
|
for ann in sp[:annotations]
|
||||||
createPyPlotAnnotationObject(sp, ann...)
|
createPyPlotAnnotationObject(sp, ann...)
|
||||||
end
|
end
|
||||||
|
|
||||||
# title
|
# title
|
||||||
if haskey(attr, :title)
|
if sp[:title] != ""
|
||||||
loc = lowercase(string(attr[:title_location]))
|
loc = lowercase(string(sp[:title_location]))
|
||||||
field = if loc == "left"
|
field = if loc == "left"
|
||||||
:_left_title
|
:_left_title
|
||||||
elseif loc == "right"
|
elseif loc == "right"
|
||||||
@ -1022,16 +990,16 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
else
|
else
|
||||||
:title
|
:title
|
||||||
end
|
end
|
||||||
ax[field][:set_text](attr[:title])
|
ax[field][:set_text](sp[:title])
|
||||||
ax[field][:set_fontsize](attr[:titlefont].pointsize)
|
ax[field][:set_fontsize](sp[:titlefont].pointsize)
|
||||||
ax[field][:set_color](getPyPlotColor(attr[:foreground_color_title]))
|
ax[field][:set_color](getPyPlotColor(sp[:foreground_color_title]))
|
||||||
# ax[:set_title](attr[:title], loc = loc)
|
# ax[:set_title](sp[:title], loc = loc)
|
||||||
end
|
end
|
||||||
|
|
||||||
# axis attributes
|
# axis attributes
|
||||||
for letter in (:x, :y, :z)
|
for letter in (:x, :y, :z)
|
||||||
axissym = Symbol(letter, :axis)
|
axissym = Symbol(letter, :axis)
|
||||||
axis = attr[axissym]
|
axis = sp[axissym]
|
||||||
haskey(ax, axissym) || continue
|
haskey(ax, axissym) || continue
|
||||||
applyPyPlotScale(ax, axis[:scale], letter)
|
applyPyPlotScale(ax, axis[:scale], letter)
|
||||||
setPyPlotLims(ax, axis)
|
setPyPlotLims(ax, axis)
|
||||||
@ -1045,8 +1013,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
lab[:set_fontsize](axis[:tickfont].pointsize)
|
lab[:set_fontsize](axis[:tickfont].pointsize)
|
||||||
lab[:set_rotation](axis[:rotation])
|
lab[:set_rotation](axis[:rotation])
|
||||||
end
|
end
|
||||||
if get(attr, :grid, false)
|
if sp[:grid]
|
||||||
fgcolor = getPyPlotColor(attr[:foreground_color_grid])
|
fgcolor = getPyPlotColor(sp[:foreground_color_grid])
|
||||||
ax[axissym][:grid](true, color = fgcolor)
|
ax[axissym][:grid](true, color = fgcolor)
|
||||||
ax[:set_axisbelow](true)
|
ax[:set_axisbelow](true)
|
||||||
end
|
end
|
||||||
@ -1054,14 +1022,18 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
|
|||||||
end
|
end
|
||||||
|
|
||||||
# aspect ratio
|
# aspect ratio
|
||||||
aratio = get(attr, :aspect_ratio, :none)
|
aratio = sp[:aspect_ratio]
|
||||||
if aratio != :none
|
if aratio != :none
|
||||||
ax[:set_aspect](isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C")
|
ax[:set_aspect](isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# legend
|
||||||
addPyPlotLegend(plt, sp, ax)
|
addPyPlotLegend(plt, sp, ax)
|
||||||
|
|
||||||
|
# this sets the bg color inside the grid
|
||||||
|
ax[:set_axis_bgcolor](getPyPlotColor(sp[:background_color_inside]))
|
||||||
end
|
end
|
||||||
drawfig(plt.o)
|
drawfig(fig)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -1075,10 +1047,10 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
|
|||||||
# TODO: this should initialize to the margin from sp.attr
|
# TODO: this should initialize to the margin from sp.attr
|
||||||
# figure out how much the axis components and title "stick out" from the plot area
|
# figure out how much the axis components and title "stick out" from the plot area
|
||||||
# leftpad = toppad = rightpad = bottompad = 1mm
|
# leftpad = toppad = rightpad = bottompad = 1mm
|
||||||
leftpad = sp.attr[:left_margin]
|
leftpad = sp[:left_margin]
|
||||||
toppad = sp.attr[:top_margin]
|
toppad = sp[:top_margin]
|
||||||
rightpad = sp.attr[:right_margin]
|
rightpad = sp[:right_margin]
|
||||||
bottompad = sp.attr[:bottom_margin]
|
bottompad = sp[:bottom_margin]
|
||||||
for bb in (py_bbox_axis(ax, "x"), py_bbox_axis(ax, "y"), py_bbox_title(ax))
|
for bb in (py_bbox_axis(ax, "x"), py_bbox_axis(ax, "y"), py_bbox_title(ax))
|
||||||
if ispositive(width(bb)) && ispositive(height(bb))
|
if ispositive(width(bb)) && ispositive(height(bb))
|
||||||
leftpad = max(leftpad, left(plotbb) - left(bb))
|
leftpad = max(leftpad, left(plotbb) - left(bb))
|
||||||
@ -1149,7 +1121,7 @@ const _pyplot_legend_pos = KW(
|
|||||||
)
|
)
|
||||||
|
|
||||||
function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
|
function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
|
||||||
leg = sp.attr[:legend]
|
leg = sp[:legend]
|
||||||
if leg != :none
|
if leg != :none
|
||||||
# gotta do this to ensure both axes are included
|
# gotta do this to ensure both axes are included
|
||||||
labels = []
|
labels = []
|
||||||
@ -1179,19 +1151,19 @@ function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
|
|||||||
labels,
|
labels,
|
||||||
loc = get(_pyplot_legend_pos, leg, "best"),
|
loc = get(_pyplot_legend_pos, leg, "best"),
|
||||||
scatterpoints = 1,
|
scatterpoints = 1,
|
||||||
fontsize = sp.attr[:legendfont].pointsize
|
fontsize = sp[:legendfont].pointsize
|
||||||
# framealpha = 0.6
|
# framealpha = 0.6
|
||||||
)
|
)
|
||||||
leg[:set_zorder](1000)
|
leg[:set_zorder](1000)
|
||||||
|
|
||||||
fgcolor = getPyPlotColor(sp.attr[:foreground_color_legend])
|
fgcolor = getPyPlotColor(sp[:foreground_color_legend])
|
||||||
for txt in leg[:get_texts]()
|
for txt in leg[:get_texts]()
|
||||||
PyPlot.plt[:setp](txt, color = fgcolor)
|
PyPlot.plt[:setp](txt, color = fgcolor)
|
||||||
end
|
end
|
||||||
|
|
||||||
# set some legend properties
|
# set some legend properties
|
||||||
frame = leg[:get_frame]()
|
frame = leg[:get_frame]()
|
||||||
frame[:set_facecolor](getPyPlotColor(sp.attr[:background_color_legend]))
|
frame[:set_facecolor](getPyPlotColor(sp[:background_color_legend]))
|
||||||
frame[:set_edgecolor](fgcolor)
|
frame[:set_edgecolor](fgcolor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1231,7 +1203,7 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
|
|||||||
ax = sp.o
|
ax = sp.o
|
||||||
ax == nothing && return
|
ax == nothing && return
|
||||||
# figw, figh = size(py_bbox_fig(sp.plt))
|
# figw, figh = size(py_bbox_fig(sp.plt))
|
||||||
figw, figh = sp.plt.attr[: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)
|
||||||
ax[:set_position](pcts)
|
ax[:set_position](pcts)
|
||||||
@ -1288,7 +1260,7 @@ for (mime, fmt) in _pyplot_mimeformats
|
|||||||
io,
|
io,
|
||||||
format=$fmt,
|
format=$fmt,
|
||||||
# bbox_inches = "tight",
|
# bbox_inches = "tight",
|
||||||
# figsize = map(px2inch, plt.attr[:size]),
|
# figsize = map(px2inch, plt[:size]),
|
||||||
facecolor = fig.o["get_facecolor"](),
|
facecolor = fig.o["get_facecolor"](),
|
||||||
edgecolor = "none",
|
edgecolor = "none",
|
||||||
dpi = DPI
|
dpi = DPI
|
||||||
|
|||||||
@ -360,57 +360,6 @@ webcolor(c, α) = webcolor(convertColor(getColor(c), α))
|
|||||||
|
|
||||||
# ----------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
# TODO: allow the setting of the algorithm, either by passing a symbol (:colordiff, :fixed, etc) or a function?
|
|
||||||
|
|
||||||
# function handlePlotColors(::AbstractBackend, d::KW)
|
|
||||||
# if :background_color in supportedArgs()
|
|
||||||
# bgcolor = convertColor(d[:background_color])
|
|
||||||
# else
|
|
||||||
# bgcolor = default(:background_color)
|
|
||||||
# if d[:background_color] != default(:background_color)
|
|
||||||
# warn("Cannot set background_color with backend $(backend())")
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# d[:color_palette] = get_color_palette(get(d, :color_palette, :auto), bgcolor, 100)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# # set the foreground color (text, ticks, gridlines) to be white or black depending
|
|
||||||
# # on how dark the background is.
|
|
||||||
# fgcolor = get(d, :foreground_color, :auto)
|
|
||||||
# fgcolor = if fgcolor == :auto
|
|
||||||
# isdark(bgcolor) ? colorant"white" : colorant"black"
|
|
||||||
# else
|
|
||||||
# convertColor(fgcolor)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # bg/fg color
|
|
||||||
# d[:background_color] = colorscheme(bgcolor)
|
|
||||||
# d[:foreground_color] = colorscheme(fgcolor)
|
|
||||||
#
|
|
||||||
# # update sub-background colors
|
|
||||||
# for bgtype in ("legend", "inside", "outside")
|
|
||||||
# bgsym = Symbol("background_color_" * bgtype)
|
|
||||||
# if d[bgsym] == :match
|
|
||||||
# d[bgsym] = d[:background_color]
|
|
||||||
# elseif d[bgsym] == nothing
|
|
||||||
# d[bgsym] = colorscheme(RGBA(0,0,0,0))
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # update sub-foreground colors
|
|
||||||
# for fgtype in ("legend", "grid", "axis", "text", "border", "guide")
|
|
||||||
# fgsym = Symbol("foreground_color_" * fgtype)
|
|
||||||
# if d[fgsym] == :match
|
|
||||||
# d[fgsym] = d[:foreground_color]
|
|
||||||
# elseif d[fgsym] == nothing
|
|
||||||
# d[fgsym] = colorscheme(RGBA(0,0,0,0))
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# end
|
|
||||||
|
|
||||||
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
# converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically
|
||||||
function getSeriesRGBColor(c, attr::KW, n::Int)
|
function getSeriesRGBColor(c, attr::KW, n::Int)
|
||||||
|
|||||||
15
src/plot.jl
15
src/plot.jl
@ -48,8 +48,8 @@ function plot(args...; kw...)
|
|||||||
|
|
||||||
# create an empty Plot then process
|
# create an empty Plot then process
|
||||||
plt = Plot()
|
plt = Plot()
|
||||||
plt.user_attr = d
|
# plt.user_attr = d
|
||||||
_plot!(plt, args...)
|
_plot!(plt, d, args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
# build a new plot from existing plots
|
# build a new plot from existing plots
|
||||||
@ -127,8 +127,8 @@ end
|
|||||||
function plot!(plt::Plot, args...; kw...)
|
function plot!(plt::Plot, args...; kw...)
|
||||||
d = KW(kw)
|
d = KW(kw)
|
||||||
preprocessArgs!(d)
|
preprocessArgs!(d)
|
||||||
merge!(plt.user_attr, d)
|
# merge!(plt.user_attr, d)
|
||||||
_plot!(plt, args...)
|
_plot!(plt, d, args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function strip_first_letter(s::Symbol)
|
function strip_first_letter(s::Symbol)
|
||||||
@ -201,8 +201,8 @@ end
|
|||||||
# this is the core plotting function. recursively apply recipes to build
|
# this is the core plotting function. recursively apply recipes to build
|
||||||
# a list of series KW dicts.
|
# a list of series KW dicts.
|
||||||
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
|
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
|
||||||
function _plot!(plt::Plot, args...)
|
function _plot!(plt::Plot, d::KW, args...)
|
||||||
d = plt.user_attr
|
# d = plt.user_attr
|
||||||
d[:plot_object] = plt
|
d[:plot_object] = plt
|
||||||
|
|
||||||
# the grouping mechanism is a recipe on a GroupBy object
|
# the grouping mechanism is a recipe on a GroupBy object
|
||||||
@ -290,8 +290,8 @@ function _plot!(plt::Plot, args...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# TODO: init subplots here
|
# TODO: init subplots here
|
||||||
|
_update_plot_args(plt, d)
|
||||||
if !plt.init
|
if !plt.init
|
||||||
_update_plot_args(plt, d)
|
|
||||||
plt.o = _create_backend_figure(plt)
|
plt.o = _create_backend_figure(plt)
|
||||||
|
|
||||||
# create the layout and subplots from the inputs
|
# create the layout and subplots from the inputs
|
||||||
@ -309,7 +309,6 @@ function _plot!(plt::Plot, args...)
|
|||||||
|
|
||||||
# first apply any args for the subplots
|
# first apply any args for the subplots
|
||||||
for (idx,sp) in enumerate(plt.subplots)
|
for (idx,sp) in enumerate(plt.subplots)
|
||||||
DD(d,"$idx")
|
|
||||||
_update_subplot_args(plt, sp, d, idx)
|
_update_subplot_args(plt, sp, d, idx)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
40
src/types.jl
40
src/types.jl
@ -20,18 +20,6 @@ end
|
|||||||
wrap{T}(obj::T) = InputWrapper{T}(obj)
|
wrap{T}(obj::T) = InputWrapper{T}(obj)
|
||||||
Base.isempty(wrapper::InputWrapper) = false
|
Base.isempty(wrapper::InputWrapper) = false
|
||||||
|
|
||||||
# -----------------------------------------------------------
|
|
||||||
|
|
||||||
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
|
|
||||||
type Axis
|
|
||||||
d::KW
|
|
||||||
end
|
|
||||||
|
|
||||||
type Extrema
|
|
||||||
emin::Float64
|
|
||||||
emax::Float64
|
|
||||||
end
|
|
||||||
Extrema() = Extrema(Inf, -Inf)
|
|
||||||
|
|
||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
@ -48,6 +36,20 @@ end
|
|||||||
|
|
||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
|
||||||
|
type Axis
|
||||||
|
sp::Subplot
|
||||||
|
d::KW
|
||||||
|
end
|
||||||
|
|
||||||
|
type Extrema
|
||||||
|
emin::Float64
|
||||||
|
emax::Float64
|
||||||
|
end
|
||||||
|
Extrema() = Extrema(Inf, -Inf)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
typealias SubplotMap Dict{Any, Subplot}
|
typealias SubplotMap Dict{Any, Subplot}
|
||||||
|
|
||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
@ -62,14 +64,14 @@ attr!(series::Series, v, k::Symbol) = (series.d[k] = v)
|
|||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
type Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
type Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
||||||
backend::T # the backend type
|
backend::T # the backend type
|
||||||
n::Int # number of series
|
n::Int # number of series
|
||||||
attr::KW # arguments for the whole plot
|
attr::KW # arguments for the whole plot
|
||||||
user_attr::KW # raw arg inputs (after aliases). these are used as the input dict in `_plot!`
|
user_attr::KW # raw arg inputs (after aliases). these are used as the input dict in `_plot!`
|
||||||
series_list::Vector{Series} # arguments for each series
|
series_list::Vector{Series} # arguments for each series
|
||||||
o # the backend's plot object
|
o # the backend's plot object
|
||||||
subplots::Vector{Subplot}
|
subplots::Vector{Subplot}
|
||||||
spmap::SubplotMap # provide any label as a map to a subplot
|
spmap::SubplotMap # provide any label as a map to a subplot
|
||||||
layout::AbstractLayout
|
layout::AbstractLayout
|
||||||
init::Bool
|
init::Bool
|
||||||
end
|
end
|
||||||
|
|||||||
@ -640,7 +640,7 @@ function dumpSupportGraphs()
|
|||||||
for func in (supportGraphArgs, supportGraphTypes, supportGraphStyles,
|
for func in (supportGraphArgs, supportGraphTypes, supportGraphStyles,
|
||||||
supportGraphMarkers, supportGraphScales, supportGraphAxes)
|
supportGraphMarkers, supportGraphScales, supportGraphAxes)
|
||||||
plt = func()
|
plt = func()
|
||||||
png(Pkg.dir("ExamplePlots", "docs", "examples", "img", "supported", "$(string(func))"))
|
png(Pkg.dir("PlotDocs", "docs", "examples", "img", "supported", "$(string(func))"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user