refactored and renamed plot defaults into plot,subplot,axis defaults, plus some associated fixes

This commit is contained in:
Thomas Breloff 2016-05-16 20:57:50 -04:00
parent 61107b8577
commit c89e9c5f73
9 changed files with 185 additions and 173 deletions

View File

@ -113,118 +113,114 @@ const _allScales = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
# -----------------------------------------------------------------------------
const _seriesDefaults = KW()
const _series_defaults = KW()
# series-specific
_seriesDefaults[:axis] = :left
_seriesDefaults[:label] = "AUTO"
_seriesDefaults[:seriescolor] = :auto
_seriesDefaults[:seriesalpha] = nothing
_seriesDefaults[:seriestype] = :path
_seriesDefaults[:linestyle] = :solid
_seriesDefaults[:linewidth] = :auto
_seriesDefaults[:linecolor] = :match
_seriesDefaults[:linealpha] = nothing
_seriesDefaults[:fillrange] = nothing # ribbons, areas, etc
_seriesDefaults[:fillcolor] = :match
_seriesDefaults[:fillalpha] = nothing
_seriesDefaults[:markershape] = :none
_seriesDefaults[:markercolor] = :match
_seriesDefaults[:markeralpha] = nothing
_seriesDefaults[:markersize] = 6
_seriesDefaults[:markerstrokestyle] = :solid
_seriesDefaults[:markerstrokewidth] = 1
_seriesDefaults[:markerstrokecolor] = :match
_seriesDefaults[:markerstrokealpha] = nothing
_seriesDefaults[:bins] = 30 # number of bins for hists
_seriesDefaults[:smooth] = false # regression line?
_seriesDefaults[:group] = nothing # groupby vector
_seriesDefaults[:x] = nothing
_seriesDefaults[:y] = nothing
_seriesDefaults[:z] = nothing # depth for contour, surface, etc
_seriesDefaults[:marker_z] = nothing # value for color scale
_seriesDefaults[:levels] = 15
_seriesDefaults[:orientation] = :vertical
_seriesDefaults[:bar_position] = :overlay # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
_seriesDefaults[:xerror] = nothing
_seriesDefaults[:yerror] = nothing
_seriesDefaults[:ribbon] = nothing
_seriesDefaults[:quiver] = nothing
_seriesDefaults[:arrow] = nothing # allows for adding arrows to line/path... call `arrow(args...)`
_seriesDefaults[:normalize] = false # do we want a normalized histogram?
_seriesDefaults[:weights] = nothing # optional weights for histograms (1D and 2D)
_seriesDefaults[:contours] = false # add contours to 3d surface and wireframe plots
_seriesDefaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
_series_defaults[:axis] = :left
_series_defaults[:label] = "AUTO"
_series_defaults[:seriescolor] = :auto
_series_defaults[:seriesalpha] = nothing
_series_defaults[:seriestype] = :path
_series_defaults[:linestyle] = :solid
_series_defaults[:linewidth] = :auto
_series_defaults[:linecolor] = :match
_series_defaults[:linealpha] = nothing
_series_defaults[:fillrange] = nothing # ribbons, areas, etc
_series_defaults[:fillcolor] = :match
_series_defaults[:fillalpha] = nothing
_series_defaults[:markershape] = :none
_series_defaults[:markercolor] = :match
_series_defaults[:markeralpha] = nothing
_series_defaults[:markersize] = 6
_series_defaults[:markerstrokestyle] = :solid
_series_defaults[:markerstrokewidth] = 1
_series_defaults[:markerstrokecolor] = :match
_series_defaults[:markerstrokealpha] = nothing
_series_defaults[:bins] = 30 # number of bins for hists
_series_defaults[:smooth] = false # regression line?
_series_defaults[:group] = nothing # groupby vector
_series_defaults[:x] = nothing
_series_defaults[:y] = nothing
_series_defaults[:z] = nothing # depth for contour, surface, etc
_series_defaults[:marker_z] = nothing # value for color scale
_series_defaults[:levels] = 15
_series_defaults[:orientation] = :vertical
_series_defaults[:bar_position] = :overlay # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
_series_defaults[:xerror] = nothing
_series_defaults[:yerror] = nothing
_series_defaults[:ribbon] = nothing
_series_defaults[:quiver] = nothing
_series_defaults[:arrow] = nothing # allows for adding arrows to line/path... call `arrow(args...)`
_series_defaults[:normalize] = false # do we want a normalized histogram?
_series_defaults[:weights] = nothing # optional weights for histograms (1D and 2D)
_series_defaults[:contours] = false # add contours to 3d surface and wireframe plots
_series_defaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
_seriesDefaults[:subplot] = :auto
_series_defaults[:subplot] = :auto # which subplot(s) does this series belong to?
const _plotDefaults = KW()
const _plot_defaults = KW()
# plot globals
_plotDefaults[:title] = ""
_plotDefaults[:xlabel] = ""
_plotDefaults[:ylabel] = ""
_plotDefaults[:zlabel] = ""
_plotDefaults[:yrightlabel] = ""
_plotDefaults[:legend] = :best
_plotDefaults[:colorbar] = :legend
_plotDefaults[:background_color] = colorant"white" # default for all backgrounds
_plotDefaults[:background_color_legend] = :match # background of legend
_plotDefaults[:background_color_inside] = :match # background inside grid
_plotDefaults[:background_color_outside] = :match # background outside grid
_plotDefaults[:foreground_color] = :auto # default for all foregrounds
_plotDefaults[:foreground_color_legend] = :match # foreground of legend
_plotDefaults[:foreground_color_grid] = :match # grid color
_plotDefaults[:foreground_color_axis] = :match # axis border/tick colors
_plotDefaults[:foreground_color_border] = :match # plot area border/spines
_plotDefaults[:foreground_color_text] = :match # tick text color
_plotDefaults[:foreground_color_guide] = :match # guide text color
_plotDefaults[:xlims] = :auto
_plotDefaults[:ylims] = :auto
_plotDefaults[:zlims] = :auto
_plotDefaults[:xticks] = :auto
_plotDefaults[:yticks] = :auto
_plotDefaults[:zticks] = :auto
_plotDefaults[:xscale] = :identity
_plotDefaults[:yscale] = :identity
_plotDefaults[:zscale] = :identity
_plotDefaults[:xrotation] = 0
_plotDefaults[:yrotation] = 0
_plotDefaults[:zrotation] = 0
_plotDefaults[:xflip] = false
_plotDefaults[:yflip] = false
_plotDefaults[:zflip] = false
_plotDefaults[:size] = (600,400)
_plotDefaults[:pos] = (0,0)
_plotDefaults[:windowtitle] = "Plots.jl"
_plotDefaults[:show] = false
_plotDefaults[:layout] = :auto
_plotDefaults[:n] = -1
_plotDefaults[:nr] = -1
_plotDefaults[:nc] = -1
_plotDefaults[:color_palette] = :auto
_plotDefaults[:link] = false
_plotDefaults[:linkx] = false
_plotDefaults[:linky] = false
_plotDefaults[:linkfunc] = nothing
_plotDefaults[:tickfont] = font(8)
_plotDefaults[:guidefont] = font(11)
_plotDefaults[:legendfont] = font(8)
_plotDefaults[:grid] = true
_plotDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
_plotDefaults[:overwrite_figure] = false
_plotDefaults[:polar] = false
_plotDefaults[:aspect_ratio] = :none # choose from :none or :equal
_plotDefaults[:xaxis] = xaxis()
_plotDefaults[:yaxis] = yaxis()
_plotDefaults[:zaxis] = zaxis()
_plot_defaults[:title] = ""
_plot_defaults[:legend] = :best
_plot_defaults[:colorbar] = :legend
_plot_defaults[:background_color] = colorant"white" # default for all backgrounds
_plot_defaults[:background_color_outside] = :match # background outside grid
_plot_defaults[:foreground_color] = :auto # default for all foregrounds
_plot_defaults[:size] = (600,400)
_plot_defaults[:pos] = (0,0)
_plot_defaults[:windowtitle] = "Plots.jl"
_plot_defaults[:show] = false
_plot_defaults[:layout] = :auto
_plot_defaults[:num_subplots] = -1
_plot_defaults[:num_rows] = -1
_plot_defaults[:num_cols] = -1
_plot_defaults[:color_palette] = :auto
_plot_defaults[:link] = false
_plot_defaults[:linkx] = false
_plot_defaults[:linky] = false
_plot_defaults[:linkfunc] = nothing
_plot_defaults[:overwrite_figure] = false
# TODO: x/y scales
const _subplot_defaults = KW()
const _allArgs = sort(collect(union(keys(_seriesDefaults), keys(_plotDefaults))))
supportedArgs(::AbstractBackend) = error("supportedArgs not defined") #_allArgs
_subplot_defaults[:title] = ""
_subplot_defaults[:background_color_legend] = :match # background of legend
_subplot_defaults[:background_color_inside] = :match # background inside grid
_subplot_defaults[:foreground_color_legend] = :match # foreground of legend
_subplot_defaults[:foreground_color_grid] = :match # grid color
_subplot_defaults[:legendfont] = font(8)
_subplot_defaults[:grid] = true
_subplot_defaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
_subplot_defaults[:polar] = false
_subplot_defaults[:aspect_ratio] = :none # choose from :none or :equal
const _axis_defaults = KW()
_axis_defaults[:label] = :auto
_axis_defaults[:xlims] = :auto
_axis_defaults[:xticks] = :auto
_axis_defaults[:xscale] = :identity
_axis_defaults[:xrotation] = 0
_axis_defaults[:xflip] = false
# _axis_defaults[:axis] = :auto
_axis_defaults[:tickfont] = font(8)
_axis_defaults[:guidefont] = font(11)
_axis_defaults[:foreground_color_axis] = :match # axis border/tick colors
_axis_defaults[:foreground_color_border] = :match # plot area border/spines
_axis_defaults[:foreground_color_text] = :match # tick text color
_axis_defaults[:foreground_color_guide] = :match # guide text color
const _all_defaults = KW[
_series_defaults,
_plot_defaults,
_subplot_defaults,
_axis_defaults
]
const _all_args = sort(collect(union(map(keys, _all_defaults)...)))
supportedArgs(::AbstractBackend) = error("supportedArgs not defined") #_all_args
supportedArgs() = supportedArgs(backend())
RecipesBase.is_key_supported(k::Symbol) = (k in supportedArgs())
@ -342,8 +338,9 @@ add_aliases(:show, :gui, :display)
add_aliases(:color_palette, :palette)
add_aliases(:linkx, :xlink)
add_aliases(:linky, :ylink)
add_aliases(:nr, :nrow, :nrows, :rows)
add_aliases(:nc, :ncol, :ncols, :cols, :ncolumns, :columns)
add_aliases(:num_subplots, :n, :numplots, :nplts)
add_aliases(:num_rows, :nr, :nrow, :nrows, :rows)
add_aliases(:num_cols, :nc, :ncol, :ncols, :cols, :ncolumns, :columns)
add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse)
add_aliases(:xerror, :xerr, :xerrorbar)
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar)
@ -354,7 +351,7 @@ add_aliases(:match_dimensions, :transpose, :transpose_z)
# add all pluralized forms to the _keyAliases dict
for arg in keys(_seriesDefaults)
for arg in keys(_series_defaults)
_keyAliases[makeplural(arg)] = arg
end
@ -372,24 +369,37 @@ end
function default(k::Symbol)
k = get(_keyAliases, k, k)
if haskey(_seriesDefaults, k)
return _seriesDefaults[k]
elseif haskey(_plotDefaults, k)
return _plotDefaults[k]
else
error("Unknown key: ", k)
for defaults in _all_defaults
if haskey(defaults, k)
return defaults[k]
end
end
error("Unknown key: ", k)
# if haskey(_series_defaults, k)
# return _series_defaults[k]
# elseif haskey(_plot_defaults, k)
# return _plot_defaults[k]
# else
# error("Unknown key: ", k)
# end
end
function default(k::Symbol, v)
k = get(_keyAliases, k, k)
if haskey(_seriesDefaults, k)
_seriesDefaults[k] = v
elseif haskey(_plotDefaults, k)
_plotDefaults[k] = v
else
error("Unknown key: ", k)
for defaults in _all_defaults
if haskey(defaults, k)
defaults[k] = v
return v
end
end
error("Unknown key: ", k)
# if haskey(_series_defaults, k)
# _series_defaults[k] = v
# elseif haskey(_plot_defaults, k)
# _plot_defaults[k] = v
# else
# error("Unknown key: ", k)
# end
end
function default(; kw...)
@ -801,8 +811,8 @@ function getPlotArgs(pkg::AbstractBackend, kw, idx::Int; set_defaults = true)
# add defaults?
if set_defaults
for k in keys(_plotDefaults)
setDictValue(kwdict, d, k, idx, _plotDefaults)
for k in keys(_plot_defaults)
setDictValue(kwdict, d, k, idx, _plot_defaults)
end
end
#
@ -839,8 +849,8 @@ end
# d = KW()
#
# # add defaults?
# for k in keys(_seriesDefaults)
# setDictValue(kwdict, d, k, commandIndex, _seriesDefaults)
# for k in keys(_series_defaults)
# setDictValue(kwdict, d, k, commandIndex, _series_defaults)
# end
#
# # groupby args?

