working on colors, args

This commit is contained in:
Thomas Breloff 2015-09-18 16:53:43 -04:00
parent fa899a67a7
commit 455f85e230
3 changed files with 111 additions and 38 deletions

View File

@ -3,7 +3,7 @@
# const COLORS = [:black, :blue, :green, :red, :darkGray, :darkCyan, :darkYellow, :darkMagenta, # const COLORS = [:black, :blue, :green, :red, :darkGray, :darkCyan, :darkYellow, :darkMagenta,
# :darkBlue, :darkGreen, :darkRed, :gray, :cyan, :yellow, :magenta] # :darkBlue, :darkGreen, :darkRed, :gray, :cyan, :yellow, :magenta]
const COLORS = distinguishable_colors(20) # const COLORS = distinguishable_colors(20)
const AXES = [:left, :right] const AXES = [:left, :right]
const TYPES = [:line, const TYPES = [:line,
:step, :step,
@ -185,23 +185,76 @@ end
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
convertColor(c::Union{AbstractString, Symbol}) = parse(Colorant, string(c))
convertColor(c::Colorant) = c
convertColor(cvec::AbstractVector) = map(convertColor, cvec)
# for now, choose a boundary value on the other side from the background value
function adjustAway(bgval, vmin=0., vmax=100.)
bgval < 0.5 * (vmax+vmin) ? vmax : vmin
end
function getBackgroundRGBColor(c, d::Dict)
bgcolor = convertColor(d[:background_color])
d[:background_color] = bgcolor
# d[:color_palette] = RGB{Float64}[bgcolor]
palette = distinguishable_colors(20, bgcolor)[2:end]
@show palette
# try to adjust colors away from background color
# for now, lets do this by moving both lightness and chroma to to other side of the spectrum as compared to the background
bg_lab = Lab(bgcolor)
palette = RGB{Float64}[begin
lab = Lab(rgb)
Lab(
adjustAway(bg_lab.l, -128, 128),
# adjustAway(bg_lab.a, -128, 128),
lab.a,
lab.b
)
end for rgb in palette]
d[:color_palette] = palette
@show d[:color_palette]
bgcolor
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
# note: if plt is nothing, we aren't doing anything with the color anyways function getSeriesRGBColor(c, d::Dict, n::Int)
function getRGBColor(c, n::Int = 0)
# auto-assign a color based on plot index # # create a color palette on the fly using the background color as the seed
if c == :auto && n > 0 # if !haskey(d, :color_palette)
c = autopick(COLORS, n) # c = convertColor(d[:background_color])
end # d[:background_color] = c
# d[:color_palette] = cp = RGB[c]
# else
# convert it from a symbol/string # cp = d[:color_palette]
if isa(c, Symbol) # @show n cp
c = string(c) # if length(cp) < n+1
end # cp = distinguishable_colors(n+1, cp)
if isa(c, AbstractString) # @show cp
c = parse(Colorant, c) # d[:color_palette] = cp
end # end
c = (c == :auto ? autopick(d[:color_palette], n) : convertColor(c))
# if c == :auto
# # pick a new color
# cp = d[:color_palette]
# if length(cp) < n+1
# cp = distinguishable_colors(n+1, cp)
# end
# c = cp[n+1]
# d[:color_palette] = cp
# end
# @show d[:color_palette]
# @show c length(cp)
# # just to be safe
# c = convertColor(c)
# # push!(d[:color_palette], c)
# # @show c d[:color_palette]
# should be a RGB now... either it was passed in, generated automatically, or created from a string # should be a RGB now... either it was passed in, generated automatically, or created from a string
@assert isa(c, RGB) @assert isa(c, RGB)
@ -237,7 +290,7 @@ function getPlotArgs(pkg::PlottingPackage, kw, idx::Int)
end end
# convert color # convert color
d[:background_color] = getRGBColor(d[:background_color]) d[:background_color] = getBackgroundRGBColor(d[:background_color], d)
# no need for these # no need for these
delete!(d, :x) delete!(d, :x)
@ -249,7 +302,7 @@ end
# note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot # note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot
function getSeriesArgs(pkg::PlottingPackage, kw, idx::Int, n::Int) function getSeriesArgs(pkg::PlottingPackage, initargs::Dict, kw, idx::Int, n::Int) # TODO, pass in initargs, not plt
d = Dict(kw) d = Dict(kw)
# add defaults? # add defaults?
@ -277,11 +330,11 @@ function getSeriesArgs(pkg::PlottingPackage, kw, idx::Int, n::Int)
end end
# update color # update color
d[:color] = getRGBColor(d[:color], n) d[:color] = getSeriesRGBColor(d[:color], initargs, n)
# update markercolor # update markercolor
mc = d[:markercolor] mc = d[:markercolor]
mc = (mc == :match ? d[:color] : getRGBColor(mc, n)) mc = (mc == :match ? d[:color] : getSeriesRGBColor(mc, initargs, n))
d[:markercolor] = mc d[:markercolor] = mc
# set label # set label

View File

@ -22,6 +22,7 @@ Base.print(io::IO, plt::Plot) = print(io, string(plt))
Base.show(io::IO, plt::Plot) = print(io, string(plt)) Base.show(io::IO, plt::Plot) = print(io, string(plt))
getplot(plt::Plot) = plt getplot(plt::Plot) = plt
getinitargs(plt::Plot, idx::Int = 1) = plt.initargs
doc""" doc"""
@ -90,7 +91,15 @@ function plot(args...; kw...)
pkg = plotter() pkg = plotter()
d = Dict(kw) d = Dict(kw)
replaceAliases!(d) replaceAliases!(d)
# # ensure we're passing in an RGB
# if haskey(d, :background_color)
# d[:background_color] = convertColor(d[:background_color])
# end
plt = plot(pkg; getPlotArgs(pkg, d, 1)...) # create a new, blank plot plt = plot(pkg; getPlotArgs(pkg, d, 1)...) # create a new, blank plot
delete!(d, :background_color)
plot!(plt, args...; d...) # add to it plot!(plt, args...; d...) # add to it
end end
@ -158,7 +167,7 @@ function createKWargsList(plt::PlottingObject; kw...)
if !haskey(d, :x) if !haskey(d, :x)
d[:x] = 1:length(d[:y]) d[:x] = 1:length(d[:y])
end end
[getSeriesArgs(plt.plotter, d, 1, plt.n + 1)] [getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), d, 1, plt.n + 1)]
end end
@ -169,7 +178,7 @@ end
# create one series where y is vectors of numbers # create one series where y is vectors of numbers
function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...) function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = 1:length(y) d[:x] = 1:length(y)
d[:y] = y d[:y] = y
[d] [d]
@ -178,7 +187,7 @@ end
# create one series where x/y are vectors of numbers # create one series where x/y are vectors of numbers
function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec{S}; kw...) function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec{S}; kw...)
@assert length(x) == length(y) @assert length(x) == length(y)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x d[:x] = x
d[:y] = y d[:y] = y
[d] [d]
@ -189,7 +198,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, y::AMat{T}; kw...)
n,m = size(y) n,m = size(y)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = 1:n d[:x] = 1:n
d[:y] = y[:,i] d[:y] = y[:,i]
push!(ret, d) push!(ret, d)
@ -203,7 +212,7 @@ function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::A
@assert length(x) == n @assert length(x) == n
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x d[:x] = x
d[:y] = y[:,i] d[:y] = y[:,i]
push!(ret, d) push!(ret, d)
@ -217,7 +226,7 @@ function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AMat{T}, y::A
n,m = size(y) n,m = size(y)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x[:,i] d[:x] = x[:,i]
d[:y] = y[:,i] d[:y] = y[:,i]
push!(ret, d) push!(ret, d)
@ -232,7 +241,7 @@ end
# create 1 series, y = f(x), x ∈ [xmin, xmax] # create 1 series, y = f(x), x ∈ [xmin, xmax]
function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...) function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
width = plt.initargs[:size][1] width = plt.initargs[:size][1]
d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width
d[:y] = map(f, d[:x]) d[:y] = map(f, d[:x])
@ -246,7 +255,7 @@ function createKWargsList(plt::PlottingObject, fs::Vector{Function}, xmin::Real,
width = plt.initargs[:size][1] width = plt.initargs[:size][1]
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x d[:x] = x
d[:y] = map(fs[i], x) d[:y] = map(fs[i], x)
push!(ret, d) push!(ret, d)
@ -256,7 +265,7 @@ end
# create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax] # create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax]
function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...) function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
width = plt.initargs[:size][1] width = plt.initargs[:size][1]
u = collect(linspace(umin, umax, width)) # we don't need more than the width u = collect(linspace(umin, umax, width)) # we don't need more than the width
d[:x] = map(fx, u) d[:x] = map(fx, u)
@ -266,7 +275,7 @@ end
# create 1 series, y = f(x) # create 1 series, y = f(x)
function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, f::Function; kw...) function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, f::Function; kw...)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x d[:x] = x
d[:y] = map(f, x) d[:y] = map(f, x)
[d] [d]
@ -278,7 +287,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AMat{T}, f::Function;
n,m = size(x) n,m = size(x)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x[:,i] d[:x] = x[:,i]
d[:y] = map(f, d[:x]) d[:y] = map(f, d[:x])
push!(ret, d) push!(ret, d)
@ -298,7 +307,7 @@ function createKWargsList(plt::PlottingObject, y::AVec; kw...)
m = length(y) m = length(y)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = 1:length(y[i]) d[:x] = 1:length(y[i])
d[:y] = y[i] d[:y] = y[i]
push!(ret, d) push!(ret, d)
@ -318,7 +327,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec; kw.
m = length(y) m = length(y)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x d[:x] = x
d[:y] = getyvec(x, y[i]) d[:y] = getyvec(x, y[i])
push!(ret, d) push!(ret, d)
@ -332,7 +341,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec, y::AMat{T}; kw.
@assert length(x) == m @assert length(x) == m
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x[i] d[:x] = x[i]
d[:y] = getyvec(x[i], y[:,i]) d[:y] = getyvec(x[i], y[:,i])
push!(ret, d) push!(ret, d)
@ -346,7 +355,7 @@ function createKWargsList(plt::PlottingObject, x::AVec, y::AVec; kw...)
m = length(y) m = length(y)
ret = [] ret = []
for i in 1:m for i in 1:m
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = x[i] d[:x] = x[i]
d[:y] = getyvec(x[i], y[i]) d[:y] = getyvec(x[i], y[i])
push!(ret, d) push!(ret, d)
@ -358,7 +367,7 @@ end
function createKWargsList(plt::PlottingObject, n::Integer; kw...) function createKWargsList(plt::PlottingObject, n::Integer; kw...)
ret = [] ret = []
for i in 1:n for i in 1:n
d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, i, plt.n + i)
d[:x] = zeros(0) d[:x] = zeros(0)
d[:y] = zeros(0) d[:y] = zeros(0)
push!(ret, d) push!(ret, d)
@ -370,7 +379,7 @@ end
createKWargsList{T<:Tuple}(plt::PlottingObject, y::AVec{T}; kw...) = createKWargsList(plt, 1:length(y), y; kw...) createKWargsList{T<:Tuple}(plt::PlottingObject, y::AVec{T}; kw...) = createKWargsList(plt, 1:length(y), y; kw...)
function createKWargsList{S<:Real, T<:Tuple}(plt::PlottingObject, x::AVec{S}, y::AVec{T}; kw...) function createKWargsList{S<:Real, T<:Tuple}(plt::PlottingObject, x::AVec{S}, y::AVec{T}; kw...)
d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x d[:x] = x
d[:y] = y d[:y] = y
[d] [d]

