working on colors, args, and axis flip

This commit is contained in:
Thomas Breloff 2015-10-06 17:51:54 -04:00
parent bbc18549b3
commit e5007b6c87
13 changed files with 710 additions and 364 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -101,7 +101,7 @@ ohlc!(args...; kw...) = plot!(args...; kw..., linetype = :ohlc)
"Sparsity plot... heatmap of non-zero values of a matrix"
function spy{T<:Real}(y::AMat{T}; kw...)
I,J,V = findnz(y)
heatmap(J, I; leg=false, kw...)
heatmap(J, I; leg=false, yflip=true, kw...)
end
title!(s::AbstractString) = plot!(title = s)

View File

@ -104,10 +104,10 @@ _seriesDefaults[:label] = "AUTO"
_seriesDefaults[:linetype] = :path
_seriesDefaults[:linestyle] = :solid
_seriesDefaults[:linewidth] = 1
_seriesDefaults[:marker] = :none
_seriesDefaults[:markershape] = :none
_seriesDefaults[:markercolor] = :match
_seriesDefaults[:markersize] = 6
_seriesDefaults[:fill] = nothing # ribbons, areas, etc
_seriesDefaults[:fillrange] = nothing # ribbons, areas, etc
_seriesDefaults[:fillcolor] = :match
# _seriesDefaults[:ribbon] = nothing
# _seriesDefaults[:ribboncolor] = :match
@ -159,6 +159,13 @@ supportedArgs(::PlottingPackage) = _allArgs
supportedArgs() = supportedArgs(backend())
const _argNotes = Dict(
:color => "Series color. To have different marker and/or fill colors, optionally set the markercolor and fillcolor args.",
:z => "Determines the depth. For color gradients, we expect 0 ≤ z ≤ 1.",
:heatmap_c => "For Qwt heatmaps only... will be deprecated eventually.",
)
# -----------------------------------------------------------------------------
makeplural(s::Symbol) = Symbol(string(s,"s"))
@ -200,16 +207,19 @@ const _keyAliases = Dict(
:s => :linestyle,
:ls => :linestyle,
:m => :marker,
:shape => :marker,
:mark => :marker,
:shape => :markershape,
:mc => :markercolor,
:mcolor => :markercolor,
:ms => :markersize,
:msize => :markersize,
:area => :fill,
:fillrng => :fillrange,
:fc => :fillcolor,
:fcolor => :fillcolor,
:g => :group,
:nb => :nbins,
:nbin => :nbins,
:fill => :fill,
:area => :fill,
:g => :group,
:rib => :ribbon,
:ann => :annotation,
:anns => :annotation,
@ -299,32 +309,8 @@ end
wraptuple(x::Tuple) = x
wraptuple(x) = (x,)
# given one value (:log, or :flip, or (-1,1), etc), set the appropriate arg
function processAxisArg(d::Dict, axisletter::AbstractString, arg)
T = typeof(arg)
if T <: Symbol
arg = get(_scaleAliases, arg, arg)
if arg in _allScales
d[symbol(axisletter * "scale")] = arg
elseif arg in (:flip, :invert, :inverted)
d[symbol(axisletter * "flip")] = true
end
# xlims/ylims
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
d[symbol(axisletter * "lims")] = arg
# xticks/yticks
elseif T <: AVec
d[symbol(axisletter * "ticks")] = arg
else
warn("Skipped $(axisletter)axis arg $arg. Unhandled type $T")
end
end
trueOrAllTrue(f::Function, x::AVec) = all(f, x)
trueOrAllTrue(f::Function, x) = f(x)
function handleColors!(d::Dict, arg, csym::Symbol)
try
@ -335,57 +321,82 @@ function handleColors!(d::Dict, arg, csym::Symbol)
false
end
function processLineArg(d::Dict, arg)
# given one value (:log, or :flip, or (-1,1), etc), set the appropriate arg
# TODO: use trueOrAllTrue for subplots which can pass vectors for these
function processAxisArg(d::Dict, axisletter::AbstractString, arg)
T = typeof(arg)
if T <: Symbol
# if T <: Symbol
arg = get(_typeAliases, arg, arg)
arg = get(_styleAliases, arg, arg)
arg = get(_scaleAliases, arg, arg)
# linetype
if arg in _allTypes
d[:linetype] = arg
elseif arg in _allStyles
d[:linestyle] = arg
elseif !handleColors!(d, arg, :color)
warn("Skipped line arg $arg. Unknown symbol.")
end
if arg in _allScales
d[symbol(axisletter * "scale")] = arg
elseif arg in (:flip, :invert, :inverted)
d[symbol(axisletter * "flip")] = true
# end
# xlims/ylims
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
d[symbol(axisletter * "lims")] = arg
# xticks/yticks
elseif T <: AVec
d[symbol(axisletter * "ticks")] = arg
else
warn("Skipped $(axisletter)axis arg $arg")
end
end
function processLineArg(d::Dict, arg)
# linetype
if trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
d[:linetype] = arg
# linestyle
elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
d[:linestyle] = arg
# linewidth
elseif T <: Real
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
d[:linewidth] = arg
# color
elseif !handleColors!(d, arg, :color)
warn("Skipped line arg $arg. Unhandled type $T.")
warn("Skipped line arg $arg.")
end
end
function processMarkerArg(d::Dict, arg)
T = typeof(arg)
if T <: Symbol
arg = get(_markerAliases, arg, arg)
# println(arg)
if arg in _allMarkers
# println("HERE ", arg)
d[:marker] = arg
elseif arg != :match && !handleColors!(d, arg, :markercolor)
warn("Skipped marker arg $arg. Unknown symbol.")
end
# markershape
if trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg)
d[:markershape] = arg
# markersize
elseif T <: Real
elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
d[:markersize] = arg
# markercolor
elseif !handleColors!(d, arg, :markercolor)
warn("Skipped marker arg $arg. Unhandled type $T.")
warn("Skipped marker arg $arg.")
end
end
function processFillArg(d::Dict, arg)
if !handleColors!(d, arg, :fillcolor)
d[:fillrange] = arg
end
end
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
function preprocessArgs!(d::Dict)
replaceAliases!(d, _keyAliases)
@ -406,12 +417,23 @@ function preprocessArgs!(d::Dict)
delete!(d, :line)
# handle marker args... default to ellipse if shape not set
anymarker = false
for arg in wraptuple(get(d, :marker, ()))
processMarkerArg(d, arg)
anymarker = true
end
if haskey(d, :marker) && typeof(d[:marker]) <: Tuple
d[:marker] = :ellipse
delete!(d, :marker)
if anymarker && !haskey(d, :markershape)
d[:markershape] = :ellipse
end
# handle fill
for arg in wraptuple(get(d, :fill, ()))
processFillArg(d, arg)
end
delete!(d, :fill)
return
end
# -----------------------------------------------------------------------------
@ -458,7 +480,7 @@ function warnOnUnsupported(pkg::PlottingPackage, d::Dict)
d[:axis] in supportedAxes(pkg) || warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))")
d[:linetype] == :none || d[:linetype] in supportedTypes(pkg) || warn("linetype $(d[:linetype]) is unsupported with $pkg. Choose from: $(supportedTypes(pkg))")
d[:linestyle] in supportedStyles(pkg) || warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supportedStyles(pkg))")
d[:marker] == :none || d[:marker] in supportedMarkers(pkg) || warn("marker $(d[:marker]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))")
d[:markershape] == :none || d[:markershape] in supportedMarkers(pkg) || warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))")
end
function warnOnUnsupportedScales(pkg::PlottingPackage, d::Dict)
@ -529,7 +551,7 @@ function getSeriesArgs(pkg::PlottingPackage, initargs::Dict, kw, commandIndex::I
aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
aliasesAndAutopick(d, :marker, _markerAliases, supportedMarkers(pkg), plotIndex)
aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
# update color
d[:color] = getSeriesRGBColor(d[:color], initargs, plotIndex)

View File

@ -14,7 +14,8 @@ supportedArgs(::GadflyPackage) = [
# :axis,
:background_color,
:color,
:fill,
:fillrange,
# :fillcolor,
# :foreground_color,
:group,
# :heatmap_c,
@ -25,7 +26,7 @@ supportedArgs(::GadflyPackage) = [
:linestyle,
:linetype,
:linewidth,
:marker,
:markershape,
:markercolor,
:markersize,
:n,
@ -34,7 +35,6 @@ supportedArgs(::GadflyPackage) = [
:nr,
# :pos,
:reg,
:ribbon,
:show,
:size,
:title,
@ -50,6 +50,8 @@ supportedArgs(::GadflyPackage) = [
:yticks,
:xscale,
:yscale,
:xflip,
:yflip,
:z,
]
supportedAxes(::GadflyPackage) = [:auto, :left]
@ -110,7 +112,7 @@ end
# serious hack (I think?) to draw my own shapes as annotations... will it work? who knows...
function getMarkerGeomsAndGuides(d::Dict)
marker = d[:marker]
marker = d[:markershape]
if marker == :none && d[:linetype] != :ohlc
return [],[]
end
@ -172,7 +174,7 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
d, dScatter = sticksHack(;d...)
# add the annotation
if dScatter[:marker] != :none
if dScatter[:markershape] != :none
push!(gplt.guides, createGadflyAnnotation(dScatter))
end
@ -184,11 +186,11 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
if d[:linetype] == :scatter
d[:linetype] = :none
if d[:marker] in (:none,:ellipse)
if d[:markershape] in (:none,:ellipse)
push!(gfargs, Gadfly.Geom.point)
d[:marker] = :none
# if d[:marker] == :none
# d[:marker] = :ellipse
d[:markershape] = :none
# if d[:markershape] == :none
# d[:markershape] = :ellipse
end
end
@ -216,9 +218,12 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
# 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))))
# minz, maxz = minimum(z), maximum(z)
if !isa(d[:markercolor], ColorGradient)
d[:markercolor] = colorscheme(:bluesreds)
end
push!(gplt.scales, Gadfly.Scale.ContinuousColorScale(p -> getColor(d[:markercolor], p, 1))) # minz + p * (maxz - minz))))
# nothing special...
else
colorgroup = []
@ -226,8 +231,8 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
# fills/ribbons
yminmax = []
if d[:fill] != nothing
fillmin, fillmax = map(makevec, maketuple(d[:fill]))
if d[:fillrange] != nothing
fillmin, fillmax = map(makevec, maketuple(d[:fillrange]))
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])]))
@ -277,8 +282,7 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
# Should ensure from this side that colors which are the same are merged together
push!(guide.labels, d[:label])
# push!(guide.colors, d[:marker] == :none ? first(d[:color]) : d[:markercolor])
push!(guide.colors, getColor(d[d[:marker] == :none ? :color : :markercolor], 1))
push!(guide.colors, getColor(d[d[:markershape] == :none ? :color : :markercolor], 1))
end
# end
end
@ -287,7 +291,7 @@ function addGadflySeries!(gplt, d::Dict, initargs::Dict)
x = d[d[:linetype] == :hist ? :y : :x]
if d[:axis] != :left
warn("Gadly only supports one y axis")
warn("Gadfly only supports one y axis")
end
@ -377,6 +381,29 @@ function addGadflyLimitsScale(gplt, d::Dict, isx::Bool)
return
end
function updateGadflyAxisFlips(gplt, d::Dict)
if isa(gplt.coord, Gadfly.Coord.Cartesian)
gplt.coord = Gadfly.Coord.cartesian(
gplt.coord.xvars,
gplt.coord.yvars;
xmin = gplt.coord.xmin,
xmax = gplt.coord.xmax,
ymin = gplt.coord.ymin,
ymax = gplt.coord.ymax,
xflip = get(d, :xflip, gplt.coord.xflip),
yflip = get(d, :yflip, gplt.coord.yflip),
fixed = gplt.coord.fixed,
aspect_ratio = gplt.coord.aspect_ratio,
raster = gplt.coord.raster
)
else
gplt.coord = Gadfly.Coord.Cartesian(
xflip = get(d, :xflip, false),
yflip = get(d, :yflip, false)
)
end
end
# ---------------------------------------------------------------------------
@ -413,8 +440,11 @@ function updateGadflyGuides(gplt, d::Dict)
addGadflyLimitsScale(gplt, d, true)
addGadflyLimitsScale(gplt, d, false)
haskey(d, :xticks) && addGadflyTicksGuide(gplt, d[:xticks], true)
haskey(d, :yticks) && addGadflyTicksGuide(gplt, d[:yticks], false)
updateGadflyAxisFlips(gplt, d)
end
function updatePlotItems(plt::Plot{GadflyPackage}, d::Dict)

