default_should_widen; symbol in userplot macro; cleanup in recipes

This commit is contained in:
Thomas Breloff 2016-06-07 16:44:15 -04:00
parent d0209d945d
commit 17189e3125
5 changed files with 83 additions and 55 deletions

View File

@ -206,8 +206,19 @@ function widen(lmin, lmax)
lmin-eps, lmax+eps
end
# figure out if widening is a good idea
function default_should_widen(axis::Axis)
should_widen = false
for series in series_list(axis.sp)
if series.d[:seriestype] in (:scatter,) || series.d[:markershape] != :none
should_widen = true
end
end
should_widen
end
# using the axis extrema and limit overrides, return the min/max value for this axis
function axis_limits(axis::Axis, should_widen::Bool = true)
function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis))
ex = axis[:extrema]
amin, amax = ex.emin, ex.emax
lims = axis[:lims]

View File

@ -273,16 +273,16 @@ end
# using the axis extrema and limit overrides, return the min/max value for this axis
gr_x_axislims(sp::Subplot) = axis_limits(sp[:xaxis], true)
gr_y_axislims(sp::Subplot) = axis_limits(sp[:yaxis], true)
gr_z_axislims(sp::Subplot) = axis_limits(sp[:zaxis], true)
gr_x_axislims(sp::Subplot) = axis_limits(sp[:xaxis])
gr_y_axislims(sp::Subplot) = axis_limits(sp[:yaxis])
gr_z_axislims(sp::Subplot) = axis_limits(sp[:zaxis])
gr_xy_axislims(sp::Subplot) = gr_x_axislims(sp)..., gr_y_axislims(sp)...
function gr_lims(axis::Axis, adjust::Bool, expand = nothing)
if expand != nothing
expand_extrema!(axis, expand)
end
lims = axis_limits(axis, true)
lims = axis_limits(axis)
if adjust
GR.adjustrange(lims...)
else

View File

@ -614,7 +614,7 @@ function create_grid_curly(expr::Expr)
for (i,arg) in enumerate(expr.args[2:end])
add_layout_pct!(kw, arg, i, length(expr.args)-1)
end
@show kw
# @show kw
:(EmptyLayout(label = $(QuoteNode(s)), width = $(get(kw, :w, QuoteNode(:auto))), height = $(get(kw, :h, QuoteNode(:auto)))))
end

View File