View File

@ -41,7 +41,8 @@ Base.string(subplt::Subplot) = "Subplot{$(subplt.plotter) p=$(subplt.p) n=$(subp
Base.print(io::IO, subplt::Subplot) = print(io, string(subplt)) Base.print(io::IO, subplt::Subplot) = print(io, string(subplt))
Base.show(io::IO, subplt::Subplot) = print(io, string(subplt)) Base.show(io::IO, subplt::Subplot) = print(io, string(subplt))
getplot(subplt::Subplot) = subplt.plts[mod1(subplt.n, subplt.p)] getplot(subplt::Subplot, idx::Int = subplt.n) = subplt.plts[mod1(idx, subplt.p)]
getinitargs(subplt::Subplot, idx::Int) = getplot(subplt, idx).initargs
# ------------------------------------------------------------ # ------------------------------------------------------------
@ -58,6 +59,7 @@ Create a series of plots:
""" """
function subplot(args...; kw...) function subplot(args...; kw...)
d = Dict(kw) d = Dict(kw)
replaceAliases!(d)
# figure out the layout # figure out the layout
if haskey(d, :layout) if haskey(d, :layout)
@ -74,7 +76,7 @@ function subplot(args...; kw...)
plts = Plot[] plts = Plot[]
ds = Dict[] ds = Dict[]
for i in 1:length(layout) for i in 1:length(layout)
push!(ds, getPlotArgs(pkg, kw, i)) push!(ds, getPlotArgs(pkg, d, i))
push!(plts, plot(pkg; ds[i]...)) push!(plts, plot(pkg; ds[i]...))
end end
@ -113,11 +115,20 @@ function subplot!(subplt::Subplot, args...; kw...)
error(CURRENT_BACKEND.sym, " does not support the subplot/subplot! commands at this time. Try one of: ", join(filter(pkg->subplotSupported(backend(pkg)), backends()),", ")) error(CURRENT_BACKEND.sym, " does not support the subplot/subplot! commands at this time. Try one of: ", join(filter(pkg->subplotSupported(backend(pkg)), backends()),", "))
end end
kwList = createKWargsList(subplt, args...; kw...) d = Dict(kw)
replaceAliases!(d)
@show d
for k in keys(_plotDefaults)
delete!(d, k)
end
@show d
kwList = createKWargsList(subplt, args...; d...)
for (i,d) in enumerate(kwList) for (i,d) in enumerate(kwList)
subplt.n += 1 subplt.n += 1
plt = getplot(subplt) # get the Plot object where this series will be drawn plt = getplot(subplt) # get the Plot object where this series will be drawn
d[:show] = false d[:show] = false
@show d
plot!(plt; d...) plot!(plt; d...)
end end