Merge pull request #1116 from jw3126/replaceD

replace d by plotattributes inside recipes
This commit is contained in:
Michael Krabbe Borregaard 2017-10-02 14:46:11 +02:00 committed by GitHub
commit a80c7ada27
3 changed files with 67 additions and 67 deletions

View File

@ -1,6 +1,6 @@
julia 0.6 julia 0.6
RecipesBase 0.2.0 RecipesBase 0.2.3
PlotUtils 0.4.1 PlotUtils 0.4.1
PlotThemes 0.1.3 PlotThemes 0.1.3
Reexport Reexport

View File

@ -79,7 +79,7 @@ function hvline_limits(axis::Axis)
end end
@recipe function f(::Type{Val{:hline}}, x, y, z) @recipe function f(::Type{Val{:hline}}, x, y, z)
xmin, xmax = hvline_limits(d[:subplot][:xaxis]) xmin, xmax = hvline_limits(plotattributes[:subplot][:xaxis])
n = length(y) n = length(y)
newx = repmat(Float64[xmin, xmax, NaN], n) newx = repmat(Float64[xmin, xmax, NaN], n)
newy = vec(Float64[yi for i=1:3,yi=y]) newy = vec(Float64[yi for i=1:3,yi=y])
@ -91,7 +91,7 @@ end
@deps hline path @deps hline path
@recipe function f(::Type{Val{:vline}}, x, y, z) @recipe function f(::Type{Val{:vline}}, x, y, z)
ymin, ymax = hvline_limits(d[:subplot][:yaxis]) ymin, ymax = hvline_limits(plotattributes[:subplot][:yaxis])
n = length(y) n = length(y)
newx = vec(Float64[yi for i=1:3,yi=y]) newx = vec(Float64[yi for i=1:3,yi=y])
newy = repmat(Float64[ymin, ymax, NaN], n) newy = repmat(Float64[ymin, ymax, NaN], n)
@ -123,11 +123,11 @@ end
# create a path from steps # create a path from steps
@recipe function f(::Type{Val{:steppre}}, x, y, z) @recipe function f(::Type{Val{:steppre}}, x, y, z)
d[:x], d[:y] = make_steps(x, y, :steppre) plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppre)
seriestype := :path seriestype := :path
# create a secondary series for the markers # create a secondary series for the markers
if d[:markershape] != :none if plotattributes[:markershape] != :none
@series begin @series begin
seriestype := :scatter seriestype := :scatter
x := x x := x
@ -144,11 +144,11 @@ end
# create a path from steps # create a path from steps
@recipe function f(::Type{Val{:steppost}}, x, y, z) @recipe function f(::Type{Val{:steppost}}, x, y, z)
d[:x], d[:y] = make_steps(x, y, :steppost) plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppost)
seriestype := :path seriestype := :path
# create a secondary series for the markers # create a secondary series for the markers
if d[:markershape] != :none if plotattributes[:markershape] != :none
@series begin @series begin
seriestype := :scatter seriestype := :scatter
x := x x := x
@ -170,9 +170,9 @@ end
# create vertical line segments from fill # create vertical line segments from fill
@recipe function f(::Type{Val{:sticks}}, x, y, z) @recipe function f(::Type{Val{:sticks}}, x, y, z)
n = length(x) n = length(x)
fr = d[:fillrange] fr = plotattributes[:fillrange]
if fr == nothing if fr == nothing
yaxis = d[:subplot][:yaxis] yaxis = plotattributes[:subplot][:yaxis]
fr = if yaxis[:scale] == :identity fr = if yaxis[:scale] == :identity
0.0 0.0
else else
@ -191,7 +191,7 @@ end
seriestype := :path seriestype := :path
# create a secondary series for the markers # create a secondary series for the markers
if d[:markershape] != :none if plotattributes[:markershape] != :none
@series begin @series begin
seriestype := :scatter seriestype := :scatter
x := x x := x
@ -224,7 +224,7 @@ end
@recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30) @recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30)
args = z != nothing ? (x,y,z) : (x,y) args = z != nothing ? (x,y,z) : (x,y)
newx, newy = zeros(0), zeros(0) newx, newy = zeros(0), zeros(0)
fr = d[:fillrange] fr = plotattributes[:fillrange]
newfr = fr != nothing ? zeros(0) : nothing newfr = fr != nothing ? zeros(0) : nothing
newz = z != nothing ? zeros(0) : nothing newz = z != nothing ? zeros(0) : nothing
# lz = d[:line_z] # lz = d[:line_z]
@ -274,9 +274,9 @@ end
# create a bar plot as a filled step function # create a bar plot as a filled step function
@recipe function f(::Type{Val{:bar}}, x, y, z) @recipe function f(::Type{Val{:bar}}, x, y, z)
procx, procy, xscale, yscale, baseline = _preprocess_barlike(d, x, y) procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y)
nx, ny = length(procx), length(procy) nx, ny = length(procx), length(procy)
axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis] axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis]
cv = [discrete_value!(axis, xi)[1] for xi=procx] cv = [discrete_value!(axis, xi)[1] for xi=procx]
procx = if nx == ny procx = if nx == ny
cv cv
@ -287,7 +287,7 @@ end
end end
# compute half-width of bars # compute half-width of bars
bw = d[:bar_width] bw = plotattributes[:bar_width]
hw = if bw == nothing hw = if bw == nothing
0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx))) 0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx)))
else else
@ -295,7 +295,7 @@ end
end end
# make fillto a vector... default fills to 0 # make fillto a vector... default fills to 0
fillto = d[:fillrange] fillto = plotattributes[:fillrange]
if fillto == nothing if fillto == nothing
fillto = 0 fillto = 0
end end
@ -320,7 +320,7 @@ end
expand_extrema!(axis, widen(ignorenan_extrema(xseg.pts)...)) expand_extrema!(axis, widen(ignorenan_extrema(xseg.pts)...))
# switch back # switch back
if !isvertical(d) if !isvertical(plotattributes)
xseg, yseg = yseg, xseg xseg, yseg = yseg, xseg
end end
@ -389,8 +389,8 @@ end
@recipe function f(::Type{Val{:barbins}}, x, y, z) @recipe function f(::Type{Val{:barbins}}, x, y, z)
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
if (d[:bar_width] == nothing) if (plotattributes[:bar_width] == nothing)
bar_width := diff(edge) bar_width := diff(edge)
end end
x := _bin_centers(edge) x := _bin_centers(edge)
@ -402,7 +402,7 @@ end
@recipe function f(::Type{Val{:scatterbins}}, x, y, z) @recipe function f(::Type{Val{:scatterbins}}, x, y, z)
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
xerror := diff(edge)/2 xerror := diff(edge)/2
x := _bin_centers(edge) x := _bin_centers(edge)
y := weights y := weights
@ -465,17 +465,17 @@ end
@recipe function f(::Type{Val{:stepbins}}, x, y, z) @recipe function f(::Type{Val{:stepbins}}, x, y, z)
axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] axis = plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis]
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y)
xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale) xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale)
if !isvertical(d) if !isvertical(plotattributes)
xpts, ypts = ypts, xpts xpts, ypts = ypts, xpts
end end
# create a secondary series for the markers # create a secondary series for the markers
if d[:markershape] != :none if plotattributes[:markershape] != :none
@series begin @series begin
seriestype := :scatter seriestype := :scatter
x := _bin_centers(edge) x := _bin_centers(edge)
@ -563,7 +563,7 @@ end
@deps histogram barhist @deps histogram barhist
@recipe function f(::Type{Val{:barhist}}, x, y, z) @recipe function f(::Type{Val{:barhist}}, x, y, z)
h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights])
x := h.edges[1] x := h.edges[1]
y := h.weights y := h.weights
seriestype := :barbins seriestype := :barbins
@ -572,7 +572,7 @@ end
@deps barhist barbins @deps barhist barbins
@recipe function f(::Type{Val{:stephist}}, x, y, z) @recipe function f(::Type{Val{:stephist}}, x, y, z)
h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights])
x := h.edges[1] x := h.edges[1]
y := h.weights y := h.weights
seriestype := :stepbins seriestype := :stepbins
@ -581,7 +581,7 @@ end
@deps stephist stepbins @deps stephist stepbins
@recipe function f(::Type{Val{:scatterhist}}, x, y, z) @recipe function f(::Type{Val{:scatterhist}}, x, y, z)
h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights])
x := h.edges[1] x := h.edges[1]
y := h.weights y := h.weights
seriestype := :scatterbins seriestype := :scatterbins
@ -597,11 +597,11 @@ end
:bar => :barbins, :scatter => :scatterbins, :step => :stepbins, :bar => :barbins, :scatter => :scatterbins, :step => :stepbins,
:steppost => :stepbins # :step can be mapped to :steppost in pre-processing :steppost => :stepbins # :step can be mapped to :steppost in pre-processing
) )
seriestype := get(st_map, d[:seriestype], d[:seriestype]) seriestype := get(st_map, plotattributes[:seriestype], plotattributes[:seriestype])
if d[:seriestype] == :scatterbins if plotattributes[:seriestype] == :scatterbins
# Workaround, error bars currently not set correctly by scatterbins # Workaround, error bars currently not set correctly by scatterbins
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, h.edges[1], h.weights)
xerror --> diff(h.edges[1])/2 xerror --> diff(h.edges[1])/2
seriestype := :scatter seriestype := :scatter
(Plots._bin_centers(edge), weights) (Plots._bin_centers(edge), weights)
@ -648,7 +648,7 @@ Plots.@deps bins2d heatmap
@recipe function f(::Type{Val{:histogram2d}}, x, y, z) @recipe function f(::Type{Val{:histogram2d}}, x, y, z)
h = _make_hist((x, y), d[:bins], normed = d[:normalize], weights = d[:weights]) h = _make_hist((x, y), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights])
x := h.edges[1] x := h.edges[1]
y := h.edges[2] y := h.edges[2]
z := Surface(h.weights) z := Surface(h.weights)
@ -669,7 +669,7 @@ end
@recipe function f(::Type{Val{:scatter3d}}, x, y, z) @recipe function f(::Type{Val{:scatter3d}}, x, y, z)
seriestype := :path3d seriestype := :path3d
if d[:markershape] == :none if plotattributes[:markershape] == :none
markershape := :circle markershape := :circle
end end
linewidth := 0 linewidth := 0
@ -732,17 +732,17 @@ end
# we will create a series of path segments, where each point represents one # we will create a series of path segments, where each point represents one
# side of an errorbar # side of an errorbar
@recipe function f(::Type{Val{:yerror}}, x, y, z) @recipe function f(::Type{Val{:yerror}}, x, y, z)
error_style!(d) error_style!(plotattributes)
markershape := :hline markershape := :hline
d[:x], d[:y] = error_coords(d[:x], d[:y], error_zipit(d[:yerror])) plotattributes[:x], plotattributes[:y] = error_coords(plotattributes[:x], plotattributes[:y], error_zipit(plotattributes[:yerror]))
() ()
end end
@deps yerror path @deps yerror path
@recipe function f(::Type{Val{:xerror}}, x, y, z) @recipe function f(::Type{Val{:xerror}}, x, y, z)
error_style!(d) error_style!(plotattributes)
markershape := :vline markershape := :vline
d[:y], d[:x] = error_coords(d[:y], d[:x], error_zipit(d[:xerror])) plotattributes[:y], plotattributes[:x] = error_coords(plotattributes[:y], plotattributes[:x], error_zipit(plotattributes[:xerror]))
() ()
end end
@deps xerror path @deps xerror path
@ -841,9 +841,9 @@ end
# function apply_series_recipe(d::KW, ::Type{Val{:quiver}}) # function apply_series_recipe(d::KW, ::Type{Val{:quiver}})
@recipe function f(::Type{Val{:quiver}}, x, y, z) @recipe function f(::Type{Val{:quiver}}, x, y, z)
if :arrow in supported_attrs() if :arrow in supported_attrs()
quiver_using_arrows(d) quiver_using_arrows(plotattributes)
else else
quiver_using_hack(d) quiver_using_hack(plotattributes)
end end
() ()
end end
@ -948,10 +948,10 @@ end
rs, cs, zs = findnz(z.surf) rs, cs, zs = findnz(z.surf)
xlim := ignorenan_extrema(cs) xlim := ignorenan_extrema(cs)
ylim := ignorenan_extrema(rs) ylim := ignorenan_extrema(rs)
if d[:markershape] == :none if plotattributes[:markershape] == :none
markershape := :circle markershape := :circle
end end
if d[:markersize] == default(:markersize) if plotattributes[:markersize] == default(:markersize)
markersize := 1 markersize := 1
end end
markerstrokewidth := 0 markerstrokewidth := 0