@ -22,7 +22,11 @@ end
grouphist(rand(1000,4))
```
"""
macro userplot(expr::Expr)
macro userplot(expr)
_userplot(expr)
end
function _userplot(expr::Expr)
if expr.head != :type
errror("Must call userplot on a type/immutable expression. Got: $expr")
end
@ -34,11 +38,19 @@ macro userplot(expr::Expr)
# return a code block with the type definition and convenience plotting methods
esc(quote
$expr
$funcname(args...; kw...) = plot($typename(args...); kw...)
$funcname2(args...; kw...) = plot!($typename(args...); kw...)
export $funcname, $funcname2
$funcname(args...; kw...) = plot($typename(args); kw...)
$funcname2(args...; kw...) = plot!($typename(args); kw...)
end)
end
function _userplot(sym::Symbol)
_userplot(:(type $sym
args
end))
end
# ----------------------------------------------------------------------------------
@ -59,14 +71,14 @@ num_series(x::AMat) = size(x,2)
num_series(x) = 1
# if it's not a recipe, just do nothing and return the args
function RecipesBase.apply_recipe(d::KW, args...; issubplot=false)
if issubplot && !isempty(args) && !haskey(d, :n) && !haskey(d, :layout)
# put in a sensible default
d[:n] = maximum(map(num_series, args))
end
args
end
# # if it's not a recipe, just do nothing and return the args
# function RecipesBase.apply_recipe(d::KW, args...; issubplot=false)
# if issubplot && !isempty(args) && !haskey(d, :n) && !haskey(d, :layout)
# # put in a sensible default
# d[:n] = maximum(map(num_series, args))
# end
# args
# end
if is_installed("DataFrames")
@ -136,12 +148,12 @@ end
# for seriestype `line`, need to sort by x values
@recipe function f(::Type{Val{:line}}, x, y, z)
indices = sortperm(x)
d[:x] = x[indices]
d[:y] = y[indices]
x := x[indices]
y := y[indices]
if typeof(z) <: AVec
d[:z] = z[indices]
z := z[indices]
end
d[:seriestype] = :path
seriestype := :path
()
end
@ -154,8 +166,9 @@ end
newx[rng] = x[i]
newy[rng] = [0., y[i], 0.]
end
d[:x], d[:y] = newx, newy
d[:seriestype] = :path
x := newx
y := newy
seriestype := :path
()
end
@ -164,8 +177,9 @@ end
n = length(y)
newx = repmat(Float64[xmin, xmax, NaN], n)
newy = vec(Float64[yi for i=1:3,yi=y])
d[:x], d[:y] = newx, newy
d[:seriestype] = :path
x := newx
y := newy
seriestype := :path
()
end
@ -174,8 +188,9 @@ end
n = length(y)
newx = vec(Float64[yi for i=1:3,yi=y])
newy = repmat(Float64[ymin, ymax, NaN], n)
d[:x], d[:y] = newx, newy
d[:seriestype] = :path
x := newx
y := newy
seriestype := :path
()
end
@ -255,7 +270,8 @@ sticks_fillfrom(fr::AVec, i::Integer) = fr[mod1(i, length(fr))]
newx[rng] = [x[i], x[i], NaN]
newy[rng] = [sticks_fillfrom(fr,i), y[i], NaN]
end
d[:x], d[:y] = newx, newy
x := newx
y := newy
fillrange := nothing
seriestype := :path
@ -328,10 +344,10 @@ end
fillrng[rng] = [fi, fi, fi]
end
d[:x] = x
d[:y] = y
d[:fillrange] = fillrng
d[:seriestype] = :path
x := x
y := y
fillrange := fillrng
seriestype := :path
()
end
@ -378,10 +394,12 @@ end
@recipe function f(::Type{Val{:histogram}}, x, y, z)
edges, counts = my_hist(y, d[:bins], normed = d[:normalize], weights = d[:weights])
d[:x] = edges
d[:y] = counts
d[:seriestype] = :bar
edges, counts = my_hist(y, d[:bins],
normed = d[:normalize],
weights = d[:weights])
x := edges
y := counts
seriestype := :bar
()
end
@ -416,11 +434,13 @@ end
centers(v::AVec) = v[1] + cumsum(diff(v))
@recipe function f(::Type{Val{:histogram2d}}, x, y, z)
xedges, yedges, counts = my_hist_2d(x, y, d[:bins], normed = d[:normalize], weights = d[:weights])
d[:x] = centers(xedges)
d[:y] = centers(yedges)
d[:z] = Surface(counts)
d[:seriestype] = :heatmap
xedges, yedges, counts = my_hist_2d(x, y, d[:bins],
normed = d[:normalize],
weights = d[:weights])
x := centers(xedges)
y := centers(yedges)
z := Surface(counts)
seriestype := :heatmap
()
end
@ -501,7 +521,7 @@ notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
d[:seriestype] = :shape
seriestype := :shape
n = length(groupby.groupLabels)
xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
@ -574,7 +594,7 @@ end
end
# d[:plotarg_overrides] = KW(:xticks => (1:length(shapes), groupby.groupLabels))
d[:seriestype] = :shape
seriestype := :shape
n = length(groupby.groupLabels)
xticks --> (linspace(0.5,n-0.5,n), groupby.groupLabels)
@ -592,7 +612,8 @@ end
if isvertical(d)
newx, newy = newy, newx
end
d[:x], d[:y] = newx, newy
x := newx
y := newy
seriestype := :path
()
end
@ -642,21 +663,17 @@ end
# we will create a series of path segments, where each point represents one
# side of an errorbar
# function apply_series_recipe(d::KW, ::Type{Val{:yerror}})
@recipe function f(::Type{Val{:yerror}}, x, y, z)
error_style!(d)
d[:markershape] = :hline
markershape := :hline
d[:x], d[:y] = error_coords(d[:x], d[:y], error_zipit(d[:yerror]))
# KW[d]
()
end
# function apply_series_recipe(d::KW, ::Type{Val{:xerror}})
@recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(d)
d[:markershape] = :vline
markershape := :vline
d[:y], d[:x] = error_coords(d[:y], d[:x], error_zipit(d[:xerror]))
# KW[d]
()
end
@ -705,8 +722,8 @@ end
# function apply_series_recipe(d::KW, ::Type{Val{:quiver}})
function quiver_using_hack(d::KW)
d[:label] = ""
d[:seriestype] = :shape
label := ""
seriestype := :shape
velocity = error_zipit(d[:quiver])
xorig, yorig = d[:x], d[:y]
@ -855,12 +872,12 @@ end
@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(x::AVec, ohlc::AVec{Tuple{R1,R2,R3,R4}}) = x, OHLC[OHLC(t...) for t in ohlc]
@recipe function f(x::AVec, v::AVec{OHLC})
d[:seriestype] = :path
seriestype := :path
get_xy(v, x)
end
@recipe function f(v::AVec{OHLC})
d[:seriestype] = :path
seriestype := :path
get_xy(v)
end

View File

@ -235,7 +235,7 @@ end
function fakedata(sz...)
y = zeros(sz...)
for r in 2:size(y,1)
y[r,:] = 0.95 * y[r-1,:] + randn(size(y,2))'
y[r,:] = 0.95 * y[r-1,:] + randn(size(y,2))
end
y
end