View File

@ -186,7 +186,7 @@ end
function _create_backend_figure(plt::Plot{UnicodePlotsBackend})
# do we want to give a new default size?
if !haskey(plt.plotargs, :size) || plt.plotargs[:size] == _plotDefaults[:size]
if !haskey(plt.plotargs, :size) || plt.plotargs[:size] == default(:size)
plt.plotargs[:size] = (60,20)
end
nothing

View File

@ -364,8 +364,8 @@ function handlePlotColors(::AbstractBackend, d::KW)
if :background_color in supportedArgs()
bgcolor = convertColor(d[:background_color])
else
bgcolor = _plotDefaults[:background_color]
if d[:background_color] != _plotDefaults[:background_color]
bgcolor = default(:background_color)
if d[:background_color] != default(:background_color)
warn("Cannot set background_color with backend $(backend())")
end
end

View File

@ -273,7 +273,7 @@ const _axis_symbols_fonts_colors = (
)
function Axis(letter::AbstractString, args...; kw...)
# init with values from _plotDefaults
# init with values from _plot_defaults
d = KW(
:letter => letter,
:extrema => (Inf, -Inf),
@ -282,13 +282,14 @@ function Axis(letter::AbstractString, args...; kw...)
:use_minor => false,
:show => true, # show or hide the axis? (useful for linked subplots)
)
for sym in _axis_symbols
k = symbol(letter * string(sym))
d[sym] = _plotDefaults[k]
end
for k in _axis_symbols_fonts_colors
d[k] = _plotDefaults[k]
end
merge!(d, _axis_defaults)
# for sym in _axis_symbols
# k = symbol(letter * string(sym))
# d[sym] = _plot_defaults[k]
# end
# for k in _axis_symbols_fonts_colors
# d[k] = _plot_defaults[k]
# end
# update the defaults
update!(Axis(d), args...; kw...)