View File

@ -128,15 +128,15 @@ immutable SliceIt end
z = z.data z = z.data
end end
xs, _ = convertToAnyVector(x, d) xs, _ = convertToAnyVector(x, plotattributes)
ys, _ = convertToAnyVector(y, d) ys, _ = convertToAnyVector(y, plotattributes)
zs, _ = convertToAnyVector(z, d) zs, _ = convertToAnyVector(z, plotattributes)
fr = pop!(d, :fillrange, nothing) fr = pop!(plotattributes, :fillrange, nothing)
fillranges, _ = if typeof(fr) <: Number fillranges, _ = if typeof(fr) <: Number
([fr],nothing) ([fr],nothing)
else else
convertToAnyVector(fr, d) convertToAnyVector(fr, plotattributes)
end end
mf = length(fillranges) mf = length(fillranges)
@ -148,7 +148,7 @@ immutable SliceIt end
if mx > 0 && my > 0 && mz > 0 if mx > 0 && my > 0 && mz > 0
for i in 1:max(mx, my, mz) for i in 1:max(mx, my, mz)
# add a new series # add a new series
di = copy(d) di = copy(plotattributes)
xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)] xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)]
di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi) di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi)
@ -206,11 +206,11 @@ _apply_type_recipe{T<:Union{Integer,AbstractFloat}}(d, v::AbstractArray{T}) = v
# handle "type recipes" by converting inputs, and then either re-calling or slicing # handle "type recipes" by converting inputs, and then either re-calling or slicing
@recipe function f(x, y, z) @recipe function f(x, y, z)
did_replace = false did_replace = false
newx = _apply_type_recipe(d, x) newx = _apply_type_recipe(plotattributes, x)
x === newx || (did_replace = true) x === newx || (did_replace = true)
newy = _apply_type_recipe(d, y) newy = _apply_type_recipe(plotattributes, y)
y === newy || (did_replace = true) y === newy || (did_replace = true)
newz = _apply_type_recipe(d, z) newz = _apply_type_recipe(plotattributes, z)
z === newz || (did_replace = true) z === newz || (did_replace = true)
if did_replace if did_replace
newx, newy, newz newx, newy, newz
@ -220,9 +220,9 @@ _apply_type_recipe{T<:Union{Integer,AbstractFloat}}(d, v::AbstractArray{T}) = v
end end
@recipe function f(x, y) @recipe function f(x, y)
did_replace = false did_replace = false
newx = _apply_type_recipe(d, x) newx = _apply_type_recipe(plotattributes, x)
x === newx || (did_replace = true) x === newx || (did_replace = true)
newy = _apply_type_recipe(d, y) newy = _apply_type_recipe(plotattributes, y)
y === newy || (did_replace = true) y === newy || (did_replace = true)
if did_replace if did_replace
newx, newy newx, newy
@ -231,7 +231,7 @@ end
end end
end end
@recipe function f(y) @recipe function f(y)
newy = _apply_type_recipe(d, y) newy = _apply_type_recipe(plotattributes, y)
if y !== newy if y !== newy
newy newy
else else
@ -244,7 +244,7 @@ end
@recipe function f(v1, v2, v3, v4, vrest...) @recipe function f(v1, v2, v3, v4, vrest...)
did_replace = false did_replace = false
newargs = map(v -> begin newargs = map(v -> begin
newv = _apply_type_recipe(d, v) newv = _apply_type_recipe(plotattributes, v)
if newv !== v if newv !== v
did_replace = true did_replace = true
end end
@ -271,13 +271,13 @@ function wrap_surfaces(d::KW)
end end
end end
@recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing) @recipe f(n::Integer) = is3d(get(plotattributes,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
# return a surface if this is a 3d plot, otherwise let it be sliced up # return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f{T<:Union{Integer,AbstractFloat}}(mat::AMat{T}) @recipe function f{T<:Union{Integer,AbstractFloat}}(mat::AMat{T})
if all3D(d) if all3D(plotattributes)
n,m = size(mat) n,m = size(mat)
wrap_surfaces(d) wrap_surfaces(plotattributes)
SliceIt, 1:m, 1:n, Surface(mat) SliceIt, 1:m, 1:n, Surface(mat)
else else
SliceIt, nothing, mat, nothing SliceIt, nothing, mat, nothing
@ -286,10 +286,10 @@ end
# if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface # if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface
@recipe function f{T<:AbstractMatrix}(fmt::Formatted{T}) @recipe function f{T<:AbstractMatrix}(fmt::Formatted{T})
if all3D(d) if all3D(plotattributes)
mat = fmt.data mat = fmt.data
n,m = size(mat) n,m = size(mat)
wrap_surfaces(d) wrap_surfaces(plotattributes)
SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter) SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter)
else else
SliceIt, nothing, fmt, nothing SliceIt, nothing, fmt, nothing
@ -329,7 +329,7 @@ end
else else
seriestype := :heatmap seriestype := :heatmap
yflip --> true yflip --> true
z, d[:fillcolor] = replace_image_with_heatmap(mat) z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, 1:m, 1:n, Surface(z) SliceIt, 1:m, 1:n, Surface(z)
end end
end end
@ -359,7 +359,7 @@ end
# function without range... use the current range of the x-axis # function without range... use the current range of the x-axis
@recipe function f{F<:Function}(f::FuncOrFuncs{F}) @recipe function f{F<:Function}(f::FuncOrFuncs{F})
plt = d[:plot_object] plt = plotattributes[:plot_object]
xmin, xmax = try xmin, xmax = try
axis_limits(plt[1][:xaxis]) axis_limits(plt[1][:xaxis])
catch catch
@ -421,7 +421,7 @@ end
# seriestype := :path3d # seriestype := :path3d
# end # end
# end # end
wrap_surfaces(d) wrap_surfaces(plotattributes)
SliceIt, x, y, z SliceIt, x, y, z
end end
@ -431,7 +431,7 @@ end
@recipe function f(x::AVec, y::AVec, zf::Function) @recipe function f(x::AVec, y::AVec, zf::Function)
# x = X <: Number ? sort(x) : x # x = X <: Number ? sort(x) : x
# y = Y <: Number ? sort(y) : y # y = Y <: Number ? sort(y) : y
wrap_surfaces(d) wrap_surfaces(plotattributes)
SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
end end
@ -439,10 +439,10 @@ end
# # surface-like... matrix grid # # surface-like... matrix grid
@recipe function f(x::AVec, y::AVec, z::AMat) @recipe function f(x::AVec, y::AVec, z::AMat)
if !like_surface(get(d, :seriestype, :none)) if !like_surface(get(plotattributes, :seriestype, :none))
d[:seriestype] = :contour plotattributes[:seriestype] = :contour
end end
wrap_surfaces(d) wrap_surfaces(plotattributes)
SliceIt, x, y, Surface(z) SliceIt, x, y, Surface(z)
end end
@ -494,7 +494,7 @@ end
@recipe f{R1<:Number,R2<:Number,R3<:Number}(xyz::Tuple{R1,R2,R3}) = [xyz[1]], [xyz[2]], [xyz[3]] @recipe f{R1<:Number,R2<:Number,R3<:Number}(xyz::Tuple{R1,R2,R3}) = [xyz[1]], [xyz[2]], [xyz[3]]
# these might be points+velocity, or OHLC or something else # these might be points+velocity, or OHLC or something else
@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::AVec{Tuple{R1,R2,R3,R4}}) = get(d,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) @recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::AVec{Tuple{R1,R2,R3,R4}}) = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::Tuple{R1,R2,R3,R4}) = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]] @recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::Tuple{R1,R2,R3,R4}) = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]]
@ -556,7 +556,7 @@ group_as_matrix(t) = false
@series begin @series begin
label --> string(glab) label --> string(glab)
idxfilter --> groupby.groupIds[i] idxfilter --> groupby.groupIds[i]
for (key,val) in d for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup) if splittable_kw(key, val, lengthGroup)
:($key) := split_kw(key, val, groupby.groupIds[i]) :($key) := split_kw(key, val, groupby.groupIds[i])
end end
@ -578,7 +578,7 @@ group_as_matrix(t) = false
end end
x_u = unique(x) x_u = unique(x)
x_ind = Dict(zip(x_u, 1:length(x_u))) x_ind = Dict(zip(x_u, 1:length(x_u)))
for (key,val) in d for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup) if splittable_kw(key, val, lengthGroup)
:($key) := groupedvec2mat(x_ind, x, val, groupby) :($key) := groupedvec2mat(x_ind, x, val, groupby)
end end