1118 lines
39 KiB
Julia
1118 lines
39 KiB
Julia
|
||
|
||
const _allAxes = [:auto, :left, :right]
|
||
@compat const _axesAliases = KW(
|
||
:a => :auto,
|
||
:l => :left,
|
||
:r => :right
|
||
)
|
||
|
||
const _3dTypes = [:path3d, :scatter3d, :surface, :wireframe, :contour3d]
|
||
const _allTypes = vcat([
|
||
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||
:heatmap, :hexbin, :hist, :hist2d, :hist3d, :density, :bar, :hline, :vline, #:ohlc,
|
||
:contour, :pie, :shape, :image #, :boxplot, :violin, :quiver,
|
||
], _3dTypes)
|
||
@compat const _typeAliases = KW(
|
||
:n => :none,
|
||
:no => :none,
|
||
:l => :line,
|
||
:p => :path,
|
||
:stepinv => :steppre,
|
||
:stepsinv => :steppre,
|
||
:stepinverted => :steppre,
|
||
:stepsinverted => :steppre,
|
||
:step => :steppost,
|
||
:steps => :steppost,
|
||
:stair => :steppost,
|
||
:stairs => :steppost,
|
||
:stem => :sticks,
|
||
:stems => :sticks,
|
||
:dots => :scatter,
|
||
:histogram => :hist,
|
||
:pdf => :density,
|
||
:contours => :contour,
|
||
:line3d => :path3d,
|
||
:surf => :surface,
|
||
:wire => :wireframe,
|
||
:shapes => :shape,
|
||
:poly => :shape,
|
||
:polygon => :shape,
|
||
:box => :boxplot,
|
||
:velocity => :quiver,
|
||
:gradient => :quiver,
|
||
:img => :image,
|
||
:imshow => :image,
|
||
:imagesc => :image,
|
||
)
|
||
|
||
like_histogram(seriestype::Symbol) = seriestype in (:hist, :density)
|
||
like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :steppost)
|
||
like_surface(seriestype::Symbol) = seriestype in (:contour, :contour3d, :heatmap, :surface, :wireframe, :image)
|
||
|
||
is3d(seriestype::Symbol) = seriestype in _3dTypes
|
||
is3d(d::KW) = trueOrAllTrue(is3d, d[:seriestype])
|
||
|
||
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||
@compat const _styleAliases = KW(
|
||
:a => :auto,
|
||
:s => :solid,
|
||
:d => :dash,
|
||
:dd => :dashdot,
|
||
:ddd => :dashdotdot,
|
||
)
|
||
|
||
# const _allMarkers = [:none, :auto, :ellipse, :rect, :diamond, :utriangle, :dtriangle,
|
||
# :cross, :xcross, :star5, :star8, :hexagon, :octagon, Shape]
|
||
const _allMarkers = vcat(:none, :auto, sort(collect(keys(_shapes))))
|
||
@compat const _markerAliases = KW(
|
||
:n => :none,
|
||
:no => :none,
|
||
:a => :auto,
|
||
:circle => :ellipse,
|
||
:c => :ellipse,
|
||
:square => :rect,
|
||
:sq => :rect,
|
||
:r => :rect,
|
||
:d => :diamond,
|
||
:^ => :utriangle,
|
||
:ut => :utriangle,
|
||
:utri => :utriangle,
|
||
:uptri => :utriangle,
|
||
:uptriangle => :utriangle,
|
||
:v => :dtriangle,
|
||
:V => :dtriangle,
|
||
:dt => :dtriangle,
|
||
:dtri => :dtriangle,
|
||
:downtri => :dtriangle,
|
||
:downtriangle => :dtriangle,
|
||
:+ => :cross,
|
||
:plus => :cross,
|
||
:x => :xcross,
|
||
:X => :xcross,
|
||
:star => :star5,
|
||
:s => :star5,
|
||
:star1 => :star5,
|
||
:s2 => :star8,
|
||
:star2 => :star8,
|
||
:p => :pentagon,
|
||
:pent => :pentagon,
|
||
:h => :hexagon,
|
||
:hex => :hexagon,
|
||
:hep => :heptagon,
|
||
:o => :octagon,
|
||
:oct => :octagon,
|
||
:spike => :vline,
|
||
)
|
||
|
||
const _allScales = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
|
||
@compat const _scaleAliases = KW(
|
||
:none => :identity,
|
||
:log => :log10,
|
||
)
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
const _series_defaults = KW()
|
||
|
||
# series-specific
|
||
# _series_defaults[:axis] = :left
|
||
_series_defaults[:label] = "AUTO"
|
||
_series_defaults[:seriescolor] = :auto
|
||
_series_defaults[:seriesalpha] = nothing
|
||
_series_defaults[:seriestype] = :path
|
||
_series_defaults[:linestyle] = :solid
|
||
_series_defaults[:linewidth] = :auto
|
||
_series_defaults[:linecolor] = :match
|
||
_series_defaults[:linealpha] = nothing
|
||
_series_defaults[:fillrange] = nothing # ribbons, areas, etc
|
||
_series_defaults[:fillcolor] = :match
|
||
_series_defaults[:fillalpha] = nothing
|
||
_series_defaults[:markershape] = :none
|
||
_series_defaults[:markercolor] = :match
|
||
_series_defaults[:markeralpha] = nothing
|
||
_series_defaults[:markersize] = 6
|
||
_series_defaults[:markerstrokestyle] = :solid
|
||
_series_defaults[:markerstrokewidth] = 1
|
||
_series_defaults[:markerstrokecolor] = :match
|
||
_series_defaults[:markerstrokealpha] = nothing
|
||
_series_defaults[:bins] = 30 # number of bins for hists
|
||
_series_defaults[:smooth] = false # regression line?
|
||
_series_defaults[:group] = nothing # groupby vector
|
||
_series_defaults[:x] = nothing
|
||
_series_defaults[:y] = nothing
|
||
_series_defaults[:z] = nothing # depth for contour, surface, etc
|
||
_series_defaults[:marker_z] = nothing # value for color scale
|
||
_series_defaults[:levels] = 15
|
||
_series_defaults[:orientation] = :vertical
|
||
_series_defaults[:bar_position] = :overlay # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
|
||
_series_defaults[:bar_width] = 0.8
|
||
_series_defaults[:bar_edges] = false
|
||
_series_defaults[:xerror] = nothing
|
||
_series_defaults[:yerror] = nothing
|
||
_series_defaults[:ribbon] = nothing
|
||
_series_defaults[:quiver] = nothing
|
||
_series_defaults[:arrow] = nothing # allows for adding arrows to line/path... call `arrow(args...)`
|
||
_series_defaults[:normalize] = false # do we want a normalized histogram?
|
||
_series_defaults[:weights] = nothing # optional weights for histograms (1D and 2D)
|
||
_series_defaults[:contours] = false # add contours to 3d surface and wireframe plots
|
||
_series_defaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
|
||
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
|
||
_series_defaults[:subplot] = :auto # which subplot(s) does this series belong to?
|
||
_series_defaults[:series_annotations] = [] # a list of annotations which apply to the coordinates of this series
|
||
|
||
|
||
const _plot_defaults = KW()
|
||
|
||
_plot_defaults[:plot_title] = ""
|
||
_plot_defaults[:background_color] = colorant"white" # default for all backgrounds
|
||
_plot_defaults[:background_color_outside] = :match # background outside grid
|
||
_plot_defaults[:foreground_color] = :auto # default for all foregrounds, and title color
|
||
_plot_defaults[:size] = (600,400)
|
||
_plot_defaults[:pos] = (0,0)
|
||
_plot_defaults[:windowtitle] = "Plots.jl"
|
||
_plot_defaults[:show] = false
|
||
_plot_defaults[:layout] = 1
|
||
# _plot_defaults[:num_subplots] = -1
|
||
# _plot_defaults[:num_rows] = -1
|
||
# _plot_defaults[:num_cols] = -1
|
||
_plot_defaults[:link] = false
|
||
_plot_defaults[:linkx] = false
|
||
_plot_defaults[:linky] = false
|
||
_plot_defaults[:linkfunc] = nothing
|
||
_plot_defaults[:overwrite_figure] = true
|
||
|
||
|
||
const _subplot_defaults = KW()
|
||
|
||
_subplot_defaults[:title] = ""
|
||
_subplot_defaults[:title_location] = :center # also :left or :right
|
||
_subplot_defaults[:titlefont] = font(14)
|
||
_subplot_defaults[:background_color_subplot] = :match # default for other bg colors... match takes plot default
|
||
_subplot_defaults[:background_color_legend] = :match # background of legend
|
||
_subplot_defaults[:background_color_inside] = :match # background inside grid
|
||
_subplot_defaults[:foreground_color_subplot] = :match # default for other fg colors... match takes plot default
|
||
_subplot_defaults[:foreground_color_legend] = :match # foreground of legend
|
||
_subplot_defaults[:foreground_color_grid] = :match # grid color
|
||
_subplot_defaults[:foreground_color_title] = :match # title color
|
||
_subplot_defaults[:color_palette] = :auto
|
||
_subplot_defaults[:legend] = :best
|
||
_subplot_defaults[:colorbar] = :legend
|
||
_subplot_defaults[:legendfont] = font(8)
|
||
_subplot_defaults[:grid] = true
|
||
_subplot_defaults[:annotations] = [] # annotation tuples... list of (x,y,annotation)
|
||
# _subplot_defaults[:polar] = false
|
||
_subplot_defaults[:projection] = :none # can also be :polar or :3d
|
||
_subplot_defaults[:aspect_ratio] = :none # choose from :none or :equal
|
||
|
||
const _axis_defaults = KW()
|
||
|
||
_axis_defaults[:guide] = ""
|
||
_axis_defaults[:lims] = :auto
|
||
_axis_defaults[:ticks] = :auto
|
||
_axis_defaults[:scale] = :identity
|
||
_axis_defaults[:rotation] = 0
|
||
_axis_defaults[:flip] = false
|
||
_axis_defaults[:tickfont] = font(8)
|
||
_axis_defaults[:guidefont] = font(11)
|
||
_axis_defaults[:foreground_color_axis] = :match # axis border/tick colors
|
||
_axis_defaults[:foreground_color_border] = :match # plot area border/spines
|
||
_axis_defaults[:foreground_color_text] = :match # tick text color
|
||
_axis_defaults[:foreground_color_guide] = :match # guide text color
|
||
|
||
# add defaults for the letter versions
|
||
const _axis_defaults_byletter = KW()
|
||
for letter in (:x,:y,:z)
|
||
for k in (:guide,
|
||
:lims,
|
||
:ticks,
|
||
:scale,
|
||
:rotation,
|
||
:flip,
|
||
:tickfont,
|
||
:guidefont,
|
||
:foreground_color_axis,
|
||
:foreground_color_border,
|
||
:foreground_color_text,
|
||
:foreground_color_guide)
|
||
_axis_defaults_byletter[symbol(letter,k)] = nothing
|
||
end
|
||
end
|
||
# @show _axis_defaults
|
||
# for letter in (:x, :y, :z)
|
||
# for (k,v) in _axis_defaults
|
||
# _axis_defaults[symbol(letter,k)] = v
|
||
# end
|
||
# end
|
||
|
||
const _all_defaults = KW[
|
||
_series_defaults,
|
||
_plot_defaults,
|
||
_subplot_defaults,
|
||
_axis_defaults_byletter
|
||
]
|
||
|
||
const _all_args = sort(collect(union(map(keys, _all_defaults)...)))
|
||
supportedArgs(::AbstractBackend) = error("supportedArgs not defined") #_all_args
|
||
supportedArgs() = supportedArgs(backend())
|
||
|
||
RecipesBase.is_key_supported(k::Symbol) = (k in supportedArgs())
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
makeplural(s::Symbol) = symbol(string(s,"s"))
|
||
|
||
autopick(arr::AVec, idx::Integer) = arr[mod1(idx,length(arr))]
|
||
autopick(notarr, idx::Integer) = notarr
|
||
|
||
autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx)
|
||
autopick_ignore_none_auto(notarr, idx::Integer) = notarr
|
||
|
||
function aliasesAndAutopick(d::KW, sym::Symbol, aliases::KW, options::AVec, plotIndex::Int)
|
||
if d[sym] == :auto
|
||
d[sym] = autopick_ignore_none_auto(options, plotIndex)
|
||
elseif haskey(aliases, d[sym])
|
||
d[sym] = aliases[d[sym]]
|
||
end
|
||
end
|
||
|
||
function aliases(aliasMap::KW, val)
|
||
sortedkeys(filter((k,v)-> v==val, aliasMap))
|
||
end
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
const _keyAliases = KW()
|
||
|
||
function add_aliases(sym::Symbol, aliases::Symbol...)
|
||
for alias in aliases
|
||
if haskey(_keyAliases, alias)
|
||
error("Already an alias $alias => $(_keyAliases[alias])... can't also alias $sym")
|
||
end
|
||
_keyAliases[alias] = sym
|
||
end
|
||
end
|
||
|
||
# colors
|
||
add_aliases(:seriescolor, :c, :color, :colour)
|
||
add_aliases(:linecolor, :lc, :lcolor, :lcolour, :linecolour)
|
||
add_aliases(:markercolor, :mc, :mcolor, :mcolour, :markercolour)
|
||
add_aliases(:markerstokecolor, :msc, :mscolor, :mscolour, :markerstokecolour)
|
||
add_aliases(:fillcolor, :fc, :fcolor, :fcolour, :fillcolour)
|
||
|
||
add_aliases(:background_color, :bg, :bgcolor, :bg_color, :background,
|
||
:background_colour, :bgcolour, :bg_colour)
|
||
add_aliases(:background_color_legend, :bg_legend, :bglegend, :bgcolor_legend, :bg_color_legend, :background_legend,
|
||
:background_colour_legend, :bgcolour_legend, :bg_colour_legend)
|
||
add_aliases(:background_color_inside, :bg_inside, :bginside, :bgcolor_inside, :bg_color_inside, :background_inside,
|
||
:background_colour_inside, :bgcolour_inside, :bg_colour_inside)
|
||
add_aliases(:background_color_outside, :bg_outside, :bgoutside, :bgcolor_outside, :bg_color_outside, :background_outside,
|
||
:background_colour_outside, :bgcolour_outside, :bg_colour_outside)
|
||
add_aliases(:foreground_color, :fg, :fgcolor, :fg_color, :foreground,
|
||
:foreground_colour, :fgcolour, :fg_colour)
|
||
add_aliases(:foreground_color_legend, :fg_legend, :fglegend, :fgcolor_legend, :fg_color_legend, :foreground_legend,
|
||
:foreground_colour_legend, :fgcolour_legend, :fg_colour_legend)
|
||
add_aliases(:foreground_color_grid, :fg_grid, :fggrid, :fgcolor_grid, :fg_color_grid, :foreground_grid,
|
||
:foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor)
|
||
add_aliases(:foreground_color_title, :fg_title, :fgtitle, :fgcolor_title, :fg_color_title, :foreground_title,
|
||
:foreground_colour_title, :fgcolour_title, :fg_colour_title, :titlecolor)
|
||
add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis,
|
||
:foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor)
|
||
add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border,
|
||
:foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border)
|
||
add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text,
|
||
:foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor)
|
||
add_aliases(:foreground_color_guide, :fg_guide, :fgguide, :fgcolor_guide, :fg_color_guide, :foreground_guide,
|
||
:foreground_colour_guide, :fgcolour_guide, :fg_colour_guide, :guidecolor)
|
||
|
||
# alphas
|
||
add_aliases(:seriesalpha, :alpha, :α, :opacity)
|
||
add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity)
|
||
add_aliases(:makeralpha, :ma, :malpha, :mα, :makeropacity, :mopacity)
|
||
add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity)
|
||
add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity)
|
||
|
||
# series attributes
|
||
add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt)
|
||
add_aliases(:label, :lab)
|
||
add_aliases(:line, :l)
|
||
add_aliases(:linewidth, :w, :width, :lw)
|
||
add_aliases(:linestyle, :style, :s, :ls)
|
||
add_aliases(:marker, :m, :mark)
|
||
add_aliases(:markershape, :shape)
|
||
add_aliases(:markersize, :ms, :msize)
|
||
add_aliases(:marker_z, :markerz, :zcolor)
|
||
add_aliases(:fill, :f, :area)
|
||
add_aliases(:fillrange, :fillrng, :frange, :fillto, :fill_between)
|
||
add_aliases(:group, :g, :grouping)
|
||
add_aliases(:bins, :bin, :nbin, :nbins, :nb)
|
||
add_aliases(:ribbon, :rib)
|
||
add_aliases(:annotations, :ann, :anns, :annotate, :annotation)
|
||
add_aliases(:xguide, :xlabel, :xlab, :xl)
|
||
add_aliases(:xlims, :xlim, :xlimit, :xlimits)
|
||
add_aliases(:xticks, :xtick)
|
||
add_aliases(:xrotation, :xrot, :xr)
|
||
add_aliases(:yguide, :ylabel, :ylab, :yl)
|
||
add_aliases(:ylims, :ylim, :ylimit, :ylimits)
|
||
add_aliases(:yticks, :ytick)
|
||
# add_aliases(:yrightlabel, :yrlab, :yrl, :ylabel2, :y2label, :ylab2, :y2lab, :ylabr, :ylabelright)
|
||
# add_aliases(:yrightlims, :yrlim, :yrlimit, :yrlimits)
|
||
# add_aliases(:yrightticks, :yrtick)
|
||
add_aliases(:yrotation, :yrot, :yr)
|
||
add_aliases(:zguide, :zlabel, :zlab, :zl)
|
||
add_aliases(:zlims, :zlim, :zlimit, :zlimits)
|
||
add_aliases(:zticks, :ztick)
|
||
add_aliases(:zrotation, :zrot, :zr)
|
||
add_aliases(:legend, :leg, :key)
|
||
add_aliases(:colorbar, :cb, :cbar, :colorkey)
|
||
add_aliases(:smooth, :regression, :reg)
|
||
add_aliases(:levels, :nlevels, :nlev, :levs)
|
||
add_aliases(:size, :windowsize, :wsize)
|
||
add_aliases(:windowtitle, :wtitle)
|
||
add_aliases(:show, :gui, :display)
|
||
add_aliases(:color_palette, :palette)
|
||
add_aliases(:linkx, :xlink)
|
||
add_aliases(:linky, :ylink)
|
||
# add_aliases(:num_subplots, :n, :numplots, :nplts)
|
||
# add_aliases(:num_rows, :nr, :nrow, :nrows, :rows)
|
||
# add_aliases(:num_cols, :nc, :ncol, :ncols, :cols, :ncolumns, :columns)
|
||
add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse)
|
||
add_aliases(:xerror, :xerr, :xerrorbar)
|
||
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar)
|
||
add_aliases(:quiver, :velocity, :quiver2d, :gradient)
|
||
add_aliases(:normalize, :norm, :normed, :normalized)
|
||
add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio)
|
||
add_aliases(:match_dimensions, :transpose, :transpose_z)
|
||
add_aliases(:subplot, :sp, :subplt, :splt)
|
||
add_aliases(:projection, :proj)
|
||
add_aliases(:title_location, :title_loc, :titleloc)
|
||
add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesanns, :series_annotation)
|
||
|
||
|
||
# add all pluralized forms to the _keyAliases dict
|
||
for arg in keys(_series_defaults)
|
||
_keyAliases[makeplural(arg)] = arg
|
||
end
|
||
|
||
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
# update the defaults globally
|
||
|
||
"""
|
||
`default(key)` returns the current default value for that key
|
||
`default(key, value)` sets the current default value for that key
|
||
`default(; kw...)` will set the current default value for each key/value pair
|
||
"""
|
||
|
||
function default(k::Symbol)
|
||
k = get(_keyAliases, k, k)
|
||
for defaults in _all_defaults
|
||
if haskey(defaults, k)
|
||
return defaults[k]
|
||
end
|
||
end
|
||
error("Unknown key: ", k)
|
||
# if haskey(_series_defaults, k)
|
||
# return _series_defaults[k]
|
||
# elseif haskey(_plot_defaults, k)
|
||
# return _plot_defaults[k]
|
||
# else
|
||
# error("Unknown key: ", k)
|
||
# end
|
||
end
|
||
|
||
function default(k::Symbol, v)
|
||
k = get(_keyAliases, k, k)
|
||
for defaults in _all_defaults
|
||
if haskey(defaults, k)
|
||
defaults[k] = v
|
||
return v
|
||
end
|
||
end
|
||
error("Unknown key: ", k)
|
||
# if haskey(_series_defaults, k)
|
||
# _series_defaults[k] = v
|
||
# elseif haskey(_plot_defaults, k)
|
||
# _plot_defaults[k] = v
|
||
# else
|
||
# error("Unknown key: ", k)
|
||
# end
|
||
end
|
||
|
||
function default(; kw...)
|
||
for (k,v) in kw
|
||
default(k, v)
|
||
end
|
||
end
|
||
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
# if arg is a valid color value, then set d[csym] and return true
|
||
function handleColors!(d::KW, arg, csym::Symbol)
|
||
try
|
||
if arg == :auto
|
||
d[csym] = :auto
|
||
else
|
||
c = colorscheme(arg)
|
||
d[csym] = c
|
||
end
|
||
return true
|
||
end
|
||
false
|
||
end
|
||
|
||
# # 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::KW, letter::AbstractString, arg)
|
||
# T = typeof(arg)
|
||
# arg = get(_scaleAliases, arg, arg)
|
||
# scale, flip, label, lim, tick = axis_symbols(letter, "scale", "flip", "label", "lims", "ticks")
|
||
#
|
||
# if typeof(arg) <: Font
|
||
# d[:tickfont] = arg
|
||
#
|
||
# elseif arg in _allScales
|
||
# d[scale] = arg
|
||
#
|
||
# elseif arg in (:flip, :invert, :inverted)
|
||
# d[flip] = true
|
||
#
|
||
# elseif T <: @compat(AbstractString)
|
||
# d[label] = arg
|
||
#
|
||
# # xlims/ylims
|
||
# elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
||
# d[typeof(arg[1]) <: Number ? lim : tick] = arg
|
||
#
|
||
# # xticks/yticks
|
||
# elseif T <: AVec
|
||
# d[tick] = arg
|
||
#
|
||
# elseif arg == nothing
|
||
# d[tick] = []
|
||
#
|
||
# else
|
||
# warn("Skipped $(letter)axis arg $arg")
|
||
#
|
||
# end
|
||
# end
|
||
|
||
|
||
function processLineArg(d::KW, arg)
|
||
# seriestype
|
||
if allLineTypes(arg)
|
||
d[:seriestype] = arg
|
||
|
||
# linestyle
|
||
elseif allStyles(arg)
|
||
d[:linestyle] = arg
|
||
|
||
elseif typeof(arg) <: Stroke
|
||
arg.width == nothing || (d[:linewidth] = arg.width)
|
||
arg.color == nothing || (d[:linecolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||
arg.alpha == nothing || (d[:linealpha] = arg.alpha)
|
||
arg.style == nothing || (d[:linestyle] = arg.style)
|
||
|
||
elseif 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)
|
||
|
||
elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows)
|
||
d[:arrow] = arg
|
||
|
||
# linealpha
|
||
elseif allAlphas(arg)
|
||
d[:linealpha] = arg
|
||
|
||
# linewidth
|
||
elseif allReals(arg)
|
||
d[:linewidth] = arg
|
||
|
||
# color
|
||
elseif !handleColors!(d, arg, :linecolor)
|
||
warn("Skipped line arg $arg.")
|
||
|
||
end
|
||
end
|
||
|
||
|
||
function processMarkerArg(d::KW, arg)
|
||
# markershape
|
||
if allShapes(arg)
|
||
d[:markershape] = arg
|
||
|
||
# stroke style
|
||
elseif allStyles(arg)
|
||
d[:markerstrokestyle] = arg
|
||
|
||
elseif typeof(arg) <: Stroke
|
||
arg.width == nothing || (d[:markerstrokewidth] = arg.width)
|
||
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)
|
||
|
||
elseif typeof(arg) <: Brush
|
||
arg.size == nothing || (d[:markersize] = arg.size)
|
||
arg.color == nothing || (d[:markercolor] = arg.color == :auto ? :auto : colorscheme(arg.color))
|
||
arg.alpha == nothing || (d[:markeralpha] = arg.alpha)
|
||
|
||
# linealpha
|
||
elseif allAlphas(arg)
|
||
d[:markeralpha] = arg
|
||
|
||
# markersize
|
||
elseif allReals(arg)
|
||
d[:markersize] = arg
|
||
|
||
# markercolor
|
||
elseif !handleColors!(d, arg, :markercolor)
|
||
warn("Skipped marker arg $arg.")
|
||
|
||
end
|
||
end
|
||
|
||
|
||
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)
|
||
|
||
# fillrange function
|
||
elseif allFunctions(arg)
|
||
d[:fillrange] = arg
|
||
|
||
# fillalpha
|
||
elseif allAlphas(arg)
|
||
d[:fillalpha] = arg
|
||
|
||
elseif !handleColors!(d, arg, :fillcolor)
|
||
|
||
d[:fillrange] = arg
|
||
end
|
||
end
|
||
|
||
_replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape)
|
||
_replace_markershape(shapes::AVec) = map(_replace_markershape, shapes)
|
||
_replace_markershape(shape) = shape
|
||
|
||
function _add_markershape(d::KW)
|
||
# add the markershape if it needs to be added... hack to allow "m=10" to add a shape,
|
||
# and still allow overriding in _apply_recipe
|
||
ms = pop!(d, :markershape_to_add, :none)
|
||
if !haskey(d, :markershape) && ms != :none
|
||
d[:markershape] = ms
|
||
end
|
||
end
|
||
|
||
"Handle all preprocessing of args... break out colors/sizes/etc and replace aliases."
|
||
function preprocessArgs!(d::KW)
|
||
replaceAliases!(d, _keyAliases)
|
||
|
||
# # handle axis args
|
||
# for letter in ("x", "y", "z")
|
||
# asym = symbol(letter * "axis")
|
||
# for arg in wraptuple(pop!(d, asym, ()))
|
||
# processAxisArg(d, letter, arg)
|
||
# end
|
||
# # delete!(d, asym)
|
||
#
|
||
# # # NOTE: this logic was moved to _add_plotargs...
|
||
# # # 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
|
||
# #
|
||
# # ssym = symbol(letter * "scale")
|
||
# # if haskey(d, ssym) && haskey(_scaleAliases, d[ssym])
|
||
# # d[ssym] = _scaleAliases[d[ssym]]
|
||
# # end
|
||
# end
|
||
|
||
# # if title is just a single string, then assume we want plot_title
|
||
# # TODO: make a decision if this is correct
|
||
# if haskey(d, :title) && typeof(d[:title]) <: AbstractString
|
||
# d[:plot_title] = pop!(d, :title)
|
||
# end
|
||
|
||
# handle line args
|
||
for arg in wraptuple(pop!(d, :line, ()))
|
||
processLineArg(d, arg)
|
||
end
|
||
|
||
if haskey(d, :seriestype) && haskey(_typeAliases, d[:seriestype])
|
||
d[:seriestype] = _typeAliases[d[:seriestype]]
|
||
end
|
||
|
||
# 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
|
||
delete!(d, :marker)
|
||
if haskey(d, :markershape)
|
||
d[:markershape] = _replace_markershape(d[:markershape])
|
||
elseif anymarker
|
||
d[:markershape_to_add] = :ellipse # add it after _apply_recipe
|
||
end
|
||
|
||
# handle fill
|
||
for arg in wraptuple(get(d, :fill, ()))
|
||
processFillArg(d, arg)
|
||
end
|
||
delete!(d, :fill)
|
||
|
||
# convert into strokes and brushes
|
||
|
||
if haskey(d, :arrow)
|
||
a = d[:arrow]
|
||
d[:arrow] = if a == true
|
||
arrow()
|
||
elseif a == false
|
||
nothing
|
||
elseif !(typeof(a) <: Arrow)
|
||
arrow(wraptuple(a)...)
|
||
else
|
||
a
|
||
end
|
||
end
|
||
|
||
|
||
if get(d, :arrow, false) == true
|
||
d[:arrow] = arrow()
|
||
end
|
||
|
||
# legends
|
||
if haskey(d, :legend)
|
||
d[:legend] = convertLegendValue(d[:legend])
|
||
end
|
||
if haskey(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
|
||
delete!(d, :link)
|
||
end
|
||
|
||
# # pull out invalid keywords into their own KW dict... these are likely user-defined through recipes
|
||
# kw = KW()
|
||
# for k in keys(d)
|
||
# try
|
||
# # this should error for invalid keywords (assume they are user-defined)
|
||
# k == :markershape_to_add || default(k)
|
||
# catch
|
||
# # not a valid key... pop and add to user list
|
||
# kw[k] = pop!(d, k)
|
||
# end
|
||
# end
|
||
# kw
|
||
end
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
"A special type that will break up incoming data into groups, and allow for easier creation of grouped plots"
|
||
type GroupBy
|
||
groupLabels::Vector{UTF8String} # length == numGroups
|
||
groupIds::Vector{Vector{Int}} # list of indices for each group
|
||
end
|
||
|
||
|
||
# this is when given a vector-type of values to group by
|
||
function extractGroupArgs(v::AVec, args...)
|
||
groupLabels = sort(collect(unique(v)))
|
||
n = length(groupLabels)
|
||
if n > 20
|
||
warn("You created n=$n groups... Is that intended?")
|
||
end
|
||
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels]
|
||
GroupBy(map(string, groupLabels), groupIds)
|
||
end
|
||
|
||
|
||
# expecting a mapping of "group label" to "group indices"
|
||
function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...)
|
||
groupLabels = sortedkeys(idxmap)
|
||
groupIds = VecI[collect(idxmap[k]) for k in groupLabels]
|
||
GroupBy(groupLabels, groupIds)
|
||
end
|
||
|
||
filter_data(v::AVec, idxfilter::AVec{Int}) = v[idxfilter]
|
||
filter_data(v, idxfilter) = v
|
||
|
||
function filter_data!(d::KW, idxfilter)
|
||
for s in (:x, :y, :z)
|
||
d[s] = filter_data(get(d, s, nothing), idxfilter)
|
||
end
|
||
end
|
||
|
||
function _filter_input_data!(d::KW)
|
||
idxfilter = pop!(d, :idxfilter, nothing)
|
||
if idxfilter != nothing
|
||
filter_data!(d, idxfilter)
|
||
end
|
||
end
|
||
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
function warnOnUnsupportedArgs(pkg::AbstractBackend, d::KW)
|
||
for k in sortedkeys(d)
|
||
if (!(k in supportedArgs(pkg))
|
||
# && k != :subplot
|
||
&& d[k] != default(k))
|
||
warn("Keyword argument $k not supported with $pkg. Choose from: $(supportedArgs(pkg))")
|
||
end
|
||
end
|
||
end
|
||
|
||
_markershape_supported(pkg::AbstractBackend, shape::Symbol) = shape in supportedMarkers(pkg)
|
||
_markershape_supported(pkg::AbstractBackend, shape::Shape) = Shape in supportedMarkers(pkg)
|
||
_markershape_supported(pkg::AbstractBackend, shapes::AVec) = all([_markershape_supported(pkg, shape) for shape in shapes])
|
||
|
||
function warnOnUnsupported(pkg::AbstractBackend, d::KW)
|
||
# (d[:axis] in supportedAxes(pkg)
|
||
# || warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))"))
|
||
(d[:seriestype] == :none
|
||
|| d[:seriestype] in supportedTypes(pkg)
|
||
|| warn("seriestype $(d[:seriestype]) 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[:markershape] == :none
|
||
|| _markershape_supported(pkg, d[:markershape])
|
||
|| warn("markershape $(d[:markershape]) is unsupported with $pkg. Choose from: $(supportedMarkers(pkg))"))
|
||
end
|
||
|
||
function warnOnUnsupportedScales(pkg::AbstractBackend, d::KW)
|
||
for k in (:xscale, :yscale)
|
||
if haskey(d, k)
|
||
d[k] in supportedScales(pkg) || warn("scale $(d[k]) is unsupported with $pkg. Choose from: $(supportedScales(pkg))")
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
|
||
# # given an argument key (k), we want to extract the argument value for this index.
|
||
# # if nothing is set (rarg is empty), return the default.
|
||
# function setDictValue(d_in::KW, d_out::KW, k::Symbol, idx::Int, defaults::KW)
|
||
# if haskey(d_in, k) && !(typeof(d_in[k]) <: Union{AbstractMatrix, Tuple} && isempty(d_in[k]))
|
||
# d_out[k] = slice_arg(d_in[k], idx)
|
||
# else
|
||
# d_out[k] = deepcopy(defaults[k])
|
||
# end
|
||
# end
|
||
|
||
function convertLegendValue(val::Symbol)
|
||
if val in (:both, :all, :yes)
|
||
:best
|
||
elseif val in (:no, :none)
|
||
:none
|
||
elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend, :topright, :topleft, :bottomleft, :bottomright)
|
||
val
|
||
else
|
||
error("Invalid symbol for legend: $val")
|
||
end
|
||
end
|
||
convertLegendValue(val::Bool) = val ? :best : :none
|
||
|
||
# -----------------------------------------------------------------------------
|
||
|
||
# build the argument dictionary for the plot
|
||
# function getPlotArgs(pkg::AbstractBackend, kw, idx::Int; set_defaults = true)
|
||
# d_in = KW(kw)
|
||
# d_out = KW()
|
||
#
|
||
# # add defaults?
|
||
# if set_defaults
|
||
# for k in keys(_plot_defaults)
|
||
# setDictValue(d_in, d_out, k, idx, _plot_defaults)
|
||
# end
|
||
# end
|
||
#
|
||
# # handle legend/colorbar
|
||
# d_out[:legend] = convertLegendValue(d_out[:legend])
|
||
# d_out[:colorbar] = convertLegendValue(d_out[:colorbar])
|
||
# if d_out[:colorbar] == :legend
|
||
# d_out[:colorbar] = d_out[:legend]
|
||
# end
|
||
#
|
||
# # convert color
|
||
# handlePlotColors(pkg, d_out)
|
||
#
|
||
# # no need for these
|
||
# delete!(d_out, :x)
|
||
# delete!(d_out, :y)
|
||
#
|
||
# d_out
|
||
# end
|
||
|
||
# 1-row matrices will give an element
|
||
# multi-row matrices will give a column
|
||
# InputWrapper just gives the contents
|
||
# anything else is returned as-is
|
||
function slice_arg(v::AMat, idx::Int)
|
||
c = mod1(idx, size(v,2))
|
||
size(v,1) == 1 ? v[1,c] : v[:,c]
|
||
end
|
||
slice_arg(wrapper::InputWrapper, idx) = wrapper.obj
|
||
slice_arg(v, idx) = v
|
||
|
||
|
||
# given an argument key (k), we want to extract the argument value for this index.
|
||
# matrices are sliced by column, otherwise we
|
||
# if nothing is set (or container is empty), return the default or the existing value.
|
||
function slice_arg!(d_in::KW, d_out::KW, k::Symbol, default_value, idx::Int = 1; new_key::Symbol = k, remove_pair::Bool = true)
|
||
v = get(d_in, k, get(d_out, new_key, default_value))
|
||
d_out[new_key] = if haskey(d_in, k) && typeof(v) <: AMat && !isempty(v)
|
||
slice_arg(v, idx)
|
||
else
|
||
v
|
||
end
|
||
if remove_pair
|
||
delete!(d_in, k)
|
||
end
|
||
end
|
||
|
||
# if the value is `:match` then we take whatever match_color is.
|
||
# this is mainly used for cascading defaults for foreground and background colors
|
||
function color_or_match!(d::KW, k::Symbol, match_color)
|
||
v = d[k]
|
||
d[k] = if v == :match
|
||
match_color
|
||
elseif v == nothing
|
||
colorscheme(RGBA(0,0,0,0))
|
||
else
|
||
v
|
||
end
|
||
end
|
||
|
||
|
||
# update plotargs from an input dictionary
|
||
function _update_plot_args(plt::Plot, d_in::KW)
|
||
pargs = plt.plotargs
|
||
for (k,v) in _plot_defaults
|
||
slice_arg!(d_in, pargs, k, v)
|
||
end
|
||
|
||
# handle colors
|
||
bg = convertColor(pargs[:background_color])
|
||
fg = pargs[:foreground_color]
|
||
if fg == :auto
|
||
fg = isdark(bg) ? colorant"white" : colorant"black"
|
||
end
|
||
pargs[:background_color] = bg
|
||
pargs[:foreground_color] = convertColor(fg)
|
||
color_or_match!(pargs, :background_color_outside, bg)
|
||
end
|
||
|
||
|
||
# update a subplots args and axes
|
||
function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::Integer)
|
||
pargs = plt.plotargs
|
||
spargs = sp.attr
|
||
# @show subplot_index, sp
|
||
for (k,v) in _subplot_defaults
|
||
slice_arg!(d_in, spargs, k, v, subplot_index)
|
||
end
|
||
|
||
# handle legend/colorbar
|
||
spargs[:legend] = convertLegendValue(spargs[:legend])
|
||
spargs[:colorbar] = convertLegendValue(spargs[:colorbar])
|
||
if spargs[:colorbar] == :legend
|
||
spargs[:colorbar] = spargs[:legend]
|
||
end
|
||
|
||
# background colors
|
||
bg = color_or_match!(spargs, :background_color_subplot, pargs[:background_color])
|
||
spargs[:color_palette] = get_color_palette(spargs[:color_palette], bg, 30)
|
||
color_or_match!(spargs, :background_color_legend, bg)
|
||
color_or_match!(spargs, :background_color_inside, bg)
|
||
|
||
# foreground colors
|
||
fg = color_or_match!(spargs, :foreground_color_subplot, pargs[:foreground_color])
|
||
color_or_match!(spargs, :foreground_color_legend, fg)
|
||
color_or_match!(spargs, :foreground_color_grid, fg)
|
||
color_or_match!(spargs, :foreground_color_title, fg)
|
||
|
||
# info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||
# DD(spargs, "before loop")
|
||
|
||
for letter in (:x, :y, :z)
|
||
# get (maybe initialize) the axis
|
||
axissym = symbol(letter, :axis)
|
||
axis = if haskey(spargs, axissym)
|
||
spargs[axissym]
|
||
else
|
||
spargs[axissym] = Axis(letter)
|
||
end
|
||
|
||
# grab magic args (for example `xaxis = (:flip, :log)`)
|
||
args = wraptuple(get(d_in, axissym, ()))
|
||
|
||
# build the KW of arguments from the letter version (i.e. xticks --> ticks)
|
||
kw = KW()
|
||
# DD(d_in, "d_in before")
|
||
|
||
for (k,v) in _axis_defaults
|
||
# first get the args without the letter: `tickfont = font(10)`
|
||
# note: we don't pop because we want this to apply to all axes! (delete after all have finished)
|
||
if haskey(d_in, k)
|
||
kw[k] = slice_arg(d_in[k], subplot_index)
|
||
end
|
||
|
||
# then get those args that were passed with a leading letter: `xlabel = "X"`
|
||
lk = symbol(letter, k)
|
||
if haskey(d_in, lk)
|
||
kw[k] = slice_arg(pop!(d_in, lk), subplot_index)
|
||
end
|
||
end
|
||
|
||
# for (k,v) in _axis_defaults
|
||
# # first get the args without the letter: `tickfont = font(10)`
|
||
# slice_arg!(d_in, kw, k, v, subplot_index)
|
||
#
|
||
# # then get those args that were passed with a leading letter: `xlabel = "X"`
|
||
# lk = symbol(letter, k)
|
||
# slice_arg!(d_in, kw, lk, v, subplot_index; new_key = k)
|
||
# # if haskey(d_in, lk)
|
||
# # kw[k] = d_in[lk]
|
||
# # end
|
||
# end
|
||
# DD(d_in, "d_in after")
|
||
# DD(kw, "kw")
|
||
|
||
# update the axis
|
||
# @show args,kw
|
||
update!(axis, args...; kw...)
|
||
|
||
# update the axis colors
|
||
color_or_match!(axis.d, :foreground_color_axis, fg)
|
||
color_or_match!(axis.d, :foreground_color_border, fg)
|
||
color_or_match!(axis.d, :foreground_color_guide, fg)
|
||
color_or_match!(axis.d, :foreground_color_text, fg)
|
||
# DD(axis.d, "axis")
|
||
end
|
||
|
||
# now we can get rid of the axis keys without a letter
|
||
for k in keys(_axis_defaults)
|
||
delete!(d_in, k)
|
||
end
|
||
|
||
# DD(spargs[:xaxis].d, "after loop")
|
||
# info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
|
||
end
|
||
|
||
|
||
function has_black_border_for_default(st::Symbol)
|
||
like_histogram(st) || st in (:hexbin, :bar)
|
||
end
|
||
#
|
||
# # 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
|
||
# kwdict = KW(kw)
|
||
# d = KW()
|
||
#
|
||
# # add defaults?
|
||
# for k in keys(_series_defaults)
|
||
# setDictValue(kwdict, d, k, commandIndex, _series_defaults)
|
||
# end
|
||
#
|
||
# # groupby args?
|
||
# for k in (:idxfilter, :numUncounted, :dataframe)
|
||
# if haskey(kwdict, k)
|
||
# d[k] = kwdict[k]
|
||
# end
|
||
# end
|
||
#
|
||
# if haskey(_typeAliases, d[:seriestype])
|
||
# d[:seriestype] = _typeAliases[d[:seriestype]]
|
||
# end
|
||
#
|
||
# aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
|
||
# aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
|
||
# aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
|
||
#
|
||
# # update color
|
||
# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex)
|
||
#
|
||
# # # update linecolor
|
||
# # c = d[:linecolor]
|
||
# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||
# # d[:linecolor] = c
|
||
#
|
||
# # # update markercolor
|
||
# # c = d[:markercolor]
|
||
# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||
# # d[:markercolor] = c
|
||
#
|
||
# # # update fillcolor
|
||
# # c = d[:fillcolor]
|
||
# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||
# # d[:fillcolor] = c
|
||
#
|
||
# # update colors
|
||
# for csym in (:linecolor, :markercolor, :fillcolor)
|
||
# d[csym] = if d[csym] == :match
|
||
# if has_black_border_for_default(d[:seriestype]) && csym == :linecolor
|
||
# :black
|
||
# else
|
||
# d[:seriescolor]
|
||
# end
|
||
# else
|
||
# getSeriesRGBColor(d[csym], plotargs, plotIndex)
|
||
# end
|
||
# end
|
||
#
|
||
# # update markerstrokecolor
|
||
# c = d[:markerstrokecolor]
|
||
# c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex))
|
||
# d[:markerstrokecolor] = c
|
||
#
|
||
# # update alphas
|
||
# for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha)
|
||
# if d[asym] == nothing
|
||
# d[asym] = d[:seriesalpha]
|
||
# end
|
||
# end
|
||
#
|
||
# # scatter plots don't have a line, but must have a shape
|
||
# if d[:seriestype] in (:scatter, :scatter3d)
|
||
# d[:linewidth] = 0
|
||
# if d[:markershape] == :none
|
||
# d[:markershape] = :ellipse
|
||
# end
|
||
# end
|
||
#
|
||
# # 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
|
||
# end
|