z axis args; pyplot z axis; major pyplot cleanup; other cleanup/fixes
This commit is contained in:
parent
0a636b5899
commit
d70f462899
598
src/args.jl
598
src/args.jl
@ -159,6 +159,7 @@ const _plotDefaults = KW()
|
|||||||
_plotDefaults[:title] = ""
|
_plotDefaults[:title] = ""
|
||||||
_plotDefaults[:xlabel] = ""
|
_plotDefaults[:xlabel] = ""
|
||||||
_plotDefaults[:ylabel] = ""
|
_plotDefaults[:ylabel] = ""
|
||||||
|
_plotDefaults[:zlabel] = ""
|
||||||
_plotDefaults[:yrightlabel] = ""
|
_plotDefaults[:yrightlabel] = ""
|
||||||
_plotDefaults[:legend] = :best
|
_plotDefaults[:legend] = :best
|
||||||
_plotDefaults[:colorbar] = :legend
|
_plotDefaults[:colorbar] = :legend
|
||||||
@ -169,10 +170,13 @@ _plotDefaults[:ylims] = :auto
|
|||||||
_plotDefaults[:zlims] = :auto
|
_plotDefaults[:zlims] = :auto
|
||||||
_plotDefaults[:xticks] = :auto
|
_plotDefaults[:xticks] = :auto
|
||||||
_plotDefaults[:yticks] = :auto
|
_plotDefaults[:yticks] = :auto
|
||||||
|
_plotDefaults[:zticks] = :auto
|
||||||
_plotDefaults[:xscale] = :identity
|
_plotDefaults[:xscale] = :identity
|
||||||
_plotDefaults[:yscale] = :identity
|
_plotDefaults[:yscale] = :identity
|
||||||
|
_plotDefaults[:zscale] = :identity
|
||||||
_plotDefaults[:xflip] = false
|
_plotDefaults[:xflip] = false
|
||||||
_plotDefaults[:yflip] = false
|
_plotDefaults[:yflip] = false
|
||||||
|
_plotDefaults[:zflip] = false
|
||||||
_plotDefaults[:size] = (600,400)
|
_plotDefaults[:size] = (600,400)
|
||||||
_plotDefaults[:pos] = (0,0)
|
_plotDefaults[:pos] = (0,0)
|
||||||
_plotDefaults[:windowtitle] = "Plots.jl"
|
_plotDefaults[:windowtitle] = "Plots.jl"
|
||||||
@ -214,16 +218,15 @@ autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:non
|
|||||||
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
|
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
|
||||||
|
|
||||||
function aliasesAndAutopick(d::KW, sym::Symbol, aliases::KW, options::AVec, plotIndex::Int)
|
function aliasesAndAutopick(d::KW, sym::Symbol, aliases::KW, options::AVec, plotIndex::Int)
|
||||||
if d[sym] == :auto
|
if d[sym] == :auto
|
||||||
d[sym] = autopick_ignore_none_auto(options, plotIndex)
|
d[sym] = autopick_ignore_none_auto(options, plotIndex)
|
||||||
elseif haskey(aliases, d[sym])
|
elseif haskey(aliases, d[sym])
|
||||||
d[sym] = aliases[d[sym]]
|
d[sym] = aliases[d[sym]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function aliases(aliasMap::KW, val)
|
function aliases(aliasMap::KW, val)
|
||||||
# sort(vcat(val, collect(keys(filter((k,v)-> v==val, aliasMap)))))
|
sortedkeys(filter((k,v)-> v==val, aliasMap))
|
||||||
sortedkeys(filter((k,v)-> v==val, aliasMap))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -278,6 +281,7 @@ end
|
|||||||
:annotations => :annotation,
|
:annotations => :annotation,
|
||||||
:xlab => :xlabel,
|
:xlab => :xlabel,
|
||||||
:ylab => :ylabel,
|
:ylab => :ylabel,
|
||||||
|
:zlab => :zlabel,
|
||||||
:yrlab => :yrightlabel,
|
:yrlab => :yrightlabel,
|
||||||
:ylabr => :yrightlabel,
|
:ylabr => :yrightlabel,
|
||||||
:y2lab => :yrightlabel,
|
:y2lab => :yrightlabel,
|
||||||
@ -344,7 +348,7 @@ end
|
|||||||
|
|
||||||
# add all pluralized forms to the _keyAliases dict
|
# add all pluralized forms to the _keyAliases dict
|
||||||
for arg in keys(_seriesDefaults)
|
for arg in keys(_seriesDefaults)
|
||||||
_keyAliases[makeplural(arg)] = arg
|
_keyAliases[makeplural(arg)] = arg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -360,189 +364,175 @@ end
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
function default(k::Symbol)
|
function default(k::Symbol)
|
||||||
k = get(_keyAliases, k, k)
|
k = get(_keyAliases, k, k)
|
||||||
if haskey(_seriesDefaults, k)
|
if haskey(_seriesDefaults, k)
|
||||||
return _seriesDefaults[k]
|
return _seriesDefaults[k]
|
||||||
elseif haskey(_plotDefaults, k)
|
elseif haskey(_plotDefaults, k)
|
||||||
return _plotDefaults[k]
|
return _plotDefaults[k]
|
||||||
else
|
else
|
||||||
error("Unknown key: ", k)
|
error("Unknown key: ", k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function default(k::Symbol, v)
|
function default(k::Symbol, v)
|
||||||
k = get(_keyAliases, k, k)
|
k = get(_keyAliases, k, k)
|
||||||
if haskey(_seriesDefaults, k)
|
if haskey(_seriesDefaults, k)
|
||||||
_seriesDefaults[k] = v
|
_seriesDefaults[k] = v
|
||||||
elseif haskey(_plotDefaults, k)
|
elseif haskey(_plotDefaults, k)
|
||||||
_plotDefaults[k] = v
|
_plotDefaults[k] = v
|
||||||
else
|
else
|
||||||
error("Unknown key: ", k)
|
error("Unknown key: ", k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function default(; kw...)
|
function default(; kw...)
|
||||||
for (k,v) in kw
|
for (k,v) in kw
|
||||||
default(k, v)
|
default(k, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function handleColors!(d::KW, arg, csym::Symbol)
|
function handleColors!(d::KW, arg, csym::Symbol)
|
||||||
try
|
try
|
||||||
if arg == :auto
|
if arg == :auto
|
||||||
d[csym] = :auto
|
d[csym] = :auto
|
||||||
else
|
else
|
||||||
c = colorscheme(arg)
|
c = colorscheme(arg)
|
||||||
d[csym] = c
|
d[csym] = c
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
return true
|
false
|
||||||
end
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# given one value (:log, or :flip, or (-1,1), etc), set the appropriate 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
|
# TODO: use trueOrAllTrue for subplots which can pass vectors for these
|
||||||
function processAxisArg(d::KW, axisletter::@compat(AbstractString), arg)
|
function processAxisArg(d::KW, letter::AbstractString, arg)
|
||||||
T = typeof(arg)
|
T = typeof(arg)
|
||||||
# if T <: Symbol
|
arg = get(_scaleAliases, arg, arg)
|
||||||
|
scale, flip, label, lim, tick = axis_symbols(letter, "scale", "flip", "label", "lims", "ticks")
|
||||||
|
|
||||||
arg = get(_scaleAliases, arg, arg)
|
if typeof(arg) <: Font
|
||||||
|
d[:tickfont] = arg
|
||||||
|
|
||||||
if arg in _allScales
|
elseif arg in _allScales
|
||||||
d[symbol(axisletter * "scale")] = arg
|
d[scale] = arg
|
||||||
|
|
||||||
elseif arg in (:flip, :invert, :inverted)
|
elseif arg in (:flip, :invert, :inverted)
|
||||||
d[symbol(axisletter * "flip")] = true
|
d[flip] = true
|
||||||
|
|
||||||
elseif T <: @compat(AbstractString)
|
elseif T <: @compat(AbstractString)
|
||||||
d[symbol(axisletter * "label")] = arg
|
d[label] = arg
|
||||||
|
|
||||||
# xlims/ylims
|
# xlims/ylims
|
||||||
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
||||||
d[symbol(axisletter * "lims")] = arg
|
d[typeof(arg[1]) <: Number ? lim : tick] = arg
|
||||||
|
|
||||||
# xticks/yticks
|
# xticks/yticks
|
||||||
elseif T <: AVec
|
elseif T <: AVec
|
||||||
d[symbol(axisletter * "ticks")] = arg
|
d[tick] = arg
|
||||||
|
|
||||||
elseif arg == nothing
|
elseif arg == nothing
|
||||||
d[symbol(axisletter * "ticks")] = []
|
d[tick] = []
|
||||||
|
|
||||||
else
|
else
|
||||||
warn("Skipped $(axisletter)axis arg $arg")
|
warn("Skipped $(letter)axis arg $arg")
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function processLineArg(d::KW, arg)
|
function processLineArg(d::KW, arg)
|
||||||
|
# linetype
|
||||||
|
if allLineTypes(arg)
|
||||||
|
d[:linetype] = arg
|
||||||
|
|
||||||
# linetype
|
# linestyle
|
||||||
# if trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
|
elseif allStyles(arg)
|
||||||
if allLineTypes(arg)
|
d[:linestyle] = arg
|
||||||
d[:linetype] = arg
|
|
||||||
|
|
||||||
# linestyle
|
elseif typeof(arg) <: Stroke
|
||||||
# elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
arg.width == nothing || (d[:linewidth] = arg.width)
|
||||||
elseif allStyles(arg)
|
arg.color == nothing || (d[:linecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||||
d[:linestyle] = arg
|
arg.alpha == nothing || (d[:linealpha] = arg.alpha)
|
||||||
|
arg.style == nothing || (d[:linestyle] = arg.style)
|
||||||
|
|
||||||
elseif typeof(arg) <: Stroke
|
elseif typeof(arg) <: Brush
|
||||||
arg.width == nothing || (d[:linewidth] = arg.width)
|
arg.size == nothing || (d[:fillrange] = arg.size)
|
||||||
arg.color == nothing || (d[:linecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||||
arg.alpha == nothing || (d[:linealpha] = arg.alpha)
|
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
||||||
arg.style == nothing || (d[:linestyle] = arg.style)
|
|
||||||
|
|
||||||
elseif typeof(arg) <: Brush
|
# linealpha
|
||||||
arg.size == nothing || (d[:fillrange] = arg.size)
|
elseif allAlphas(arg)
|
||||||
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
d[:linealpha] = arg
|
||||||
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
|
||||||
|
|
||||||
# linealpha
|
# linewidth
|
||||||
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
|
elseif allReals(arg)
|
||||||
elseif allAlphas(arg)
|
d[:linewidth] = arg
|
||||||
d[:linealpha] = arg
|
|
||||||
|
|
||||||
# linewidth
|
# color
|
||||||
# elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
elseif !handleColors!(d, arg, :linecolor)
|
||||||
elseif allReals(arg)
|
warn("Skipped line arg $arg.")
|
||||||
d[:linewidth] = arg
|
|
||||||
|
|
||||||
# color
|
end
|
||||||
elseif !handleColors!(d, arg, :linecolor)
|
|
||||||
warn("Skipped line arg $arg.")
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function processMarkerArg(d::KW, arg)
|
function processMarkerArg(d::KW, arg)
|
||||||
|
# markershape
|
||||||
|
if allShapes(arg)
|
||||||
|
d[:markershape] = arg
|
||||||
|
|
||||||
# markershape
|
# stroke style
|
||||||
# if trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg)
|
elseif allStyles(arg)
|
||||||
# d[:markershape] = arg
|
d[:markerstrokestyle] = arg
|
||||||
|
|
||||||
# elseif trueOrAllTrue(a -> isa(a, Shape), arg)
|
elseif typeof(arg) <: Stroke
|
||||||
if allShapes(arg)
|
arg.width == nothing || (d[:markerstrokewidth] = arg.width)
|
||||||
d[:markershape] = arg
|
arg.color == nothing || (d[:markerstrokecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||||
|
arg.alpha == nothing || (d[:markerstrokealpha] = arg.alpha)
|
||||||
|
arg.style == nothing || (d[:markerstrokestyle] = arg.style)
|
||||||
|
|
||||||
# stroke style
|
elseif typeof(arg) <: Brush
|
||||||
# elseif trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
arg.size == nothing || (d[:markersize] = arg.size)
|
||||||
elseif allStyles(arg)
|
arg.color == nothing || (d[:markercolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||||
d[:markerstrokestyle] = arg
|
arg.alpha == nothing || (d[:markeralpha] = arg.alpha)
|
||||||
|
|
||||||
elseif typeof(arg) <: Stroke
|
# linealpha
|
||||||
arg.width == nothing || (d[:markerstrokewidth] = arg.width)
|
elseif allAlphas(arg)
|
||||||
arg.color == nothing || (d[:markerstrokecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
d[:markeralpha] = arg
|
||||||
arg.alpha == nothing || (d[:markerstrokealpha] = arg.alpha)
|
|
||||||
arg.style == nothing || (d[:markerstrokestyle] = arg.style)
|
|
||||||
|
|
||||||
elseif typeof(arg) <: Brush
|
# markersize
|
||||||
arg.size == nothing || (d[:markersize] = arg.size)
|
elseif allReals(arg)
|
||||||
arg.color == nothing || (d[:markercolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
d[:markersize] = arg
|
||||||
arg.alpha == nothing || (d[:markeralpha] = arg.alpha)
|
|
||||||
|
|
||||||
# linealpha
|
# markercolor
|
||||||
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
|
elseif !handleColors!(d, arg, :markercolor)
|
||||||
elseif allAlphas(arg)
|
warn("Skipped marker arg $arg.")
|
||||||
d[:markeralpha] = arg
|
|
||||||
|
|
||||||
# markersize
|
end
|
||||||
# elseif trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
|
||||||
elseif allReals(arg)
|
|
||||||
d[:markersize] = arg
|
|
||||||
|
|
||||||
# markercolor
|
|
||||||
elseif !handleColors!(d, arg, :markercolor)
|
|
||||||
warn("Skipped marker arg $arg.")
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function processFillArg(d::KW, arg)
|
function processFillArg(d::KW, arg)
|
||||||
|
if typeof(arg) <: Brush
|
||||||
|
arg.size == nothing || (d[:fillrange] = arg.size)
|
||||||
|
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||||||
|
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
||||||
|
|
||||||
if typeof(arg) <: Brush
|
# fillrange function
|
||||||
arg.size == nothing || (d[:fillrange] = arg.size)
|
elseif allFunctions(arg)
|
||||||
arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
d[:fillrange] = arg
|
||||||
arg.alpha == nothing || (d[:fillalpha] = arg.alpha)
|
|
||||||
|
|
||||||
# fillrange function
|
# fillalpha
|
||||||
# elseif trueOrAllTrue(a -> isa(a, Function), arg)
|
elseif allAlphas(arg)
|
||||||
elseif allFunctions(arg)
|
d[:fillalpha] = arg
|
||||||
d[:fillrange] = arg
|
|
||||||
|
|
||||||
# fillalpha
|
elseif !handleColors!(d, arg, :fillcolor)
|
||||||
# elseif trueOrAllTrue(a -> typeof(a) <: Real && a > 0 && a < 1, arg)
|
|
||||||
elseif allAlphas(arg)
|
|
||||||
d[:fillalpha] = arg
|
|
||||||
|
|
||||||
elseif !handleColors!(d, arg, :fillcolor)
|
d[:fillrange] = arg
|
||||||
|
end
|
||||||
d[:fillrange] = arg
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
|
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
|
||||||
@ -552,119 +542,116 @@ _replace_markershape(shape) = shape
|
|||||||
|
|
||||||
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
|
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
|
||||||
function preprocessArgs!(d::KW)
|
function preprocessArgs!(d::KW)
|
||||||
replaceAliases!(d, _keyAliases)
|
replaceAliases!(d, _keyAliases)
|
||||||
|
|
||||||
# handle axis args
|
# handle axis args
|
||||||
for axisletter in ("x", "y")
|
for letter in ("x", "y", "z")
|
||||||
asym = symbol(axisletter * "axis")
|
asym = symbol(letter * "axis")
|
||||||
for arg in wraptuple(get(d, asym, ()))
|
for arg in wraptuple(get(d, asym, ()))
|
||||||
processAxisArg(d, axisletter, arg)
|
processAxisArg(d, letter, arg)
|
||||||
|
end
|
||||||
|
delete!(d, asym)
|
||||||
|
|
||||||
|
# turn :labels into :ticks_and_labels
|
||||||
|
tsym = symbol(letter * "ticks")
|
||||||
|
if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
||||||
|
d[tsym] = (1:length(d[tsym]), d[tsym])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
delete!(d, asym)
|
|
||||||
|
|
||||||
# turn :labels into :ticks_and_labels
|
# handle line args
|
||||||
tsym = symbol(axisletter * "ticks")
|
for arg in wraptuple(get(d, :line, ()))
|
||||||
if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
processLineArg(d, arg)
|
||||||
d[tsym] = (1:length(d[tsym]), d[tsym])
|
|
||||||
end
|
end
|
||||||
end
|
delete!(d, :line)
|
||||||
|
|
||||||
# handle line args
|
# handle marker args... default to ellipse if shape not set
|
||||||
for arg in wraptuple(get(d, :line, ()))
|
anymarker = false
|
||||||
processLineArg(d, arg)
|
for arg in wraptuple(get(d, :marker, ()))
|
||||||
end
|
processMarkerArg(d, arg)
|
||||||
delete!(d, :line)
|
anymarker = true
|
||||||
|
end
|
||||||
|
delete!(d, :marker)
|
||||||
|
if haskey(d, :markershape)
|
||||||
|
d[:markershape] = _replace_markershape(d[:markershape])
|
||||||
|
elseif anymarker
|
||||||
|
d[:markershape] = :ellipse
|
||||||
|
end
|
||||||
|
|
||||||
# handle marker args... default to ellipse if shape not set
|
# handle fill
|
||||||
anymarker = false
|
for arg in wraptuple(get(d, :fill, ()))
|
||||||
for arg in wraptuple(get(d, :marker, ()))
|
processFillArg(d, arg)
|
||||||
processMarkerArg(d, arg)
|
end
|
||||||
anymarker = true
|
delete!(d, :fill)
|
||||||
end
|
|
||||||
delete!(d, :marker)
|
|
||||||
# if anymarker && !haskey(d, :markershape)
|
|
||||||
# d[:markershape] = :ellipse
|
|
||||||
# end
|
|
||||||
if haskey(d, :markershape)
|
|
||||||
d[:markershape] = _replace_markershape(d[:markershape])
|
|
||||||
elseif anymarker
|
|
||||||
d[:markershape] = :ellipse
|
|
||||||
end
|
|
||||||
|
|
||||||
# handle fill
|
|
||||||
for arg in wraptuple(get(d, :fill, ()))
|
|
||||||
processFillArg(d, arg)
|
|
||||||
end
|
|
||||||
delete!(d, :fill)
|
|
||||||
|
|
||||||
# convert into strokes and brushes
|
# convert into strokes and brushes
|
||||||
|
|
||||||
# legends
|
# legends
|
||||||
if haskey(d, :legend)
|
if haskey(d, :legend)
|
||||||
d[:legend] = convertLegendValue(d[:legend])
|
d[:legend] = convertLegendValue(d[:legend])
|
||||||
end
|
end
|
||||||
if haskey(d, :colorbar)
|
if haskey(d, :colorbar)
|
||||||
d[:colorbar] = convertLegendValue(d[:colorbar])
|
d[:colorbar] = convertLegendValue(d[:colorbar])
|
||||||
end
|
|
||||||
|
|
||||||
# handle subplot links
|
|
||||||
if haskey(d, :link)
|
|
||||||
l = d[:link]
|
|
||||||
if isa(l, Bool)
|
|
||||||
d[:linkx] = l
|
|
||||||
d[:linky] = l
|
|
||||||
elseif isa(l, Function)
|
|
||||||
d[:linkx] = true
|
|
||||||
d[:linky] = true
|
|
||||||
d[:linkfunc] = l
|
|
||||||
else
|
|
||||||
warn("Unhandled/invalid link $l. Should be a Bool or a function mapping (row,column) -> (linkx, linky), where linkx/y can be Bool or Void (nothing)")
|
|
||||||
end
|
end
|
||||||
delete!(d, :link)
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
# handle subplot links
|
||||||
|
if haskey(d, :link)
|
||||||
|
l = d[:link]
|
||||||
|
if isa(l, Bool)
|
||||||
|
d[:linkx] = l
|
||||||
|
d[:linky] = l
|
||||||
|
elseif isa(l, Function)
|
||||||
|
d[:linkx] = true
|
||||||
|
d[:linky] = true
|
||||||
|
d[:linkfunc] = l
|
||||||
|
else
|
||||||
|
warn("Unhandled/invalid link $l. Should be a Bool or a function mapping (row,column) -> (linkx, linky), where linkx/y can be Bool or Void (nothing)")
|
||||||
|
end
|
||||||
|
delete!(d, :link)
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
"A special type that will break up incoming data into groups, and allow for easier creation of grouped plots"
|
"A special type that will break up incoming data into groups, and allow for easier creation of grouped plots"
|
||||||
type GroupBy
|
type GroupBy
|
||||||
groupLabels::Vector{UTF8String} # length == numGroups
|
groupLabels::Vector{UTF8String} # length == numGroups
|
||||||
groupIds::Vector{Vector{Int}} # list of indices for each group
|
groupIds::Vector{Vector{Int}} # list of indices for each group
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# this is when given a vector-type of values to group by
|
# this is when given a vector-type of values to group by
|
||||||
function extractGroupArgs(v::AVec, args...)
|
function extractGroupArgs(v::AVec, args...)
|
||||||
groupLabels = sort(collect(unique(v)))
|
groupLabels = sort(collect(unique(v)))
|
||||||
n = length(groupLabels)
|
n = length(groupLabels)
|
||||||
if n > 20
|
if n > 20
|
||||||
error("Too many group labels. n=$n Is that intended?")
|
error("Too many group labels. n=$n Is that intended?")
|
||||||
end
|
end
|
||||||
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
||||||
GroupBy(map(string, groupLabels), groupIds)
|
GroupBy(map(string, groupLabels), groupIds)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# expecting a mapping of "group label" to "group indices"
|
# expecting a mapping of "group label" to "group indices"
|
||||||
function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...)
|
function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...)
|
||||||
groupLabels = sortedkeys(idxmap)
|
groupLabels = sortedkeys(idxmap)
|
||||||
groupIds = VecI[collect(idxmap[k]) for k in groupLabels]
|
groupIds = VecI[collect(idxmap[k]) for k in groupLabels]
|
||||||
GroupBy(groupLabels, groupIds)
|
GroupBy(groupLabels, groupIds)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
function warnOnUnsupportedArgs(pkg::AbstractBackend, d::KW)
|
function warnOnUnsupportedArgs(pkg::AbstractBackend, d::KW)
|
||||||
for k in sortedkeys(d)
|
for k in sortedkeys(d)
|
||||||
if (!(k in supportedArgs(pkg))
|
if (!(k in supportedArgs(pkg))
|
||||||
&& k != :subplot
|
&& k != :subplot
|
||||||
&& d[k] != default(k))
|
&& d[k] != default(k))
|
||||||
warn("Keyword argument $k not supported with $pkg. Choose from: $(supportedArgs(pkg))")
|
warn("Keyword argument $k not supported with $pkg. Choose from: $(supportedArgs(pkg))")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
_markershape_supported(pkg::AbstractBackend, shape::Symbol) = shape in supportedMarkers(pkg)
|
_markershape_supported(pkg::AbstractBackend, shape::Symbol) = shape in supportedMarkers(pkg)
|
||||||
@ -672,18 +659,16 @@ _markershape_supported(pkg::AbstractBackend, shape::Shape) = Shape in supportedM
|
|||||||
_markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
|
_markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
|
||||||
|
|
||||||
function warnOnUnsupported(pkg::AbstractBackend, d::KW)
|
function warnOnUnsupported(pkg::AbstractBackend, d::KW)
|
||||||
(d[:axis] in supportedAxes(pkg)
|
(d[:axis] in supportedAxes(pkg)
|
||||||
|| warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))"))
|
|| warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))"))
|
||||||
(d[:linetype] == :none
|
(d[:linetype] == :none
|
||||||
|| d[:linetype] in supportedTypes(pkg)
|
|| d[:linetype] in supportedTypes(pkg)
|
||||||
|| warn("linetype $(d[:linetype]) is unsupported with $pkg. Choose from: $(supportedTypes(pkg))"))
|
|| warn("linetype $(d[:linetype]) is unsupported with $pkg. Choose from: $(supportedTypes(pkg))"))
|
||||||
(d[:linestyle] in supportedStyles(pkg)
|
(d[:linestyle] in supportedStyles(pkg)
|
||||||
|| warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supportedStyles(pkg))"))
|
|| warn("linestyle $(d[:linestyle]) is unsupported with $pkg. Choose from: $(supportedStyles(pkg))"))
|
||||||
(d[:markershape] == :none
|
(d[:markershape] == :none
|
||||||
|| _markershape_supported(pkg, d[:markershape])
|
|| _markershape_supported(pkg, d[:markershape])
|
||||||
# || d[:markershape] in supportedMarkers(pkg)
|
|| warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))"))
|
||||||
# || (Shape in supportedMarkers(pkg) && typeof(d[:markershape]) <: Shape)
|
|
||||||
|| warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function warnOnUnsupportedScales(pkg::AbstractBackend, d::KW)
|
function warnOnUnsupportedScales(pkg::AbstractBackend, d::KW)
|
||||||
@ -702,8 +687,8 @@ end
|
|||||||
# anything else is returned as-is
|
# anything else is returned as-is
|
||||||
# getArgValue(v::Tuple, idx::Int) = v[mod1(idx, length(v))]
|
# getArgValue(v::Tuple, idx::Int) = v[mod1(idx, length(v))]
|
||||||
function getArgValue(v::AMat, idx::Int)
|
function getArgValue(v::AMat, idx::Int)
|
||||||
c = mod1(idx, size(v,2))
|
c = mod1(idx, size(v,2))
|
||||||
size(v,1) == 1 ? v[1,c] : v[:,c]
|
size(v,1) == 1 ? v[1,c] : v[:,c]
|
||||||
end
|
end
|
||||||
getArgValue(v, idx) = v
|
getArgValue(v, idx) = v
|
||||||
|
|
||||||
@ -711,23 +696,23 @@ getArgValue(v, idx) = v
|
|||||||
# given an argument key (k), we want to extract the argument value for this index.
|
# given an argument key (k), we want to extract the argument value for this index.
|
||||||
# if nothing is set (or container is empty), return the default.
|
# if nothing is set (or container is empty), return the default.
|
||||||
function setDictValue(d_in::KW, d_out::KW, k::Symbol, idx::Int, defaults::KW)
|
function setDictValue(d_in::KW, d_out::KW, k::Symbol, idx::Int, defaults::KW)
|
||||||
if haskey(d_in, k) && !(typeof(d_in[k]) <: @compat(Union{AbstractArray, Tuple}) && isempty(d_in[k]))
|
if haskey(d_in, k) && !(typeof(d_in[k]) <: @compat(Union{AbstractArray, Tuple}) && isempty(d_in[k]))
|
||||||
d_out[k] = getArgValue(d_in[k], idx)
|
d_out[k] = getArgValue(d_in[k], idx)
|
||||||
else
|
else
|
||||||
d_out[k] = defaults[k]
|
d_out[k] = defaults[k]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function convertLegendValue(val::Symbol)
|
function convertLegendValue(val::Symbol)
|
||||||
if val in (:both, :all, :yes)
|
if val in (:both, :all, :yes)
|
||||||
:best
|
:best
|
||||||
elseif val in (:no, :none)
|
elseif val in (:no, :none)
|
||||||
:none
|
:none
|
||||||
elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend)
|
elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend)
|
||||||
val
|
val
|
||||||
else
|
else
|
||||||
error("Invalid symbol for legend: $val")
|
error("Invalid symbol for legend: $val")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
convertLegendValue(val::Bool) = val ? :best : :none
|
convertLegendValue(val::Bool) = val ? :best : :none
|
||||||
|
|
||||||
@ -735,94 +720,93 @@ convertLegendValue(val::Bool) = val ? :best : :none
|
|||||||
|
|
||||||
# build the argument dictionary for the plot
|
# build the argument dictionary for the plot
|
||||||
function getPlotArgs(pkg::AbstractBackend, kw, idx::Int; set_defaults = true)
|
function getPlotArgs(pkg::AbstractBackend, kw, idx::Int; set_defaults = true)
|
||||||
kwdict = KW(kw)
|
kwdict = KW(kw)
|
||||||
d = KW()
|
d = KW()
|
||||||
|
|
||||||
# add defaults?
|
# add defaults?
|
||||||
if set_defaults
|
if set_defaults
|
||||||
for k in keys(_plotDefaults)
|
for k in keys(_plotDefaults)
|
||||||
setDictValue(kwdict, d, k, idx, _plotDefaults)
|
setDictValue(kwdict, d, k, idx, _plotDefaults)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
for k in (:xscale, :yscale)
|
for k in (:xscale, :yscale)
|
||||||
if haskey(_scaleAliases, d[k])
|
if haskey(_scaleAliases, d[k])
|
||||||
d[k] = _scaleAliases[d[k]]
|
d[k] = _scaleAliases[d[k]]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# handle legend/colorbar
|
# handle legend/colorbar
|
||||||
d[:legend] = convertLegendValue(d[:legend])
|
d[:legend] = convertLegendValue(d[:legend])
|
||||||
d[:colorbar] = convertLegendValue(d[:colorbar])
|
d[:colorbar] = convertLegendValue(d[:colorbar])
|
||||||
if d[:colorbar] == :legend
|
if d[:colorbar] == :legend
|
||||||
d[:colorbar] = d[:legend]
|
d[:colorbar] = d[:legend]
|
||||||
end
|
end
|
||||||
|
|
||||||
# convert color
|
# convert color
|
||||||
handlePlotColors(pkg, d)
|
handlePlotColors(pkg, d)
|
||||||
|
|
||||||
# no need for these
|
# no need for these
|
||||||
delete!(d, :x)
|
delete!(d, :x)
|
||||||
delete!(d, :y)
|
delete!(d, :y)
|
||||||
|
|
||||||
d
|
d
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# build the argument dictionary for a series
|
# build the argument dictionary for a series
|
||||||
function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt
|
function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt
|
||||||
kwdict = KW(kw)
|
kwdict = KW(kw)
|
||||||
d = KW()
|
d = KW()
|
||||||
|
|
||||||
# add defaults?
|
# add defaults?
|
||||||
for k in keys(_seriesDefaults)
|
for k in keys(_seriesDefaults)
|
||||||
setDictValue(kwdict, d, k, commandIndex, _seriesDefaults)
|
setDictValue(kwdict, d, k, commandIndex, _seriesDefaults)
|
||||||
end
|
|
||||||
|
|
||||||
# groupby args?
|
|
||||||
for k in (:idxfilter, :numUncounted, :dataframe)
|
|
||||||
if haskey(kwdict, k)
|
|
||||||
d[k] = kwdict[k]
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if haskey(_typeAliases, d[:linetype])
|
# groupby args?
|
||||||
d[:linetype] = _typeAliases[d[:linetype]]
|
for k in (:idxfilter, :numUncounted, :dataframe)
|
||||||
end
|
if haskey(kwdict, k)
|
||||||
|
d[k] = kwdict[k]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
|
if haskey(_typeAliases, d[:linetype])
|
||||||
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
|
d[:linetype] = _typeAliases[d[:linetype]]
|
||||||
aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
end
|
||||||
|
|
||||||
# update color
|
aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
|
||||||
d[:linecolor] = getSeriesRGBColor(d[:linecolor], plotargs, plotIndex)
|
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
|
||||||
|
aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
||||||
|
|
||||||
# update markercolor
|
# update color
|
||||||
c = d[:markercolor]
|
d[:linecolor] = getSeriesRGBColor(d[:linecolor], plotargs, plotIndex)
|
||||||
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
|
||||||
d[:markercolor] = c
|
|
||||||
|
|
||||||
# update markerstrokecolor
|
# update markercolor
|
||||||
c = d[:markerstrokecolor]
|
c = d[:markercolor]
|
||||||
c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex))
|
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||||
d[:markerstrokecolor] = c
|
d[:markercolor] = c
|
||||||
|
|
||||||
# update fillcolor
|
# update markerstrokecolor
|
||||||
c = d[:fillcolor]
|
c = d[:markerstrokecolor]
|
||||||
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||||
d[:fillcolor] = c
|
d[:markerstrokecolor] = c
|
||||||
|
|
||||||
# set label
|
# update fillcolor
|
||||||
label = d[:label]
|
c = d[:fillcolor]
|
||||||
label = (label == "AUTO" ? "y$globalIndex" : label)
|
c = (c == :match ? d[:linecolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||||||
if d[:axis] == :right && !(length(label) >= 4 && label[end-3:end] != " (R)")
|
d[:fillcolor] = c
|
||||||
label = string(label, " (R)")
|
|
||||||
end
|
|
||||||
d[:label] = label
|
|
||||||
|
|
||||||
warnOnUnsupported(pkg, d)
|
# set label
|
||||||
|
label = d[:label]
|
||||||
|
label = (label == "AUTO" ? "y$globalIndex" : label)
|
||||||
|
if d[:axis] == :right && !(length(label) >= 4 && label[end-3:end] != " (R)")
|
||||||
|
label = string(label, " (R)")
|
||||||
|
end
|
||||||
|
d[:label] = label
|
||||||
|
|
||||||
|
warnOnUnsupported(pkg, d)
|
||||||
|
|
||||||
d
|
d
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,30 +2,30 @@
|
|||||||
# https://github.com/stevengj/PyPlot.jl
|
# https://github.com/stevengj/PyPlot.jl
|
||||||
|
|
||||||
function _initialize_backend(::PyPlotBackend)
|
function _initialize_backend(::PyPlotBackend)
|
||||||
@eval begin
|
@eval begin
|
||||||
import PyPlot
|
import PyPlot
|
||||||
export PyPlot
|
export PyPlot
|
||||||
const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors"))
|
const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors"))
|
||||||
const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path"))
|
const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path"))
|
||||||
const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d"))
|
const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d"))
|
||||||
const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches"))
|
const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches"))
|
||||||
# const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar"))
|
# const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar"))
|
||||||
end
|
end
|
||||||
|
|
||||||
if !isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
|
if !isa(Base.Multimedia.displays[end], Base.REPL.REPLDisplay)
|
||||||
PyPlot.ioff() # stops wierd behavior of displaying incomplete graphs in IJulia
|
PyPlot.ioff() # stops wierd behavior of displaying incomplete graphs in IJulia
|
||||||
|
|
||||||
# # TODO: how the hell can I use PyQt4??
|
# # TODO: how the hell can I use PyQt4??
|
||||||
# "pyqt4"=>:qt_pyqt4
|
# "pyqt4"=>:qt_pyqt4
|
||||||
# PyPlot.backend[1] = "pyqt4"
|
# PyPlot.backend[1] = "pyqt4"
|
||||||
# PyPlot.gui[1] = :qt_pyqt4
|
# PyPlot.gui[1] = :qt_pyqt4
|
||||||
# PyPlot.switch_backend("Qt4Agg")
|
# PyPlot.switch_backend("Qt4Agg")
|
||||||
|
|
||||||
# only turn on the gui if we want it
|
# only turn on the gui if we want it
|
||||||
if PyPlot.gui != :none
|
if PyPlot.gui != :none
|
||||||
PyPlot.pygui(true)
|
PyPlot.pygui(true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# -------------------------------
|
# -------------------------------
|
||||||
@ -35,15 +35,10 @@ getPyPlotColor(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (
|
|||||||
getPyPlotColor(cvec::ColorVector, α=nothing) = map(getPyPlotColor, convertColor(cvec, α).v)
|
getPyPlotColor(cvec::ColorVector, α=nothing) = map(getPyPlotColor, convertColor(cvec, α).v)
|
||||||
getPyPlotColor(scheme::ColorScheme, α=nothing) = getPyPlotColor(convertColor(getColor(scheme), α))
|
getPyPlotColor(scheme::ColorScheme, α=nothing) = getPyPlotColor(convertColor(getColor(scheme), α))
|
||||||
getPyPlotColor(c, α=nothing) = getPyPlotColor(convertColor(c, α))
|
getPyPlotColor(c, α=nothing) = getPyPlotColor(convertColor(c, α))
|
||||||
# getPyPlotColor(c, alpha) = getPyPlotColor(colorscheme(c, alpha))
|
|
||||||
|
|
||||||
function getPyPlotColorMap(c::ColorGradient, α=nothing)
|
function getPyPlotColorMap(c::ColorGradient, α=nothing)
|
||||||
# c = ColorGradient(c.colors, c.values, alpha=α)
|
pyvals = [(v, getPyPlotColor(getColorZ(c, v), α)) for v in c.values]
|
||||||
# pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", map(getPyPlotColor, getColorVector(c)))
|
pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", pyvals)
|
||||||
# pyvals = [(c.values[i], getPyPlotColor(c.colors[i], α)) for i in 1:length(c.colors)]
|
|
||||||
pyvals = [(v, getPyPlotColor(getColorZ(c, v), α)) for v in c.values]
|
|
||||||
# @show c α pyvals
|
|
||||||
pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", pyvals)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# anything else just gets a bluesred gradient
|
# anything else just gets a bluesred gradient
|
||||||
@ -51,25 +46,24 @@ getPyPlotColorMap(c, α=nothing) = getPyPlotColorMap(ColorGradient(:bluesreds),
|
|||||||
|
|
||||||
# get the style (solid, dashed, etc)
|
# get the style (solid, dashed, etc)
|
||||||
function getPyPlotLineStyle(linetype::Symbol, linestyle::Symbol)
|
function getPyPlotLineStyle(linetype::Symbol, linestyle::Symbol)
|
||||||
linetype == :none && return " "
|
linetype == :none && return " "
|
||||||
linestyle == :solid && return "-"
|
linestyle == :solid && return "-"
|
||||||
linestyle == :dash && return "--"
|
linestyle == :dash && return "--"
|
||||||
linestyle == :dot && return ":"
|
linestyle == :dot && return ":"
|
||||||
linestyle == :dashdot && return "-."
|
linestyle == :dashdot && return "-."
|
||||||
warn("Unknown linestyle $linestyle")
|
warn("Unknown linestyle $linestyle")
|
||||||
return "-"
|
return "-"
|
||||||
end
|
end
|
||||||
|
|
||||||
function getPyPlotMarker(marker::Shape)
|
function getPyPlotMarker(marker::Shape)
|
||||||
n = length(marker.vertices)
|
n = length(marker.vertices)
|
||||||
mat = zeros(n+1,2)
|
mat = zeros(n+1,2)
|
||||||
for (i,vert) in enumerate(marker.vertices)
|
for (i,vert) in enumerate(marker.vertices)
|
||||||
mat[i,1] = vert[1]
|
mat[i,1] = vert[1]
|
||||||
mat[i,2] = vert[2]
|
mat[i,2] = vert[2]
|
||||||
end
|
end
|
||||||
mat[n+1,:] = mat[1,:]
|
mat[n+1,:] = mat[1,:]
|
||||||
pypath.pymember("Path")(mat)
|
pypath.pymember("Path")(mat)
|
||||||
# marker.vertices
|
|
||||||
end
|
end
|
||||||
|
|
||||||
const _path_MOVETO = UInt8(1)
|
const _path_MOVETO = UInt8(1)
|
||||||
@ -99,56 +93,51 @@ end
|
|||||||
|
|
||||||
# get the marker shape
|
# get the marker shape
|
||||||
function getPyPlotMarker(marker::Symbol)
|
function getPyPlotMarker(marker::Symbol)
|
||||||
marker == :none && return " "
|
marker == :none && return " "
|
||||||
marker == :ellipse && return "o"
|
marker == :ellipse && return "o"
|
||||||
marker == :rect && return "s"
|
marker == :rect && return "s"
|
||||||
marker == :diamond && return "D"
|
marker == :diamond && return "D"
|
||||||
marker == :utriangle && return "^"
|
marker == :utriangle && return "^"
|
||||||
marker == :dtriangle && return "v"
|
marker == :dtriangle && return "v"
|
||||||
marker == :cross && return "+"
|
marker == :cross && return "+"
|
||||||
marker == :xcross && return "x"
|
marker == :xcross && return "x"
|
||||||
marker == :star5 && return "*"
|
marker == :star5 && return "*"
|
||||||
marker == :pentagon && return "p"
|
marker == :pentagon && return "p"
|
||||||
marker == :hexagon && return "h"
|
marker == :hexagon && return "h"
|
||||||
marker == :octagon && return "8"
|
marker == :octagon && return "8"
|
||||||
haskey(_shapes, marker) && return getPyPlotMarker(_shapes[marker])
|
haskey(_shapes, marker) && return getPyPlotMarker(_shapes[marker])
|
||||||
|
|
||||||
warn("Unknown marker $marker")
|
warn("Unknown marker $marker")
|
||||||
return "o"
|
return "o"
|
||||||
end
|
end
|
||||||
|
|
||||||
# getPyPlotMarker(markers::AVec) = map(getPyPlotMarker, markers)
|
# getPyPlotMarker(markers::AVec) = map(getPyPlotMarker, markers)
|
||||||
function getPyPlotMarker(markers::AVec)
|
function getPyPlotMarker(markers::AVec)
|
||||||
warn("Vectors of markers are currently unsupported in PyPlot: $markers")
|
warn("Vectors of markers are currently unsupported in PyPlot: $markers")
|
||||||
getPyPlotMarker(markers[1])
|
getPyPlotMarker(markers[1])
|
||||||
end
|
end
|
||||||
|
|
||||||
# pass through
|
# pass through
|
||||||
function getPyPlotMarker(marker::AbstractString)
|
function getPyPlotMarker(marker::AbstractString)
|
||||||
@assert length(marker) == 1
|
@assert length(marker) == 1
|
||||||
marker
|
marker
|
||||||
end
|
end
|
||||||
|
|
||||||
function getPyPlotStepStyle(linetype::Symbol)
|
function getPyPlotStepStyle(linetype::Symbol)
|
||||||
linetype == :steppost && return "steps-post"
|
linetype == :steppost && return "steps-post"
|
||||||
linetype == :steppre && return "steps-pre"
|
linetype == :steppre && return "steps-pre"
|
||||||
return "default"
|
return "default"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# immutable PyPlotFigWrapper
|
|
||||||
# fig
|
|
||||||
# kwargs # for add_subplot
|
|
||||||
# end
|
|
||||||
|
|
||||||
type PyPlotAxisWrapper
|
type PyPlotAxisWrapper
|
||||||
ax
|
ax
|
||||||
rightax
|
rightax
|
||||||
fig
|
fig
|
||||||
kwargs # for add_subplot
|
kwargs # for add_subplot
|
||||||
end
|
end
|
||||||
|
|
||||||
# getfig(wrap::@compat(Union{PyPlotAxisWrapper,PyPlotFigWrapper})) = wrap.fig
|
|
||||||
getfig(wrap::PyPlotAxisWrapper) = wrap.fig
|
getfig(wrap::PyPlotAxisWrapper) = wrap.fig
|
||||||
|
|
||||||
|
|
||||||
@ -165,14 +154,12 @@ function getLeftAxis(wrap::PyPlotAxisWrapper)
|
|||||||
wrap.ax
|
wrap.ax
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# getLeftAxis(wrap::PyPlotAxisWrapper) = wrap.ax
|
|
||||||
# getRightAxis(x) = getLeftAxis(x)[:twinx]()
|
|
||||||
|
|
||||||
function getRightAxis(wrap::PyPlotAxisWrapper)
|
function getRightAxis(wrap::PyPlotAxisWrapper)
|
||||||
if wrap.rightax == nothing
|
if wrap.rightax == nothing
|
||||||
wrap.rightax = getLeftAxis(wrap)[:twinx]()
|
wrap.rightax = getLeftAxis(wrap)[:twinx]()
|
||||||
end
|
end
|
||||||
wrap.rightax
|
wrap.rightax
|
||||||
end
|
end
|
||||||
|
|
||||||
getLeftAxis(plt::Plot{PyPlotBackend}) = getLeftAxis(plt.o)
|
getLeftAxis(plt::Plot{PyPlotBackend}) = getLeftAxis(plt.o)
|
||||||
@ -209,118 +196,94 @@ function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
|
|||||||
return ax[get(fmap, linetype, :plot)]
|
return ax[get(fmap, linetype, :plot)]
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateAxisColors(ax, fgcolor)
|
|
||||||
# for loc in ("bottom", "top", "left", "right")
|
|
||||||
for (loc, spine) in ax[:spines]
|
|
||||||
# ax[:spines][loc][:set_color](fgcolor)
|
|
||||||
spine[:set_color](fgcolor)
|
|
||||||
end
|
|
||||||
for axis in ("x", "y")
|
|
||||||
ax[:tick_params](axis=axis, colors=fgcolor, which="both")
|
|
||||||
end
|
|
||||||
for axis in (:yaxis, :xaxis)
|
|
||||||
ax[axis][:label][:set_color](fgcolor)
|
|
||||||
end
|
|
||||||
ax[:title][:set_color](fgcolor)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Bool)
|
function handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Bool)
|
||||||
if smooth
|
if smooth
|
||||||
xs, ys = regressionXY(d[:x], d[:y])
|
xs, ys = regressionXY(d[:x], d[:y])
|
||||||
ax[:plot](xs, ys,
|
ax[:plot](xs, ys,
|
||||||
# linestyle = getPyPlotLineStyle(:path, :dashdot),
|
# linestyle = getPyPlotLineStyle(:path, :dashdot),
|
||||||
color = getPyPlotColor(d[:linecolor]),
|
color = getPyPlotColor(d[:linecolor]),
|
||||||
linewidth = 2
|
linewidth = 2
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Real) = handleSmooth(plt, ax, d, true)
|
handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Real) = handleSmooth(plt, ax, d, true)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# makePyPlotCurrent(wrap::PyPlotFigWrapper) = PyPlot.figure(wrap.fig.o[:number])
|
|
||||||
# makePyPlotCurrent(wrap::PyPlotAxisWrapper) = nothing #PyPlot.sca(wrap.ax.o)
|
|
||||||
makePyPlotCurrent(wrap::PyPlotAxisWrapper) = wrap.ax == nothing ? PyPlot.figure(wrap.fig.o[:number]) : nothing
|
makePyPlotCurrent(wrap::PyPlotAxisWrapper) = wrap.ax == nothing ? PyPlot.figure(wrap.fig.o[:number]) : nothing
|
||||||
makePyPlotCurrent(plt::Plot{PyPlotBackend}) = plt.o == nothing ? nothing : makePyPlotCurrent(plt.o)
|
makePyPlotCurrent(plt::Plot{PyPlotBackend}) = plt.o == nothing ? nothing : makePyPlotCurrent(plt.o)
|
||||||
|
|
||||||
|
|
||||||
function _before_add_series(plt::Plot{PyPlotBackend})
|
function _before_add_series(plt::Plot{PyPlotBackend})
|
||||||
makePyPlotCurrent(plt)
|
makePyPlotCurrent(plt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
function pyplot_figure(plotargs::KW)
|
function pyplot_figure(plotargs::KW)
|
||||||
w,h = map(px2inch, plotargs[:size])
|
w,h = map(px2inch, plotargs[:size])
|
||||||
bgcolor = getPyPlotColor(plotargs[:background_color])
|
bgcolor = getPyPlotColor(plotargs[:background_color])
|
||||||
|
|
||||||
# reuse the current figure?
|
# reuse the current figure?
|
||||||
fig = if plotargs[:overwrite_figure]
|
fig = if plotargs[:overwrite_figure]
|
||||||
PyPlot.gcf()
|
PyPlot.gcf()
|
||||||
else
|
else
|
||||||
PyPlot.figure()
|
PyPlot.figure()
|
||||||
end
|
end
|
||||||
|
|
||||||
# update the specs
|
# update the specs
|
||||||
# fig[:set_size_inches](w,h, (isijulia() ? [] : [true])...)
|
# fig[:set_size_inches](w,h, (isijulia() ? [] : [true])...)
|
||||||
fig[:set_size_inches](w, h, forward = true)
|
fig[:set_size_inches](w, h, forward = true)
|
||||||
fig[:set_facecolor](bgcolor)
|
fig[:set_facecolor](bgcolor)
|
||||||
fig[:set_dpi](DPI)
|
fig[:set_dpi](DPI)
|
||||||
fig[:set_tight_layout](true)
|
fig[:set_tight_layout](true)
|
||||||
|
|
||||||
# clear the figure
|
# clear the figure
|
||||||
PyPlot.clf()
|
PyPlot.clf()
|
||||||
|
|
||||||
# resize the window
|
# resize the window
|
||||||
PyPlot.plt[:get_current_fig_manager]()[:resize](plotargs[:size]...)
|
PyPlot.plt[:get_current_fig_manager]()[:resize](plotargs[:size]...)
|
||||||
fig
|
fig
|
||||||
end
|
end
|
||||||
|
|
||||||
function pyplot_3d_setup!(wrap, d)
|
function pyplot_3d_setup!(wrap, d)
|
||||||
# 3D?
|
# 3D?
|
||||||
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
|
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
|
||||||
if trueOrAllTrue(lt -> lt in _3dTypes, get(d, :linetype, :none))
|
if trueOrAllTrue(lt -> lt in _3dTypes, get(d, :linetype, :none))
|
||||||
push!(wrap.kwargs, (:projection, "3d"))
|
push!(wrap.kwargs, (:projection, "3d"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
# TODO:
|
|
||||||
# fillto # might have to use barHack/histogramHack??
|
|
||||||
# reg # true or false, add a regression line for each line
|
|
||||||
# pos # (Int,Int), move the enclosing window to this position
|
|
||||||
# windowtitle # string or symbol, set the title of the enclosing windowtitle
|
|
||||||
# screen # Integer, move enclosing window to this screen number (for multiscreen desktops)
|
|
||||||
# show # true or false, show the plot (in case you don't want the window to pop up right away)
|
|
||||||
|
|
||||||
function _create_plot(pkg::PyPlotBackend; kw...)
|
function _create_plot(pkg::PyPlotBackend; kw...)
|
||||||
# create the figure
|
# create the figure
|
||||||
d = KW(kw)
|
d = KW(kw)
|
||||||
|
|
||||||
# standalone plots will create a figure, but not if part of a subplot (do it later)
|
# standalone plots will create a figure, but not if part of a subplot (do it later)
|
||||||
if haskey(d, :subplot)
|
if haskey(d, :subplot)
|
||||||
wrap = nothing
|
wrap = nothing
|
||||||
else
|
else
|
||||||
wrap = PyPlotAxisWrapper(nothing, nothing, pyplot_figure(d), [])
|
wrap = PyPlotAxisWrapper(nothing, nothing, pyplot_figure(d), [])
|
||||||
# wrap = PyPlotAxisWrapper(nothing, nothing, PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true), [])
|
# wrap = PyPlotAxisWrapper(nothing, nothing, PyPlot.figure(; figsize = (w,h), facecolor = bgcolor, dpi = DPI, tight_layout = true), [])
|
||||||
|
|
||||||
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
|
# if haskey(d, :linetype) && first(d[:linetype]) in _3dTypes # && isa(plt.o, PyPlotFigWrapper)
|
||||||
# push!(wrap.kwargs, (:projection, "3d"))
|
# push!(wrap.kwargs, (:projection, "3d"))
|
||||||
# end
|
# end
|
||||||
pyplot_3d_setup!(wrap, d)
|
pyplot_3d_setup!(wrap, d)
|
||||||
|
|
||||||
if get(d, :polar, false)
|
if get(d, :polar, false)
|
||||||
push!(wrap.kwargs, (:polar, true))
|
push!(wrap.kwargs, (:polar, true))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
plt = Plot(wrap, pkg, 0, d, KW[])
|
plt = Plot(wrap, pkg, 0, d, KW[])
|
||||||
plt
|
plt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
||||||
d = KW(kw)
|
d = KW(kw)
|
||||||
@ -430,7 +393,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
|||||||
extra_kwargs[:c] = convert(Vector{Float64}, d[:zcolor])
|
extra_kwargs[:c] = convert(Vector{Float64}, d[:zcolor])
|
||||||
extra_kwargs[:cmap] = getPyPlotColorMap(c, d[:markeralpha])
|
extra_kwargs[:cmap] = getPyPlotColorMap(c, d[:markeralpha])
|
||||||
else
|
else
|
||||||
# extra_kwargs[:c] = getPyPlotColor(c, d[:markeralpha])
|
|
||||||
ppc = getPyPlotColor(c, d[:markeralpha])
|
ppc = getPyPlotColor(c, d[:markeralpha])
|
||||||
|
|
||||||
# total hack due to PyPlot bug (see issue #145).
|
# total hack due to PyPlot bug (see issue #145).
|
||||||
@ -442,9 +404,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
|||||||
extra_kwargs[:c] = ppc
|
extra_kwargs[:c] = ppc
|
||||||
|
|
||||||
end
|
end
|
||||||
# if d[:markeralpha] != nothing
|
|
||||||
# extra_kwargs[:alpha] = d[:markeralpha]
|
|
||||||
# end
|
|
||||||
extra_kwargs[:edgecolors] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha])
|
extra_kwargs[:edgecolors] = getPyPlotColor(d[:markerstrokecolor], d[:markerstrokealpha])
|
||||||
extra_kwargs[:linewidths] = d[:markerstrokewidth]
|
extra_kwargs[:linewidths] = d[:markerstrokewidth]
|
||||||
else
|
else
|
||||||
@ -456,12 +415,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# if d[:markeralpha] != nothing
|
|
||||||
# extra_kwargs[:alpha] = d[:markeralpha]
|
|
||||||
# elseif d[:linealpha] != nothing
|
|
||||||
# extra_kwargs[:alpha] = d[:linealpha]
|
|
||||||
# end
|
|
||||||
|
|
||||||
# set these for all types
|
# set these for all types
|
||||||
if !(lt in (:contour,:surface,:wireframe,:heatmap))
|
if !(lt in (:contour,:surface,:wireframe,:heatmap))
|
||||||
if !(lt in (:scatter, :scatter3d, :shape))
|
if !(lt in (:scatter, :scatter3d, :shape))
|
||||||
@ -555,190 +508,185 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function Base.getindex(plt::Plot{PyPlotBackend}, i::Integer)
|
function Base.getindex(plt::Plot{PyPlotBackend}, i::Integer)
|
||||||
series = plt.seriesargs[i][:serieshandle]
|
series = plt.seriesargs[i][:serieshandle]
|
||||||
try
|
try
|
||||||
return series[:get_data]()
|
return series[:get_data]()
|
||||||
catch
|
catch
|
||||||
xy = series[:get_offsets]()
|
xy = series[:get_offsets]()
|
||||||
return vec(xy[:,1]), vec(xy[:,2])
|
return vec(xy[:,1]), vec(xy[:,2])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function minmaxseries(ds, vec, axis)
|
function minmaxseries(ds, vec, axis)
|
||||||
lo, hi = Inf, -Inf
|
lo, hi = Inf, -Inf
|
||||||
for d in ds
|
for d in ds
|
||||||
d[:axis] == axis || continue
|
d[:axis] == axis || continue
|
||||||
v = d[vec]
|
v = d[vec]
|
||||||
if length(v) > 0
|
if length(v) > 0
|
||||||
vlo, vhi = extrema(v)
|
vlo, vhi = extrema(v)
|
||||||
lo = min(lo, vlo)
|
lo = min(lo, vlo)
|
||||||
hi = max(hi, vhi)
|
hi = max(hi, vhi)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
if lo == hi
|
||||||
if lo == hi
|
hi = if lo == 0
|
||||||
hi = if lo == 0
|
1e-6
|
||||||
1e-6
|
else
|
||||||
else
|
hi + min(abs(1e-2hi), 1e-6)
|
||||||
hi + min(abs(1e-2hi), 1e-6)
|
end
|
||||||
end
|
end
|
||||||
end
|
lo, hi
|
||||||
lo, hi
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: this needs to handle one-sided fixed limits
|
# TODO: this needs to handle one-sided fixed limits
|
||||||
function set_lims!(plt::Plot{PyPlotBackend}, axis::Symbol)
|
function set_lims!(plt::Plot{PyPlotBackend}, axis::Symbol)
|
||||||
ax = getAxis(plt, axis)
|
ax = getAxis(plt, axis)
|
||||||
if plt.plotargs[:xlims] == :auto
|
if plt.plotargs[:xlims] == :auto
|
||||||
ax[:set_xlim](minmaxseries(plt.seriesargs, :x, axis)...)
|
ax[:set_xlim](minmaxseries(plt.seriesargs, :x, axis)...)
|
||||||
end
|
end
|
||||||
if plt.plotargs[:ylims] == :auto
|
if plt.plotargs[:ylims] == :auto
|
||||||
ax[:set_ylim](minmaxseries(plt.seriesargs, :y, axis)...)
|
ax[:set_ylim](minmaxseries(plt.seriesargs, :y, axis)...)
|
||||||
end
|
end
|
||||||
if plt.plotargs[:zlims] == :auto && haskey(ax, :set_zlim)
|
if plt.plotargs[:zlims] == :auto && haskey(ax, :set_zlim)
|
||||||
ax[:set_zlim](minmaxseries(plt.seriesargs, :z, axis)...)
|
ax[:set_zlim](minmaxseries(plt.seriesargs, :z, axis)...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Base.setindex!{X,Y}(plt::Plot{PyPlotBackend}, xy::Tuple{X,Y}, i::Integer)
|
function Base.setindex!{X,Y}(plt::Plot{PyPlotBackend}, xy::Tuple{X,Y}, i::Integer)
|
||||||
d = plt.seriesargs[i]
|
d = plt.seriesargs[i]
|
||||||
series = d[:serieshandle]
|
series = d[:serieshandle]
|
||||||
x, y = xy
|
x, y = xy
|
||||||
d[:x], d[:y] = x, y
|
d[:x], d[:y] = x, y
|
||||||
try
|
try
|
||||||
series[:set_data](x, y)
|
series[:set_data](x, y)
|
||||||
catch
|
catch
|
||||||
series[:set_offsets](hcat(x, y))
|
series[:set_offsets](hcat(x, y))
|
||||||
end
|
end
|
||||||
|
|
||||||
set_lims!(plt, d[:axis])
|
set_lims!(plt, d[:axis])
|
||||||
plt
|
plt
|
||||||
end
|
end
|
||||||
|
|
||||||
function Base.setindex!{X,Y,Z}(plt::Plot{PyPlotBackend}, xyz::Tuple{X,Y,Z}, i::Integer)
|
function Base.setindex!{X,Y,Z}(plt::Plot{PyPlotBackend}, xyz::Tuple{X,Y,Z}, i::Integer)
|
||||||
warn("setindex not implemented for xyz")
|
warn("setindex not implemented for xyz")
|
||||||
plt
|
plt
|
||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
function addPyPlotLims(ax, lims, dimension)
|
function addPyPlotLims(ax, lims, letter)
|
||||||
lims == :auto && return
|
lims == :auto && return
|
||||||
ltype = limsType(lims)
|
ltype = limsType(lims)
|
||||||
if ltype == :limits
|
if ltype == :limits
|
||||||
if dimension == :xlim
|
setf = ax[symbol("set_", letter, "lim")]
|
||||||
isfinite(lims[1]) && ax[:set_xlim](left = lims[1])
|
l1, l2 = lims
|
||||||
isfinite(lims[2]) && ax[:set_xlim](right = lims[2])
|
if isfinite(l1)
|
||||||
elseif dimension == :ylim
|
letter == "x" ? setf(left = l1) : setf(bottom = l1)
|
||||||
isfinite(lims[1]) && ax[:set_ylim](bottom = lims[1])
|
end
|
||||||
isfinite(lims[2]) && ax[:set_ylim](top = lims[2])
|
if isfinite(l2)
|
||||||
elseif dimension == :zlim && haskey(ax, :set_zlim)
|
letter == "x" ? setf(right = l2) : setf(top = l2)
|
||||||
isfinite(lims[1]) && ax[:set_zlim](bottom = lims[1])
|
|
||||||
isfinite(lims[2]) && ax[:set_zlim](top = lims[2])
|
|
||||||
else
|
|
||||||
error("Invalid argument at position 3: $dimension")
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error("Invalid input for $dimension: ", lims)
|
error("Invalid input for $letter: ", lims)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function addPyPlotTicks(ax, ticks, isx::Bool)
|
function addPyPlotTicks(ax, ticks, letter)
|
||||||
ticks == :auto && return
|
ticks == :auto && return
|
||||||
if ticks == :none || ticks == nothing
|
if ticks == :none || ticks == nothing
|
||||||
ticks = zeros(0)
|
ticks = zeros(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
ttype = ticksType(ticks)
|
ttype = ticksType(ticks)
|
||||||
if ttype == :ticks
|
tickfunc = symbol("set_", letter, "ticks")
|
||||||
ax[isx ? :set_xticks : :set_yticks](ticks)
|
labfunc = symbol("set_", letter, "ticklabels")
|
||||||
elseif ttype == :ticks_and_labels
|
if ttype == :ticks
|
||||||
ax[isx ? :set_xticks : :set_yticks](ticks[1])
|
ax[tickfunc](ticks)
|
||||||
ax[isx ? :set_xticklabels : :set_yticklabels](ticks[2])
|
elseif ttype == :ticks_and_labels
|
||||||
else
|
ax[tickfunc](ticks[1])
|
||||||
error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
|
ax[labfunc](ticks[2])
|
||||||
end
|
else
|
||||||
|
error("Invalid input for $(isx ? "xticks" : "yticks"): ", ticks)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
usingRightAxis(plt::Plot{PyPlotBackend}) = any(args -> args[:axis] in (:right,:auto), plt.seriesargs)
|
function applyPyPlotScale(ax, scaleType::Symbol, letter)
|
||||||
|
func = ax[symbol("set_", letter, "scale")]
|
||||||
|
scaleType == :identity && return func("linear")
|
||||||
|
scaleType == :ln && return func("log", basex = e, basey = e)
|
||||||
|
scaleType == :log2 && return func("log", basex = 2, basey = 2)
|
||||||
|
scaleType == :log10 && return func("log", basex = 10, basey = 10)
|
||||||
|
warn("Unhandled scaleType: ", scaleType)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function updateAxisColors(ax, fgcolor)
|
||||||
|
for (loc, spine) in ax[:spines]
|
||||||
|
spine[:set_color](fgcolor)
|
||||||
|
end
|
||||||
|
for letter in ("x", "y", "z")
|
||||||
|
axis = axis_symbol(letter, "axis")
|
||||||
|
if haskey(ax, axis)
|
||||||
|
ax[:tick_params](axis=letter, colors=fgcolor, which="both")
|
||||||
|
ax[axis][:label][:set_color](fgcolor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ax[:title][:set_color](fgcolor)
|
||||||
|
end
|
||||||
|
|
||||||
|
function usingRightAxis(plt::Plot{PyPlotBackend})
|
||||||
|
any(args -> args[:axis] in (:right,:auto), plt.seriesargs)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
|
function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
|
||||||
figorax = plt.o
|
figorax = plt.o
|
||||||
ax = getLeftAxis(figorax)
|
ax = getLeftAxis(figorax)
|
||||||
# PyPlot.sca(ax)
|
ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
|
||||||
|
guidesz = get(d, :guidefont, plt.plotargs[:guidefont]).pointsize
|
||||||
|
|
||||||
|
# title
|
||||||
|
haskey(d, :title) && ax[:set_title](d[:title])
|
||||||
|
ax[:title][:set_fontsize](guidesz)
|
||||||
|
|
||||||
# title and axis labels
|
# handle right y axis
|
||||||
# haskey(d, :title) && PyPlot.title(d[:title])
|
axes = [getLeftAxis(figorax)]
|
||||||
haskey(d, :title) && ax[:set_title](d[:title])
|
if usingRightAxis(plt)
|
||||||
haskey(d, :xlabel) && ax[:set_xlabel](d[:xlabel])
|
push!(axes, getRightAxis(figorax))
|
||||||
if haskey(d, :ylabel)
|
if get(d, :yrightlabel, "") != ""
|
||||||
ax[:set_ylabel](d[:ylabel])
|
rightax = getRightAxis(figorax)
|
||||||
end
|
rightax[:set_ylabel](d[:yrightlabel])
|
||||||
if usingRightAxis(plt) && get(d, :yrightlabel, "") != ""
|
end
|
||||||
rightax = getRightAxis(figorax)
|
|
||||||
rightax[:set_ylabel](d[:yrightlabel])
|
|
||||||
end
|
|
||||||
|
|
||||||
# scales
|
|
||||||
haskey(d, :xscale) && applyPyPlotScale(ax, d[:xscale], true)
|
|
||||||
haskey(d, :yscale) && applyPyPlotScale(ax, d[:yscale], false)
|
|
||||||
|
|
||||||
# limits and ticks
|
|
||||||
haskey(d, :xlims) && addPyPlotLims(ax, d[:xlims], :xlim)
|
|
||||||
haskey(d, :ylims) && addPyPlotLims(ax, d[:ylims], :ylim)
|
|
||||||
haskey(d, :zlims) && addPyPlotLims(ax, d[:zlims], :zlim)
|
|
||||||
haskey(d, :xticks) && addPyPlotTicks(ax, d[:xticks], true)
|
|
||||||
haskey(d, :yticks) && addPyPlotTicks(ax, d[:yticks], false)
|
|
||||||
|
|
||||||
if get(d, :xflip, false)
|
|
||||||
ax[:invert_xaxis]()
|
|
||||||
end
|
|
||||||
if get(d, :yflip, false)
|
|
||||||
ax[:invert_yaxis]()
|
|
||||||
end
|
|
||||||
|
|
||||||
axes = [getLeftAxis(figorax)]
|
|
||||||
if usingRightAxis(plt)
|
|
||||||
push!(axes, getRightAxis(figorax))
|
|
||||||
end
|
|
||||||
|
|
||||||
# font sizes
|
|
||||||
for ax in axes
|
|
||||||
# haskey(d, :yrightlabel) || continue
|
|
||||||
|
|
||||||
|
|
||||||
# guides
|
|
||||||
sz = get(d, :guidefont, plt.plotargs[:guidefont]).pointsize
|
|
||||||
ax[:title][:set_fontsize](sz)
|
|
||||||
ax[:xaxis][:label][:set_fontsize](sz)
|
|
||||||
ax[:yaxis][:label][:set_fontsize](sz)
|
|
||||||
|
|
||||||
# ticks
|
|
||||||
sz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
|
|
||||||
for sym in (:get_xticklabels, :get_yticklabels)
|
|
||||||
for lab in ax[sym]()
|
|
||||||
lab[:set_fontsize](sz)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# grid
|
# handle each axis in turn
|
||||||
if get(d, :grid, false)
|
for letter in ("x", "y", "z")
|
||||||
ax[:xaxis][:grid](true)
|
axis, scale, lims, ticks, flip, lab = axis_symbols(letter, "axis", "scale", "lims", "ticks", "flip", "label")
|
||||||
ax[:yaxis][:grid](true)
|
haskey(ax, axis) || continue
|
||||||
ax[:set_axisbelow](true)
|
haskey(d, scale) && applyPyPlotScale(ax, d[scale], letter)
|
||||||
|
haskey(d, lims) && addPyPlotLims(ax, d[lims], letter)
|
||||||
|
haskey(d, ticks) && addPyPlotTicks(ax, d[ticks], letter)
|
||||||
|
haskey(d, lab) && ax[symbol("set_", letter, "label")](d[lab])
|
||||||
|
if get(d, flip, false)
|
||||||
|
ax[symbol("invert_", letter, "axis")]()
|
||||||
|
end
|
||||||
|
for tmpax in axes
|
||||||
|
tmpax[axis][:label][:set_fontsize](guidesz)
|
||||||
|
for lab in tmpax[symbol("get_", letter, "ticklabels")]()
|
||||||
|
lab[:set_fontsize](ticksz)
|
||||||
|
end
|
||||||
|
if get(d, :grid, false)
|
||||||
|
fgcolor = getPyPlotColor(plt.plotargs[:foreground_color])
|
||||||
|
tmpax[axis][:grid](true, color = fgcolor)
|
||||||
|
tmpax[:set_axisbelow](true)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function applyPyPlotScale(ax, scaleType::Symbol, isx::Bool)
|
|
||||||
func = ax[isx ? :set_xscale : :set_yscale]
|
|
||||||
scaleType == :identity && return func("linear")
|
|
||||||
scaleType == :ln && return func("log", basex = e, basey = e)
|
|
||||||
scaleType == :log2 && return func("log", basex = 2, basey = 2)
|
|
||||||
scaleType == :log10 && return func("log", basex = 10, basey = 10)
|
|
||||||
warn("Unhandled scaleType: ", scaleType)
|
|
||||||
end
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -21,72 +21,36 @@ stringsSupported() = stringsSupported(backend())
|
|||||||
|
|
||||||
supportedArgs(::GadflyBackend) = [
|
supportedArgs(::GadflyBackend) = [
|
||||||
:annotation,
|
:annotation,
|
||||||
# :axis,
|
:background_color, :foreground_color, :color_palette,
|
||||||
:background_color,
|
|
||||||
:linecolor,
|
|
||||||
:color_palette,
|
|
||||||
:fillrange,
|
|
||||||
:fillcolor,
|
|
||||||
:fillalpha,
|
|
||||||
:foreground_color,
|
|
||||||
:group,
|
:group,
|
||||||
:label,
|
:label,
|
||||||
:layout,
|
|
||||||
:legend,
|
|
||||||
:colorbar,
|
|
||||||
:linestyle,
|
|
||||||
:linetype,
|
:linetype,
|
||||||
:linewidth,
|
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||||
:linealpha,
|
:markershape, :markercolor, :markersize, :markeralpha,
|
||||||
:markershape,
|
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
||||||
:markercolor,
|
:fillrange, :fillcolor, :fillalpha,
|
||||||
:markersize,
|
|
||||||
:markeralpha,
|
|
||||||
:markerstrokewidth,
|
|
||||||
:markerstrokecolor,
|
|
||||||
:markerstrokealpha,
|
|
||||||
# :markerstrokestyle,
|
|
||||||
:n,
|
|
||||||
:nbins,
|
:nbins,
|
||||||
:nc,
|
:n, :nc, :nr, :layout,
|
||||||
:nr,
|
|
||||||
# :pos,
|
|
||||||
:smooth,
|
:smooth,
|
||||||
:show,
|
:title, :windowtitle, :show, :size,
|
||||||
:size,
|
:x, :xlabel, :xlims, :xticks, :xscale, :xflip,
|
||||||
:title,
|
:y, :ylabel, :ylims, :yticks, :yscale, :yflip,
|
||||||
:windowtitle,
|
# :z, :zlabel, :zlims, :zticks, :zscale, :zflip,
|
||||||
:x,
|
|
||||||
:xlabel,
|
|
||||||
:xlims,
|
|
||||||
:xticks,
|
|
||||||
:y,
|
|
||||||
:ylabel,
|
|
||||||
:ylims,
|
|
||||||
# :yrightlabel,
|
|
||||||
:yticks,
|
|
||||||
:xscale,
|
|
||||||
:yscale,
|
|
||||||
:xflip,
|
|
||||||
:yflip,
|
|
||||||
:z,
|
:z,
|
||||||
:zcolor,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:tickfont,
|
:grid, :legend, :colorbar,
|
||||||
:guidefont,
|
:zcolor, :levels,
|
||||||
:legendfont,
|
:xerror, :yerror,
|
||||||
:grid,
|
:ribbon, :quiver,
|
||||||
# :surface,
|
|
||||||
:levels,
|
|
||||||
:xerror,
|
|
||||||
:yerror,
|
|
||||||
:ribbon,
|
|
||||||
:quiver,
|
|
||||||
:orientation,
|
:orientation,
|
||||||
]
|
]
|
||||||
supportedAxes(::GadflyBackend) = [:auto, :left]
|
supportedAxes(::GadflyBackend) = [:auto, :left]
|
||||||
supportedTypes(::GadflyBackend) = [:none, :line, :path, :steppre, :steppost, :sticks,
|
supportedTypes(::GadflyBackend) = [
|
||||||
:scatter, :hist2d, :hexbin, :hist, :bar, :box, :violin, :quiver,
|
:none, :line, :path, :steppre, :steppost, :sticks,
|
||||||
:hline, :vline, :contour, :shape]
|
:scatter, :hist2d, :hexbin, :hist,
|
||||||
|
:bar, :box, :violin, :quiver,
|
||||||
|
:hline, :vline, :contour, :shape
|
||||||
|
]
|
||||||
supportedStyles(::GadflyBackend) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
supportedStyles(::GadflyBackend) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
supportedMarkers(::GadflyBackend) = vcat(_allMarkers, Shape)
|
supportedMarkers(::GadflyBackend) = vcat(_allMarkers, Shape)
|
||||||
supportedScales(::GadflyBackend) = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
|
supportedScales(::GadflyBackend) = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
|
||||||
@ -110,78 +74,41 @@ subplotSupported(::ImmerseBackend) = true
|
|||||||
|
|
||||||
supportedArgs(::PyPlotBackend) = [
|
supportedArgs(::PyPlotBackend) = [
|
||||||
:annotation,
|
:annotation,
|
||||||
:axis,
|
:background_color, :foreground_color, :color_palette,
|
||||||
:background_color,
|
|
||||||
:linecolor,
|
|
||||||
:color_palette,
|
|
||||||
:fillrange,
|
|
||||||
:fillcolor,
|
|
||||||
:foreground_color,
|
|
||||||
:group,
|
:group,
|
||||||
:label,
|
:label,
|
||||||
:layout,
|
|
||||||
:legend,
|
|
||||||
:colorbar,
|
|
||||||
:linestyle,
|
|
||||||
:linetype,
|
:linetype,
|
||||||
:linewidth,
|
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||||
:markershape,
|
:markershape, :markercolor, :markersize, :markeralpha,
|
||||||
:markercolor,
|
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
||||||
:markersize,
|
:fillrange, :fillcolor, :fillalpha,
|
||||||
:markerstrokewidth,
|
|
||||||
:markerstrokecolor,
|
|
||||||
:markerstrokealpha,
|
|
||||||
# :markerstrokestyle,
|
|
||||||
:n,
|
|
||||||
:nbins,
|
:nbins,
|
||||||
:nc,
|
:n, :nc, :nr, :layout,
|
||||||
:nr,
|
|
||||||
# :pos,
|
|
||||||
:smooth,
|
:smooth,
|
||||||
# :ribbon,
|
:title, :windowtitle, :show, :size,
|
||||||
:show,
|
:x, :xlabel, :xlims, :xticks, :xscale, :xflip,
|
||||||
:size,
|
:y, :ylabel, :ylims, :yticks, :yscale, :yflip,
|
||||||
:title,
|
:axis, :yrightlabel,
|
||||||
:windowtitle,
|
:z, :zlabel, :zlims, :zticks, :zscale, :zflip,
|
||||||
:x,
|
|
||||||
:xlabel,
|
|
||||||
:xlims,
|
|
||||||
:xticks,
|
|
||||||
:y,
|
|
||||||
:ylabel,
|
|
||||||
:ylims,
|
|
||||||
:zlims,
|
|
||||||
:yrightlabel,
|
|
||||||
:yticks,
|
|
||||||
:xscale,
|
|
||||||
:yscale,
|
|
||||||
:xflip,
|
|
||||||
:yflip,
|
|
||||||
:z,
|
:z,
|
||||||
:zcolor, # only supported for scatter/scatter3d
|
:tickfont, :guidefont, :legendfont,
|
||||||
:tickfont,
|
:grid, :legend, :colorbar,
|
||||||
:guidefont,
|
:zcolor, :levels,
|
||||||
:legendfont,
|
:xerror, :yerror,
|
||||||
:grid,
|
:ribbon, :quiver,
|
||||||
# :surface,
|
|
||||||
:levels,
|
|
||||||
:fillalpha,
|
|
||||||
:linealpha,
|
|
||||||
:markeralpha,
|
|
||||||
:overwrite_figure,
|
|
||||||
:xerror,
|
|
||||||
:yerror,
|
|
||||||
:ribbon,
|
|
||||||
:quiver,
|
|
||||||
:orientation,
|
:orientation,
|
||||||
|
:overwrite_figure,
|
||||||
:polar,
|
:polar,
|
||||||
]
|
]
|
||||||
supportedAxes(::PyPlotBackend) = _allAxes
|
supportedAxes(::PyPlotBackend) = _allAxes
|
||||||
supportedTypes(::PyPlotBackend) = [:none, :line, :path, :steppre, :steppost, :shape,
|
supportedTypes(::PyPlotBackend) = [
|
||||||
:scatter, :hist2d, :hexbin, :hist, :density, :bar, :box, :violin, :quiver,
|
:none, :line, :path, :steppre, :steppost, :shape,
|
||||||
:hline, :vline, :contour, :path3d, :scatter3d, :surface, :wireframe, :heatmap]
|
:scatter, :hist2d, :hexbin, :hist, :density,
|
||||||
|
:bar, :box, :violin, :quiver,
|
||||||
|
:hline, :vline, :heatmap,
|
||||||
|
:contour, :path3d, :scatter3d, :surface, :wireframe
|
||||||
|
]
|
||||||
supportedStyles(::PyPlotBackend) = [:auto, :solid, :dash, :dot, :dashdot]
|
supportedStyles(::PyPlotBackend) = [:auto, :solid, :dash, :dot, :dashdot]
|
||||||
# supportedMarkers(::PyPlotBackend) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :hexagon]
|
|
||||||
supportedMarkers(::PyPlotBackend) = vcat(_allMarkers, Shape)
|
supportedMarkers(::PyPlotBackend) = vcat(_allMarkers, Shape)
|
||||||
supportedScales(::PyPlotBackend) = [:identity, :ln, :log2, :log10]
|
supportedScales(::PyPlotBackend) = [:identity, :ln, :log2, :log10]
|
||||||
subplotSupported(::PyPlotBackend) = true
|
subplotSupported(::PyPlotBackend) = true
|
||||||
|
|||||||
46
src/plot.jl
46
src/plot.jl
@ -78,62 +78,19 @@ function plot!(plt::Plot, args...; kw...)
|
|||||||
args = _apply_recipe(d, args...; kw...)
|
args = _apply_recipe(d, args...; kw...)
|
||||||
|
|
||||||
dumpdict(d, "After plot! preprocessing")
|
dumpdict(d, "After plot! preprocessing")
|
||||||
# @show groupargs map(typeof, args)
|
|
||||||
|
|
||||||
warnOnUnsupportedArgs(plt.backend, d)
|
warnOnUnsupportedArgs(plt.backend, d)
|
||||||
|
|
||||||
# just in case the backend needs to set up the plot (make it current or something)
|
# just in case the backend needs to set up the plot (make it current or something)
|
||||||
_before_add_series(plt)
|
_before_add_series(plt)
|
||||||
|
|
||||||
# # grouping
|
# # grouping
|
||||||
# groupargs = get(d, :group, nothing) == nothing ? [nothing] : [extractGroupArgs(d[:group], args...)]
|
|
||||||
# # @show groupargs
|
|
||||||
|
|
||||||
# TODO: get the GroupBy object (or nothing), and loop through the groups, doing the following section many times
|
|
||||||
# dumpdict(d, "before", true)
|
|
||||||
groupby = if haskey(d, :group)
|
groupby = if haskey(d, :group)
|
||||||
extractGroupArgs(d[:group], args...)
|
extractGroupArgs(d[:group], args...)
|
||||||
else
|
else
|
||||||
nothing
|
nothing
|
||||||
end
|
end
|
||||||
# dumpdict(d, "after", true)
|
|
||||||
# @show groupby map(typeof, args)
|
|
||||||
|
|
||||||
_add_series(plt, d, groupby, args...)
|
_add_series(plt, d, groupby, args...)
|
||||||
|
|
||||||
#
|
|
||||||
# # get the list of dictionaries, one per series
|
|
||||||
# @show groupargs map(typeof, args)
|
|
||||||
# dumpdict(d, "before process_inputs")
|
|
||||||
# process_inputs(plt, d, groupargs..., args...)
|
|
||||||
# dumpdict(d, "after process_inputs", true)
|
|
||||||
# seriesArgList, xmeta, ymeta = build_series_args(plt, d)
|
|
||||||
# # seriesArgList, xmeta, ymeta = build_series_args(plt, groupargs..., args...; d...)
|
|
||||||
#
|
|
||||||
# # if we were able to extract guide information from the series inputs, then update the plot
|
|
||||||
# # @show xmeta, ymeta
|
|
||||||
# updateDictWithMeta(d, plt.plotargs, xmeta, true)
|
|
||||||
# updateDictWithMeta(d, plt.plotargs, ymeta, false)
|
|
||||||
#
|
|
||||||
# # now we can plot the series
|
|
||||||
# for (i,di) in enumerate(seriesArgList)
|
|
||||||
# plt.n += 1
|
|
||||||
#
|
|
||||||
# if !stringsSupported()
|
|
||||||
# setTicksFromStringVector(d, di, :x, :xticks)
|
|
||||||
# setTicksFromStringVector(d, di, :y, :yticks)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # remove plot args
|
|
||||||
# for k in keys(_plotDefaults)
|
|
||||||
# delete!(di, k)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# dumpdict(di, "Series $i")
|
|
||||||
#
|
|
||||||
# _add_series(plt.backend, plt; di...)
|
|
||||||
# end
|
|
||||||
|
|
||||||
_add_annotations(plt, d)
|
_add_annotations(plt, d)
|
||||||
|
|
||||||
warnOnUnsupportedScales(plt.backend, d)
|
warnOnUnsupportedScales(plt.backend, d)
|
||||||
@ -150,7 +107,7 @@ function plot!(plt::Plot, args...; kw...)
|
|||||||
|
|
||||||
current(plt)
|
current(plt)
|
||||||
|
|
||||||
# NOTE: lets ignore the show param and effectively use the semicolon at the end of the REPL statement
|
# note: lets ignore the show param and effectively use the semicolon at the end of the REPL statement
|
||||||
# # do we want to show it?
|
# # do we want to show it?
|
||||||
if haskey(d, :show) && d[:show]
|
if haskey(d, :show) && d[:show]
|
||||||
gui()
|
gui()
|
||||||
@ -212,6 +169,7 @@ function _add_series(plt::Plot, d::KW, ::Void, args...;
|
|||||||
if !stringsSupported()
|
if !stringsSupported()
|
||||||
setTicksFromStringVector(d, di, :x, :xticks)
|
setTicksFromStringVector(d, di, :x, :xticks)
|
||||||
setTicksFromStringVector(d, di, :y, :yticks)
|
setTicksFromStringVector(d, di, :y, :yticks)
|
||||||
|
setTicksFromStringVector(d, di, :z, :zticks)
|
||||||
end
|
end
|
||||||
|
|
||||||
# remove plot args
|
# remove plot args
|
||||||
|
|||||||
@ -231,6 +231,8 @@ limsType{T<:Real,S<:Real}(lims::@compat(Tuple{T,S})) = :limits
|
|||||||
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
||||||
limsType(lims) = :invalid
|
limsType(lims) = :invalid
|
||||||
|
|
||||||
|
axis_symbol(letter, postfix) = symbol(letter * postfix)
|
||||||
|
axis_symbols(letter, postfix...) = map(s -> axis_symbol(letter, s), postfix)
|
||||||
|
|
||||||
Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng]
|
Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng]
|
||||||
Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng]
|
Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user