working on Axis type

This commit is contained in:
Thomas Breloff 2016-05-13 16:46:15 -04:00
parent 2ba4ac6d20
commit 83bd780f2a
6 changed files with 165 additions and 122 deletions

View File

@ -772,7 +772,7 @@ function setDictValue(d_in::KW, d_out::KW, k::Symbol, idx::Int, defaults::KW)
if haskey(d_in, k) && !(typeof(d_in[k]) <: Union{AbstractMatrix, Tuple} && isempty(d_in[k]))
d_out[k] = getArgValue(d_in[k], idx)
else
d_out[k] = defaults[k]
d_out[k] = deepcopy(defaults[k])
end
end

View File

@ -384,6 +384,7 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
ax = getAxis(plt, d[:axis])
x, y, z = d[:x], d[:y], d[:z]
@show typeof((x,y,z))
xyargs = (lt in _3dTypes ? (x,y,z) : (x,y))
# handle zcolor and get c/cmap
@ -911,9 +912,10 @@ end
function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
# @show d
figorax = plt.o
ax = getLeftAxis(figorax)
ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
# ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
guidesz = get(d, :guidefont, plt.plotargs[:guidefont]).pointsize
# title
@ -930,32 +932,60 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
end
end
# handle each axis in turn
for letter in ("x", "y", "z")
axis, scale, lims, ticks, flip, lab, rotation =
axis_symbols(letter, "axis", "scale", "lims", "ticks", "flip", "label", "rotation")
haskey(ax, axis) || continue
haskey(d, scale) && applyPyPlotScale(ax, d[scale], letter)
haskey(d, lims) && addPyPlotLims(ax, d[lims], letter)
haskey(d, ticks) && addPyPlotTicks(ax, d[ticks], letter)
haskey(d, lab) && ax[symbol("set_", letter, "label")](d[lab])
if get(d, flip, false)
axissym = symbol(letter*"axis")
axis = plt.plotargs[axissym]
# @show axis
haskey(ax, axissym) || continue
applyPyPlotScale(ax, axis[:scale], letter)
addPyPlotLims(ax, axis[:lims], letter)
addPyPlotTicks(ax, get_ticks(axis), letter)
ax[symbol("set_", letter, "label")](axis[:label])
if get(axis.d, :flip, false)
ax[symbol("invert_", letter, "axis")]()
end
for tmpax in axes
tmpax[axis][:label][:set_fontsize](guidesz)
tmpax[axissym][:label][:set_fontsize](axis[:guidefont].pointsize)
for lab in tmpax[symbol("get_", letter, "ticklabels")]()
lab[:set_fontsize](ticksz)
haskey(d, rotation) && lab[:set_rotation](d[rotation])
lab[:set_fontsize](axis[:tickfont].pointsize)
lab[:set_rotation](axis[:rotation])
end
if get(d, :grid, false)
fgcolor = getPyPlotColor(plt.plotargs[:foreground_color_grid])
tmpax[axis][:grid](true, color = fgcolor)
tmpax[axissym][:grid](true, color = fgcolor)
tmpax[:set_axisbelow](true)
end
end
# @show ""
end
# # handle each axis in turn
# for letter in ("x", "y", "z")
# axis, scale, lims, ticks, flip, lab, rotation =
# axis_symbols(letter, "axis", "scale", "lims", "ticks", "flip", "label", "rotation")
# haskey(ax, axis) || continue
# haskey(d, scale) && applyPyPlotScale(ax, d[scale], letter)
# haskey(d, lims) && addPyPlotLims(ax, d[lims], letter)
# haskey(d, ticks) && addPyPlotTicks(ax, d[ticks], letter)
# haskey(d, lab) && ax[symbol("set_", letter, "label")](d[lab])
# if get(d, flip, false)
# ax[symbol("invert_", letter, "axis")]()
# end
# for tmpax in axes
# tmpax[axis][:label][:set_fontsize](guidesz)
# for lab in tmpax[symbol("get_", letter, "ticklabels")]()
# lab[:set_fontsize](ticksz)
# haskey(d, rotation) && lab[:set_rotation](d[rotation])
# end
# if get(d, :grid, false)
# fgcolor = getPyPlotColor(plt.plotargs[:foreground_color_grid])
# tmpax[axis][:grid](true, color = fgcolor)
# tmpax[:set_axisbelow](true)
# end
# end
# end
# do we want to change the aspect ratio?
aratio = get(d, :aspect_ratio, :none)
if aratio != :none

View File