View File

@ -8,7 +8,7 @@ function createGadflyAnnotation(d::Dict)
sz = [d[:markersize] * Gadfly.px]
x, y = d[:x], d[:y]
marker = d[:marker]
marker = d[:markershape]
if d[:linetype] == :ohlc
shape = ohlcshape(x, y, d[:markersize])

View File

@ -26,7 +26,7 @@ supportedArgs(::PyPlotPackage) = [
:linestyle,
:linetype,
:linewidth,
:marker,
:markershape,
:markercolor,
:markersize,
:n,
@ -51,6 +51,9 @@ supportedArgs(::PyPlotPackage) = [
:yticks,
:xscale,
:yscale,
# :xflip,
# :yflip,
# :z,
]
supportedAxes(::PyPlotPackage) = _allAxes
supportedTypes(::PyPlotPackage) = [:none, :line, :path, :step, :stepinverted, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
@ -203,8 +206,8 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
elseif lt == :scatter
d[:linetype] = :none
if d[:marker] == :none
d[:marker] = :ellipse
if d[:markershape] == :none
d[:markershape] = :ellipse
end
elseif lt in (:hline,:vline)
@ -242,7 +245,7 @@ function plot!(pkg::PyPlotPackage, plt::Plot; kw...)
else
extraargs[:linestyle] = getPyPlotLineStyle(lt, d[:linestyle])
extraargs[:marker] = getPyPlotMarker(d[:marker])
extraargs[:marker] = getPyPlotMarker(d[:markershape])
if lt == :scatter
extraargs[:s] = d[:markersize]

View File

@ -24,7 +24,7 @@ supportedArgs(::QwtPackage) = [
:linestyle,
:linetype,
:linewidth,
:marker,
:markershape,
:markercolor,
:markersize,
:n,
@ -49,6 +49,9 @@ supportedArgs(::QwtPackage) = [
:yticks,
:xscale,
:yscale,
# :xflip,
# :yflip,
# :z,
]
supportedTypes(::QwtPackage) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
supportedMarkers(::QwtPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon]
@ -75,14 +78,14 @@ function adjustQwtKeywords(plt::Plot{QwtPackage}, iscreating::Bool; kw...)
lt = d[:linetype]
if lt == :scatter
d[:linetype] = :none
if d[:marker] == :none
d[:marker] = :ellipse
if d[:markershape] == :none
d[:markershape] = :ellipse
end
elseif lt in (:hline, :vline)
addLineMarker(plt, d)
d[:linetype] = :none
d[:marker] = :ellipse
d[:markershape] = :ellipse
d[:markersize] = 1
if lt == :vline
d[:x], d[:y] = d[:y], d[:x]

View File

@ -17,7 +17,8 @@ supportedArgs(::[PkgName]Package) = [
:axis,
:background_color,
:color,
:fill,
:fillrange,
:fillcolor,
:foreground_color,
:group,
# :heatmap_c,
@ -28,7 +29,7 @@ supportedArgs(::[PkgName]Package) = [
:linestyle,
:linetype,
:linewidth,
:marker,
:markershape,
:markercolor,
:markersize,
:n,
@ -53,6 +54,9 @@ supportedArgs(::[PkgName]Package) = [
:yticks,
# :xscale,
# :yscale,
# :xflip,
# :yflip,
# :z,
]
supportedAxes(::[PkgName]Package) = _allAxes
supportedTypes(::[PkgName]Package) = _allTypes

View File

@ -26,7 +26,7 @@ supportedArgs(::UnicodePlotsPackage) = [
:linestyle,
:linetype,
# :linewidth,
:marker,
:markershape,
# :markercolor,
# :markersize,
# :n,
@ -51,6 +51,9 @@ supportedArgs(::UnicodePlotsPackage) = [
# :yticks,
# :xscale,
# :yscale,
# :xflip,
# :yflip,
# :z,
]
supportedAxes(::UnicodePlotsPackage) = [:auto, :left]
supportedTypes(::UnicodePlotsPackage) = [:none, :line, :path, :steppost, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline]
@ -144,7 +147,7 @@ function addUnicodeSeries!(o, d::Dict, addlegend::Bool, xlim, ylim)
stepstyle = :post
if lt == :path
func = UnicodePlots.lineplot!
elseif lt == :scatter || d[:marker] != :none
elseif lt == :scatter || d[:markershape] != :none
func = UnicodePlots.scatterplot!
elseif lt == :steppost
func = UnicodePlots.stairs!

View File

@ -30,14 +30,13 @@ const winston_marker = Dict(:none=>".",
)
# supportedArgs(::WinstonPackage) = setdiff(_allArgs, [:heatmap_c, :fill, :pos, :markercolor, :background_color, :xlims, :ylims, :xticks, :yticks])
supportedArgs(::WinstonPackage) = [
:annotation,
# :args,
# :axis,
# :background_color,
:color,
:fill,
# :fill,
# :foreground_color,
:group,
# :heatmap_c,
@ -48,7 +47,7 @@ supportedArgs(::WinstonPackage) = [
:linestyle,
:linetype,
:linewidth,
:marker,
:markershape,
:markercolor,
:markersize,
# :n,
@ -73,6 +72,9 @@ supportedArgs(::WinstonPackage) = [
# :yticks,
:xscale,
:yscale,
# :xflip,
# :yflip,
# :z,
]
supportedAxes(::WinstonPackage) = [:auto, :left]
supportedTypes(::WinstonPackage) = [:none, :line, :path, :sticks, :scatter, :hist, :bar]
@ -132,7 +134,7 @@ function plot!(::WinstonPackage, plt::Plot; kw...)
e[:color] = d[:color]
e[:linewidth] = d[:linewidth]
e[:kind] = winston_linestyle[d[:linestyle]]
e[:symbolkind] = winston_marker[d[:marker]]
e[:symbolkind] = winston_marker[d[:markershape]]
# markercolor # same choices as `color`, or :match will set the color to be the same as `color`
e[:symbolsize] = d[:markersize] / 5
# fillto # fillto value for area plots
@ -161,8 +163,8 @@ function plot!(::WinstonPackage, plt::Plot; kw...)
end
elseif d[:linetype] == :scatter
if d[:marker] == :none
d[:marker] = :ellipse
if d[:markershape] == :none
d[:markershape] = :ellipse
end
# elseif d[:linetype] == :step
@ -196,8 +198,8 @@ function plot!(::WinstonPackage, plt::Plot; kw...)
end
# marker
if d[:marker] != :none
# markershape
if d[:markershape] != :none
Winston.add(wplt, Winston.Points(d[:x], d[:y]; copy_remove(e, :kind)...))
end

View File

@ -88,8 +88,10 @@ 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)
colorscheme{T<:Colorant}(cs::AVec{T}) = ColorGradient(cs)
colorscheme(f::Function) = ColorFunction(f)
colorscheme(v::AVec) = ColorVector(v)
colorscheme(m::AMat) = Any[ColorVector(m[:,i]) for i in 1:size(m,2)]
colorscheme(c::Colorant) = ColorWrapper(c)
@ -97,8 +99,10 @@ const _gradients = Dict(
:blues => [colorant"lightblue", colorant"darkblue"],
:reds => [colorant"lightpink", colorant"darkred"],
:greens => [colorant"lightgreen", colorant"darkgreen"],
:redsblues => [colorant"darkred", RGB(0.9,0.9,0.9), colorant"darkblue"],
:bluesreds => [colorant"darkblue", RGB(0.9,0.9,0.9), colorant"darkred"],
:redsblues => [colorant"darkred", RGB(0.8,0.85,0.8), colorant"darkblue"],
:bluesreds => [colorant"darkblue", RGB(0.8,0.85,0.8), colorant"darkred"],
:heat => [colorant"lightyellow", colorant"orange", colorant"darkred"],
:grays => [RGB(.95,.95,.95),RGB(.05,.05,.05)],
)
# --------------------------------------------------------------
@ -107,6 +111,15 @@ const _gradients = Dict(
immutable ColorGradient <: ColorScheme
colors::Vector{Colorant}
values::Vector{Float64}
function ColorGradient{T<:Colorant,S<:Real}(cs::AVec{T}, vals::AVec{S} = 0:1)
length(cs) == length(vals) && return new(cs, collect(vals))
# otherwise interpolate evenly between the minval and maxval
minval, maxval = minimum(vals), maximum(vals)
vs = Float64[interpolate(minval, maxval, w) for w in linspace(0, 1, length(cs))]
new(cs, vs)
end
end
# create a gradient from a symbol (blues, reds, etc) and vector of boundary values
@ -115,14 +128,10 @@ function ColorGradient{T<:Real}(s::Symbol, vals::AVec{T} = 0:1)
# if we passed in the right number of values, create the gradient directly
cs = _gradients[s]
length(cs) == length(vals) && return ColorGradient(cs, collect(vals))
# otherwise interpolate evenly between the minval and maxval
minval, maxval = minimum(vals), maximum(vals)
vs = Float64[interpolate(minval, maxval, w) for w in linspace(0, 1, length(cs))]
ColorGradient(cs, vs)
ColorGradient(cs, vals)
end
function getColor(gradient::ColorGradient, z::Real, idx::Int)
cs = gradient.colors
vs = gradient.values
@ -137,7 +146,7 @@ function getColor(gradient::ColorGradient, z::Real, idx::Int)
# find the bounding colors and interpolate
for i in 2:n
if z <= vs[i]
return interpolate(cs[i-1], cs[i], (z - vs[i-1]) / (vs[i] - vs[i-1]))
return interpolate_rgb(cs[i-1], cs[i], (z - vs[i-1]) / (vs[i] - vs[i-1]))
end
end
@ -147,7 +156,7 @@ end
getColorVector(gradient::ColorGradient) = [gradient.colors[1]]
function interpolate(c1::Colorant, c2::Colorant, w::Real)
function interpolate_lab(c1::Colorant, c2::Colorant, w::Real)
lab1 = Lab(c1)
lab2 = Lab(c2)
l = interpolate(lab1.l, lab2.l, w)
@ -156,6 +165,16 @@ function interpolate(c1::Colorant, c2::Colorant, w::Real)
RGB(Lab(l, a, b))
end
function interpolate_rgb(c1::Colorant, c2::Colorant, w::Real)
rgb1 = RGB(c1)
rgb2 = RGB(c2)
r = interpolate(rgb1.r, rgb2.r, w)
g = interpolate(rgb1.g, rgb2.g, w)
b = interpolate(rgb1.b, rgb2.b, w)
RGB(r, g, b)
end
function interpolate(v1::Real, v2::Real, w::Real)
(1-w) * v1 + w * v2
end

View File

@ -95,7 +95,7 @@ function sticksHack(; kw...)
dLine[:x] = x
dLine[:y] = y
dLine[:linetype] = :path
dLine[:marker] = :none
dLine[:markershape] = :none
dLine[:fill] = nothing
# change the scatter args