diff --git a/README.md b/README.md index 50135a77..82374ba0 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ Keyword | Default | Type | Aliases `:annotation` | `nothing` | Series | `:ann`, `:annotate`, `:annotations`, `:anns` `:axis` | `left` | Series | `:axiss` `:color` | `auto` | Series | `:c`, `:colors` -`:fillto` | `nothing` | Series | `:area`, `:fill`, `:filltos` +`:fill` | `nothing` | Series | `:area`, `:fill`, `:fills` `:group` | `nothing` | Series | `:g`, `:groups` `:heatmap_c` | `(0.15,0.5)` | Series | `:heatmap_cs` `:label` | `AUTO` | Series | `:lab`, `:labels` diff --git a/src/Plots.jl b/src/Plots.jl index a54c78ab..f9e38023 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -15,6 +15,7 @@ export current, default, + colorscheme, scatter, scatter!, diff --git a/src/args.jl b/src/args.jl index 9f325764..ac3c498c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -113,7 +113,7 @@ _seriesDefaults[:fillcolor] = :match # _seriesDefaults[:ribboncolor] = :match _seriesDefaults[:nbins] = 100 # number of bins for heatmaps and hists _seriesDefaults[:heatmap_c] = (0.15, 0.5) # TODO: this should be replaced with a ColorGradient -# _seriesDefaults[:fillto] = nothing # fills in the area +# _seriesDefaults[:fill] = nothing # fills in the area _seriesDefaults[:reg] = false # regression line? _seriesDefaults[:group] = nothing # groupby vector _seriesDefaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation) @@ -206,8 +206,8 @@ const _keyAliases = Dict( :msize => :markersize, :nb => :nbins, :nbin => :nbins, - :fill => :fillto, - :area => :fillto, + :fill => :fill, + :area => :fill, :g => :group, :rib => :ribbon, :ann => :annotation, @@ -305,16 +305,11 @@ function processAxisArg(d::Dict, axisletter::AbstractString, arg) if T <: Symbol - # xscale/yscale - if haskey(_scaleAliases, arg) - arg = _scaleAliases[arg] - end + arg = get(_scaleAliases, arg, arg) + if arg in _allScales d[symbol(axisletter * "scale")] = arg - end - - # xflip/yflip - if arg in (:flip, :invert, :inverted) + elseif arg in (:flip, :invert, :inverted) d[symbol(axisletter * "flip")] = true end @@ -332,6 +327,15 @@ function processAxisArg(d::Dict, axisletter::AbstractString, arg) end end +function handleColors!(d::Dict, arg, csym::Symbol) + try + c = colorscheme(arg) + d[csym] = c + return true + end + false +end + function processLineArg(d::Dict, arg) T = typeof(arg) delete!(d, :line) @@ -346,7 +350,7 @@ function processLineArg(d::Dict, arg) d[:linetype] = arg elseif arg in _allStyles d[:linestyle] = arg - else + elseif !handleColors!(d, arg, :color) warn("Skipped line arg $arg. Unknown symbol.") end @@ -354,14 +358,8 @@ function processLineArg(d::Dict, arg) elseif T <: Real d[:linewidth] = arg - else - - try - c = colorscheme(arg) - d[:color] = c - catch - warn("Skipped line arg $arg. Unhandled type $T.") - end + elseif !handleColors!(d, arg, :color) + warn("Skipped line arg $arg. Unhandled type $T.") end end @@ -377,7 +375,7 @@ function processMarkerArg(d::Dict, arg) if arg in _allMarkers d[:marker] = arg - elseif arg != :match + elseif arg != :match && !handleColors!(d, arg, :markercolor) warn("Skipped marker arg $arg. Unknown symbol.") end @@ -385,15 +383,9 @@ function processMarkerArg(d::Dict, arg) elseif T <: Real d[:markersize] = arg - else - - try - c = colorscheme(arg) - d[:markercolor] = c - catch - warn("Skipped marker arg $arg. Unhandled type $T.") - end - + elseif !handleColors!(d, arg, :markercolor) + warn("Skipped marker arg $arg. Unhandled type $T.") + end end diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl index 57aa17cf..09c8cf50 100644 --- a/src/backends/gadfly.jl +++ b/src/backends/gadfly.jl @@ -14,7 +14,7 @@ supportedArgs(::GadflyPackage) = [ # :axis, :background_color, :color, - :fillto, + :fill, # :foreground_color, :group, # :heatmap_c, @@ -153,7 +153,8 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict) # set theme: color, line linewidth, and point size line_width = d[:linewidth] * (d[:linetype] in (:none, :ohlc, :scatter) ? 0 : 1) * Gadfly.px # 0 linewidth when we don't show a line - line_color = isa(d[:color], AbstractVector) ? colorant"black" : d[:color] + # line_color = isa(d[:color], AbstractVector) ? colorant"black" : d[:color] + line_color = getColor(d[:color], 1) # fg = initargs[:foreground_color] theme = Gadfly.Theme(; default_color = line_color, line_width = line_width, @@ -195,50 +196,67 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict) append!(gfargs, getLineGeoms(d)) # colorgroup - if isa(d[:color], AbstractVector) + z = d[:z] + + # handle line segments of different colors + cscheme = d[:color] + if isa(cscheme, ColorVector) # create a color scale, and set the color group to the index of the color - push!(gplt.scales, Gadfly.Scale.color_discrete_manual(d[:color]...)) + push!(gplt.scales, Gadfly.Scale.color_discrete_manual(cscheme.v...)) # this is super weird, but... oh well... for some reason this creates n separate line segments... # create a list of vertices that go: [x1,x2,x2,x3,x3, ... ,xi,xi, ... xn,xn] (same for y) # then the vector passed to the "color" keyword should be a vector: [1,1,2,2,3,3,4,4, ..., i,i, ... , n,n] - csindices = Int[mod1(i,length(d[:color])) for i in 1:length(d[:y])] + csindices = Int[mod1(i,length(cscheme.v)) for i in 1:length(d[:y])] cs = collect(repmat(csindices', 2, 1))[1:end-1] grp = collect(repmat((1:length(d[:y]))', 2, 1))[1:end-1] d[:x], d[:y] = map(createSegments, (d[:x], d[:y])) colorgroup = [(:color, cs), (:group, grp)] - elseif d[:z] != nothing - # colorgroup = [(:color, d[:z]), (:color_key_title, d[:label])] - colorgroup = [(:color, d[:z])] + # handle continuous color scales for the markers + elseif z != nothing && typeof(z) <: AVec + colorgroup = [(:color, z)] + minz, maxz = minimum(z), maximum(z) + push!(gplt.scales, Gadfly.Scale.ContinuousColorScale(p -> getColor(d[:markercolor], minz + p * (maxz - minz)))) + # nothing special... else colorgroup = [] end - # fillto and ribbon + # fills/ribbons yminmax = [] - fillto, ribbon = d[:fillto], d[:ribbon] - - if fillto != nothing - if ribbon != nothing - warn("Ignoring ribbon arg since fillto is set!") - end - fillto = makevec(fillto) - n = length(fillto) - push!(yminmax, (:ymin, Float64[min(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])])) - push!(yminmax, (:ymax, Float64[max(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])])) + if d[:fill] != nothing + fillmin, fillmax = map(makevec, maketuple(d[:fill])) + nmin, nmax = length(fillmin), length(fillmax) + push!(yminmax, (:ymin, Float64[min(y, fillmin[mod1(i, nmin)], fillmax[mod1(i, nmax)]) for (i,y) in enumerate(d[:y])])) + push!(yminmax, (:ymax, Float64[max(y, fillmin[mod1(i, nmin)], fillmax[mod1(i, nmax)]) for (i,y) in enumerate(d[:y])])) push!(gfargs, Gadfly.Geom.ribbon) - - elseif ribbon != nothing - ribbon = makevec(ribbon) - n = length(ribbon) - @show ribbon - push!(yminmax, (:ymin, Float64[y - ribbon[mod1(i,n)] for (i,y) in enumerate(d[:y])])) - push!(yminmax, (:ymax, Float64[y + ribbon[mod1(i,n)] for (i,y) in enumerate(d[:y])])) - push!(gfargs, Gadfly.Geom.ribbon) - end + + # # fillto and ribbon + # yminmax = [] + # fillto, ribbon = d[:fill], d[:ribbon] + + # if fillto != nothing + # if ribbon != nothing + # warn("Ignoring ribbon arg since fillto is set!") + # end + # fillto = makevec(fillto) + # n = length(fillto) + # push!(yminmax, (:ymin, Float64[min(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])])) + # push!(yminmax, (:ymax, Float64[max(y, fillto[mod1(i,n)]) for (i,y) in enumerate(d[:y])])) + # push!(gfargs, Gadfly.Geom.ribbon) + + # elseif ribbon != nothing + # ribbon = makevec(ribbon) + # n = length(ribbon) + # @show ribbon + # push!(yminmax, (:ymin, Float64[y - ribbon[mod1(i,n)] for (i,y) in enumerate(d[:y])])) + # push!(yminmax, (:ymax, Float64[y + ribbon[mod1(i,n)] for (i,y) in enumerate(d[:y])])) + # push!(gfargs, Gadfly.Geom.ribbon) + + # end # handle markers geoms, guides = getMarkerGeomsAndGuides(d) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 52b9815b..c54d875b 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -8,14 +8,14 @@ pyplot() = backend(:pyplot) # ------------------------------- -# supportedArgs(::PyPlotPackage) = setdiff(_allArgs, [:reg, :heatmap_c, :fillto, :pos, :xlims, :ylims, :xticks, :yticks]) +# supportedArgs(::PyPlotPackage) = setdiff(_allArgs, [:reg, :heatmap_c, :fill, :pos, :xlims, :ylims, :xticks, :yticks]) supportedArgs(::PyPlotPackage) = [ :annotation, # :args, :axis, :background_color, :color, - # :fillto, + # :fill, :foreground_color, :group, # :heatmap_c, @@ -227,7 +227,7 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...) if lt in (:hist, :sticks, :bar) # NOTE: this is unsupported because it does the wrong thing... it shifts the whole axis - # extraargs[:bottom] = d[:fillto] + # extraargs[:bottom] = d[:fill] if lt == :hist extraargs[:bins] = d[:nbins] diff --git a/src/backends/qwt.jl b/src/backends/qwt.jl index 8a1fc5cc..6dd67031 100644 --- a/src/backends/qwt.jl +++ b/src/backends/qwt.jl @@ -13,7 +13,7 @@ supportedArgs(::QwtPackage) = [ :axis, :background_color, :color, - :fillto, + :fill, :foreground_color, :group, :heatmap_c, diff --git a/src/backends/template.jl b/src/backends/template.jl index 3fd401bb..385ea711 100644 --- a/src/backends/template.jl +++ b/src/backends/template.jl @@ -17,7 +17,7 @@ supportedArgs(::[PkgName]Package) = [ :axis, :background_color, :color, - :fillto, + :fill, :foreground_color, :group, # :heatmap_c, diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index dc632470..a35e79e7 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -8,14 +8,14 @@ unicodeplots() = backend(:unicodeplots) # ------------------------------- -# supportedArgs(::UnicodePlotsPackage) = setdiff(_allArgs, [:reg, :heatmap_c, :fillto, :pos, :xlims, :ylims, :xticks, :yticks]) +# supportedArgs(::UnicodePlotsPackage) = setdiff(_allArgs, [:reg, :heatmap_c, :fill, :pos, :xlims, :ylims, :xticks, :yticks]) supportedArgs(::UnicodePlotsPackage) = [ # :annotation, # :args, # :axis, # :background_color, # :color, - # :fillto, + # :fill, # :foreground_color, :group, # :heatmap_c, diff --git a/src/backends/winston.jl b/src/backends/winston.jl index 5a558ed3..5aebb9de 100644 --- a/src/backends/winston.jl +++ b/src/backends/winston.jl @@ -30,14 +30,14 @@ const winston_marker = Dict(:none=>".", ) -# supportedArgs(::WinstonPackage) = setdiff(_allArgs, [:heatmap_c, :fillto, :pos, :markercolor, :background_color, :xlims, :ylims, :xticks, :yticks]) +# supportedArgs(::WinstonPackage) = setdiff(_allArgs, [:heatmap_c, :fill, :pos, :markercolor, :background_color, :xlims, :ylims, :xticks, :yticks]) supportedArgs(::WinstonPackage) = [ :annotation, # :args, # :axis, # :background_color, :color, - :fillto, + :fill, # :foreground_color, :group, # :heatmap_c, @@ -150,7 +150,7 @@ function plot!(::WinstonPackage, plt::Plot; kw...) x, y = d[:x], d[:y] Winston.add(wplt, Winston.Curve(x, y; e...)) - fillto = d[:fillto] + fillto = d[:fill] if fillto != nothing if isa(fillto, AbstractVector) y2 = fillto diff --git a/src/colors.jl b/src/colors.jl index f0f0f487..021483a7 100644 --- a/src/colors.jl +++ b/src/colors.jl @@ -83,6 +83,7 @@ abstract ColorScheme getColor(scheme::ColorScheme, idx::Integer) = getColor(scheme, 0.0, idx) getColor(scheme::ColorScheme, z::AbstractFloat) = getColor(scheme, z, 0) +colorscheme(scheme::ColorScheme) = scheme colorscheme(s::Symbol) = haskey(_gradients, s) ? ColorGradient(s) : ColorWrapper(convertColor(s)) colorscheme{T<:Real}(s::Symbol, vals::AVec{T}) = ColorGradient(s, vals) colorscheme(cs::AVec, vs::AVec) = ColorGradient(cs, vs) @@ -288,13 +289,11 @@ function getSeriesRGBColor(c, d::Dict, n::Int) if c == :auto c = autopick(d[:color_palette], n) - else - c = convertColor(c) + # else + # # c = convertColor(c) + # c = colorscheme(c) end - # # should be a RGB now... either it was passed in, generated automatically, or created from a string - # @assert isa(c, Colorant) - - # return the RGB - c + # c should now be a subtype of ColorScheme + colorscheme(c) end diff --git a/src/plot.jl b/src/plot.jl index 04b81337..aa63f1a1 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -46,7 +46,10 @@ function plot(args...; kw...) pkg = backend() d = Dict(kw) preprocessArgs!(d) - for k in sort(collect(keys(d))); println(); @printf("%14s: ", k); println(d[k], "\n"); end + + println() + for k in sort(collect(keys(d))); @printf("%14s: ", k); println(d[k]); end + println() # # ensure we're passing in an RGB # if haskey(d, :background_color) diff --git a/src/utils.jl b/src/utils.jl index 6b720876..6a525174 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -26,7 +26,7 @@ function histogramHack(; kw...) d[:x] = midpoints d[:y] = float(counts) d[:linetype] = :bar - d[:fillto] = d[:fillto] == nothing ? 0.0 : d[:fillto] + d[:fill] = d[:fill] == nothing ? 0.0 : d[:fill] d end @@ -38,7 +38,7 @@ function barHack(; kw...) d = Dict(kw) midpoints = d[:x] heights = d[:y] - fillto = d[:fillto] == nothing ? 0.0 : d[:fillto] + fillto = d[:fill] == nothing ? 0.0 : d[:fill] # estimate the edges dists = diff(midpoints) * 0.5 @@ -65,7 +65,7 @@ function barHack(; kw...) d[:x] = x d[:y] = y d[:linetype] = :path - d[:fillto] = fillto + d[:fill] = fillto d end @@ -81,7 +81,7 @@ function sticksHack(; kw...) # these are the line vertices x = Float64[] y = Float64[] - fillto = dLine[:fillto] == nothing ? 0.0 : dLine[:fillto] + fillto = dLine[:fill] == nothing ? 0.0 : dLine[:fill] # calculate the vertices yScatter = dScatter[:y] @@ -96,7 +96,7 @@ function sticksHack(; kw...) dLine[:y] = y dLine[:linetype] = :path dLine[:marker] = :none - dLine[:fillto] = nothing + dLine[:fill] = nothing # change the scatter args dScatter[:linetype] = :none