@ -207,106 +207,106 @@ function rotate(shape::Shape, Θ::Real, c = center(shape))
end
# -----------------------------------------------------------------------
# abstract AbstractAxisTicks
# immutable DefaultAxisTicks end
#
# type CustomAxisTicks
# # TODO
# # abstract AbstractAxisTicks
# # immutable DefaultAxisTicks end
# #
# # type CustomAxisTicks
# # # TODO
# # end
#
# # simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
# type Axis
# d::KW
# # name::AbstractString # "x" or "y"
# # label::AbstractString
# # lims::NTuple{2}
# # ticks::AbstractAxisTicks
# # scale::Symbol
# # flip::Bool
# # rotation::Number
# # guidefont::Font
# # tickfont::Font
# # use_minor::Bool
# # _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
# end
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
type Axis
d::KW
# name::AbstractString # "x" or "y"
# label::AbstractString
# lims::NTuple{2}
# ticks::AbstractAxisTicks
# scale::Symbol
# flip::Bool
# rotation::Number
# guidefont::Font
# tickfont::Font
# use_minor::Bool
# _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
end
# function processAxisArg(d::KW, letter::AbstractString, arg)
function axis(letter, args...; kw...)
# TODO: this should initialize with values from _plotDefaults
d = KW(
:letter => letter,
:label => "",
:lims => :auto,
:ticks => :auto,
:scale => :identity,
:flip => false,
:rotation => 0,
:guidefont => font(11),
:tickfont => font(8),
:use_minor => false,
:foreground_color_axis => :match,
:foreground_color_border => :match,
:foreground_color_text => :match,
:foreground_color_guide => :match,
)
# first process args
for arg in args
T = typeof(arg)
arg = get(_scaleAliases, arg, arg)
# scale, flip, label, lim, tick = axis_symbols(letter, "scale", "flip", "label", "lims", "ticks")
if typeof(arg) <: Font
d[:tickfont] = arg
d[:guidefont] = arg
elseif arg in _allScales
d[:scale] = arg
elseif arg in (:flip, :invert, :inverted)
d[:flip] = true
elseif T <: @compat(AbstractString)
d[:label] = arg
# xlims/ylims
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
sym = typeof(arg[1]) <: Number ? :lims : :ticks
d[sym] = arg
# xticks/yticks
elseif T <: AVec
d[:ticks] = arg
elseif arg == nothing
d[:ticks] = []
elseif typeof(arg) <: Number
d[:rotation] = arg
else
warn("Skipped $(letter)axis arg $arg")
end
end
# then override for any keywords
for (k,v) in kw
d[k] = v
end
Axis(d)
end
xaxis(args...) = axis("x", args...)
yaxis(args...) = axis("y", args...)
zaxis(args...) = axis("z", args...)
#
#
# # function processAxisArg(d::KW, letter::AbstractString, arg)
# function axis(letter, args...; kw...)
# # TODO: this should initialize with values from _plotDefaults
# d = KW(
# :letter => letter,
# :label => "",
# :lims => :auto,
# :ticks => :auto,
# :scale => :identity,
# :flip => false,
# :rotation => 0,
# :guidefont => font(11),
# :tickfont => font(8),
# :use_minor => false,
# :foreground_color_axis => :match,
# :foreground_color_border => :match,
# :foreground_color_text => :match,
# :foreground_color_guide => :match,
# )
#
# # first process args
# for arg in args
# T = typeof(arg)
# arg = get(_scaleAliases, arg, arg)
# # scale, flip, label, lim, tick = axis_symbols(letter, "scale", "flip", "label", "lims", "ticks")
#
# if typeof(arg) <: Font
# d[:tickfont] = arg
# d[:guidefont] = arg
#
# elseif arg in _allScales
# d[:scale] = arg
#
# elseif arg in (:flip, :invert, :inverted)
# d[:flip] = true
#
# elseif T <: @compat(AbstractString)
# d[:label] = arg
#
# # xlims/ylims
# elseif (T <: Tuple || T <: AVec) && length(arg) == 2
# sym = typeof(arg[1]) <: Number ? :lims : :ticks
# d[sym] = arg
#
# # xticks/yticks
# elseif T <: AVec
# d[:ticks] = arg
#
# elseif arg == nothing
# d[:ticks] = []
#
# elseif typeof(arg) <: Number
# d[:rotation] = arg
#
# else
# warn("Skipped $(letter)axis arg $arg")
#
# end
# end
#
# # then override for any keywords
# for (k,v) in kw
# d[k] = v
# end
#
# Axis(d)
# end
#
#
# xaxis(args...) = axis("x", args...)
# yaxis(args...) = axis("y", args...)
# zaxis(args...) = axis("z", args...)
# -----------------------------------------------------------------------
@ -374,7 +374,7 @@ end
# -----------------------------------------------------------------------
# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
type Axis
type Axis #<: Associative{Symbol,Any}
d::KW
end
@ -414,8 +414,10 @@ function discrete_value!(a::Axis, v::AVec)
Float64[discrete_value!(a, vi) for vi=v]
end
Base.show(io::IO, a::Axis) = dumpdict(a.d, "Axis", true)
Base.getindex(a::Axis, k::Symbol) = getindex(a.d, k)
Base.setindex!(a::Axis, v, ks::Symbol...) = setindex!(a.d, v, ks...)
Base.haskey(a::Axis, k::Symbol) = haskey(a.d, k)
Base.extrema(a::Axis) = a[:extrema]
# get discrete ticks, or not
@ -457,13 +459,13 @@ function Axis(letter::AbstractString, args...; kw...)
# :foreground_color_guide => :match,
:extrema => (Inf, -Inf),
:discrete_map => Dict(), # map discrete values to continuous plot values
:discrete_values => [],
:discrete_values => Tuple{Float64,Any}[],
: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[k] = _plotDefaults[k]
d[sym] = _plotDefaults[k]
end
for k in _axis_symbols_fonts_colors
d[k] = _plotDefaults[k]