View File

@ -94,6 +94,7 @@ function strip_first_letter(s::Symbol)
str[1:1], symbol(str[2:end])
end
# TODO: need to apply axis args to the axes, subplot args to the subplots, and plot args to the plot
# merge the KW d into the plot args
function _add_plotargs!(plt::Plot, d::KW)
# @show d
@ -139,7 +140,7 @@ function _add_plotargs!(plt::Plot, d::KW)
# @show 4,axis
end
for k in keys(_plotDefaults)
for k in keys(_plot_defaults)
if haskey(d, k)
plt.plotargs[k] = pop!(d, k)
end
@ -262,7 +263,7 @@ function _plot!(plt::Plot, d::KW, args...)
# !!! note: at this point, kw_list is fully decomposed into individual series... one KW per series !!!
# TODO: move annotations into subplot update
# now include any annotations which were added during recipes
for kw in kw_list
append!(anns, annotations(pop!(kw, :annotation, [])))
@ -295,28 +296,6 @@ function _plot!(plt::Plot, d::KW, args...)
plt.n += 1
end
# TODO: can this be handled as a recipe?? (yes... need to remove)
# note: this could probably be handled using a recipe signature f{S<:Union{AbstractString,Symbol}}(v::AVec{S}, letter::AbstractString)
# that gets called from within the SliceIt section
# if !stringsSupported() && di[:seriestype] != :pie
# setTicksFromStringVector(plt, d, di, "x")
# setTicksFromStringVector(plt, d, di, "y")
# setTicksFromStringVector(plt, d, di, "z")
# end
# TODO: unnecessary?? (yes... deleted as part of _add_plotargs... remove this)
# # remove plot args
# for k in keys(_plotDefaults)
# delete!(di, k)
# end
# TODO: why?? (I think we can remove??)
# # merge in plotarg_overrides
# plotarg_overrides = pop!(di, :plotarg_overrides, nothing)
# if plotarg_overrides != nothing
# merge!(plt.plotargs, plotarg_overrides)
# end
# set default values, select from attribute cycles, and generally set the final attributes
_add_defaults!(kw, plt, i)
@ -334,12 +313,8 @@ function _plot!(plt::Plot, d::KW, args...)
# now that we're done adding all the series, add the annotations
_add_annotations(plt, anns)
# add title, axis labels, ticks, etc
# TODO: do we really need this subplot check?
# if !haskey(d, :subplot)
# merge!(plt.plotargs, d) # this shouldn't be needed since we merged the keys earlier
_update_plot(plt, plt.plotargs)
# end
# TODO just need to pass plt... and we should do all non-series updates here
_update_plot(plt, plt.plotargs)
current(plt)
@ -411,7 +386,7 @@ end
# end
#
# # remove plot args
# for k in keys(_plotDefaults)
# for k in keys(_plot_defaults)
# delete!(di, k)
# end
#
@ -540,7 +515,7 @@ function Base.copy(plt::Plot)
backend(plt.backend)
plt2 = plot(; plt.plotargs...)
for sargs in plt.seriesargs
sargs = filter((k,v) -> haskey(_seriesDefaults,k), sargs)
sargs = filter((k,v) -> haskey(_series_defaults,k), sargs)
plot!(plt2; sargs...)
end
plt2

View File

@ -10,8 +10,8 @@ function _add_defaults!(d::KW, plt::Plot, commandIndex::Int)
globalIndex = n
# add defaults?
for k in keys(_seriesDefaults)
setDictValue(d, d, k, commandIndex, _seriesDefaults)
for k in keys(_series_defaults)
setDictValue(d, d, k, commandIndex, _series_defaults)
end
if d[:subplot] == :auto

View File

@ -177,21 +177,47 @@ end
# ----------------------------------------------------------------------
# return the top-level layout, a list of subplots, and a SubplotMap
function build_layout(s::Symbol)
s == :auto || error() # TODO: handle anything else
layout = GridLayout(1, 2) #TODO this need to go
nr, nc = size(layout)
function build_layout(d::KW)
l = get(d, :layout, :auto)
n = get(d, :num_subplots, -1)
nr = get(d, :num_rows, -1)
nc = get(d, :num_cols, -1)
l == :auto || error() # TODO: handle anything else
nr, nc = compute_gridsize(n, nr, nc)
layout = GridLayout(nr, nc)
subplots = Subplot[]
spmap = SubplotMap()
i = 1
for r=1:nr, c=1:nc
i > n && break # only add n subplots
sp = Subplot(backend(), parent=layout)
layout[r,c] = sp
push!(subplots, sp)
spmap[(r,c)] = sp
i += 1
end
layout, subplots, spmap
end
function compute_gridsize(numplts::Int, nr::Int, nc::Int)
# figure out how many rows/columns we need
if nr == -1
if nc == -1
nr = round(Int, sqrt(numplts))
nc = ceil(Int, numplts / nr)
else
nr = ceil(Int, numplts / nc)
end
else
nc = ceil(Int, numplts / nr)
end
nr, nc
end
# ----------------------------------------------------------------------
get_subplot(plt::Plot, sp::Subplot) = sp

View File

@ -69,7 +69,7 @@ end
type Subplot{T<:AbstractBackend} <: AbstractLayout
parent::AbstractLayout
bbox::BoundingBox # the canvas area which is available to this subplot
attr::KW # args specific to this subplot
subplotargs::KW # args specific to this subplot
# axisviews::Vector{AxisView}
o # can store backend-specific data... like a pyplot ax

View File

@ -614,7 +614,7 @@ function supportGraph(allvals, func)
aspect_ratio = :equal)
end
supportGraphArgs() = supportGraph(_allArgs, supportedArgs)
supportGraphArgs() = supportGraph(_all_args, supportedArgs)
supportGraphTypes() = supportGraph(_allTypes, supportedTypes)
supportGraphStyles() = supportGraph(_allStyles, supportedStyles)
supportGraphMarkers() = supportGraph(_allMarkers, supportedMarkers)