View File

@ -81,11 +81,13 @@ end
# merge the KW d into the plot args
function _add_plotargs!(plt::Plot, d::KW)
# @show d
# handle axis updates from a recipe
for letter in ("x","y","z")
# get the Axis object
axis = plt.plotargs[symbol(letter * "axis")]
# @show 1,typeof(axis)
# update xlabel, xscale, etc
for k in _axis_symbols
@ -94,6 +96,7 @@ function _add_plotargs!(plt::Plot, d::KW)
axis[k] = d[lk]
end
end
# @show 2,axis
# update guidefont, etc
for k in _axis_symbols_fonts_colors
@ -101,6 +104,7 @@ function _add_plotargs!(plt::Plot, d::KW)
axis[k] = d[k]
end
end
# @show 3,axis
# update extrema and discrete values
datasym = symbol(letter)
@ -112,6 +116,7 @@ function _add_plotargs!(plt::Plot, d::KW)
d[datasym] = discrete_value!(axis, v)
end
end
# @show 4,axis
end
for k in keys(_plotDefaults)

View File

@ -247,7 +247,8 @@ const _box_halfwidth = 0.4
q1,q2,q3,q4,q5 = quantile(d[:y][groupby.groupIds[i]], linspace(0,1,5))
# make the shape
l, m, r = i - _box_halfwidth, i, i + _box_halfwidth
center = i - 0.5
l, m, r = center - _box_halfwidth, center, center + _box_halfwidth
xcoords = [
m, l, r, m, m, NaN, # lower T
l, l, r, r, l, NaN, # lower box
@ -266,7 +267,8 @@ const _box_halfwidth = 0.4
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
d[:linetype] = :shape
xticklabels --> groupby.groupLabels
n = length(groupby.groupLabels)
xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
# we want to set the fields directly inside series recipes... args are ignored
d[:x], d[:y] = shape_coords(shapes)
@ -315,14 +317,15 @@ end
widths = _box_halfwidth * widths / maximum(widths)
# make the violin
xcoords = vcat(widths, -reverse(widths)) + i
xcoords = vcat(widths, -reverse(widths)) + (i - 0.5)
ycoords = vcat(centers, reverse(centers))
push!(shapes, Shape(xcoords, ycoords))
end
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
d[:linetype] = :shape
xticklabels --> groupby.groupLabels
n = length(groupby.groupLabels)
xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
d[:x], d[:y] = shape_coords(shapes)
()

View File

@ -105,6 +105,8 @@ immutable SliceIt end
end
mf = length(fillranges)
@show zs
mx = length(xs)
my = length(ys)
mz = length(zs)
@ -115,6 +117,7 @@ immutable SliceIt end
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
# @show i, typeof((xi, yi, zi))
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
# @show i, typeof((di[:x], di[:y], di[:z]))
# handle fillrange
fr = fillranges[mod1(i,mf)]
@ -329,8 +332,8 @@ end
# end
@recipe function f{X,Y}(x::AVec{X}, y::AVec{Y}, zf::Function)
x = X <: Number ? sort(x) : x
y = Y <: Number ? sort(y) : y
# x = X <: Number ? sort(x) : x
# y = Y <: Number ? sort(y) : y
SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
end