From bbb00816f1c0933db2ebc5c5b02bde45dbb265e7 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Tue, 26 Jul 2016 12:34:06 -0400 Subject: [PATCH] axis formatter --- src/arg_desc.jl | 1 + src/args.jl | 4 +++- src/axes.jl | 52 ++++++++++++++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 57e6dc15..ef0ab400 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -100,6 +100,7 @@ const _arg_desc = KW( :scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`", :rotation => "Number. Degrees rotation of tick labels.", :flip => "Bool. Should we flip (reverse) the axis?", +:formatter => "Function, :scientific, or :auto. A method which converts a number to a string for tick labeling.", :tickfont => "Font. Font of axis tick labels.", :guidefont => "Font. Font of axis guide (label).", :foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.", diff --git a/src/args.jl b/src/args.jl index acdd4448..b1d0412f 100644 --- a/src/args.jl +++ b/src/args.jl @@ -265,6 +265,7 @@ const _axis_defaults = KW( :foreground_color_text => :match, # tick text color, :foreground_color_guide => :match, # guide text color, :discrete_values => [], + :formatter => :auto, ) const _suppress_warnings = Set{Symbol}([ @@ -298,7 +299,8 @@ for letter in (:x,:y,:z) :foreground_color_border, :foreground_color_text, :foreground_color_guide, - :discrete_values + :discrete_values, + :formatter, ) _axis_defaults_byletter[Symbol(letter,k)] = :match diff --git a/src/axes.jl b/src/axes.jl index d101ace5..f5b6e46c 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -73,6 +73,9 @@ function process_axis_arg!(d::KW, arg, letter = "") elseif typeof(arg) <: Number d[Symbol(letter,:rotation)] = arg + elseif typeof(arg) <: Function + d[Symbol(letter,:formatter)] = arg + else warn("Skipped $(letter)axis arg $arg") @@ -129,6 +132,12 @@ const _inv_scale_funcs = Dict{Symbol,Function}( :ln => exp, ) +# const _label_func = Dict{Symbol,Function}( +# :log10 => x -> "10^$x", +# :log2 => x -> "2^$x", +# :ln => x -> "e^$x", +# ) + const _label_func = Dict{Symbol,Function}( :log10 => x -> "10^$x", :log2 => x -> "2^$x", @@ -141,41 +150,44 @@ invscalefunc(scale::Symbol) = x -> get(_inv_scale_funcs, scale, identity)(Float6 labelfunc(scale::Symbol, backend::AbstractBackend) = get(_label_func, scale, string) function optimal_ticks_and_labels(axis::Axis, ticks = nothing) - lims = axis_limits(axis) + amin,amax = axis_limits(axis) # scale the limits scale = axis[:scale] - scaled_lims = map(scalefunc(scale), lims) - # @show lims scaled_lims + sf = scalefunc(scale) # get a list of well-laid-out ticks - cv = if ticks == nothing - optimize_ticks(scaled_lims..., + scaled_ticks = if ticks == nothing + optimize_ticks( + sf(amin), + sf(amax); k_min = 5, # minimum number of ticks k_max = 8, # maximum number of ticks - # span_buffer = 0.0 # padding buffer in case nice ticks are closeby )[1] else - ticks + map(sf, ticks) end + unscaled_ticks = map(invscalefunc(scale), scaled_ticks) - # # expand to ensure we see all the ticks - # expand_extrema!(axis, cv) - - # rescale and return values and labels - # @show cv - ticklabels = if any(isfinite, cv) - map(labelfunc(scale, backend()), Showoff.showoff(cv, :plain)) + labels = if any(isfinite, unscaled_ticks) + formatter = axis[:formatter] + if formatter == :auto + # the default behavior is to make strings of the scaled values and then apply the labelfunc + map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain)) + elseif formatter == :scientific + Showoff.showoff(unscaled_ticks, :scientific) + else + # there was an override for the formatter... use that on the unscaled ticks + map(formatter, unscaled_ticks) + end else + # no finite ticks to show... String[] end - tickvals = map(invscalefunc(scale), cv) - # @show tickvals ticklabels - # ticklabels = Showoff.showoff(tickvals, scale == :log10 ? :scientific : :auto) - tickvals, ticklabels - # basestr = scale == :log10 ? "10^" : scale == :log2 ? "2^" : scale == :ln ? "e^" : "" - # tickvals, ["$basestr$cvi" for cvi in cv] + # @show unscaled_ticks labels + # labels = Showoff.showoff(unscaled_ticks, scale == :log10 ? :scientific : :auto) + unscaled_ticks, labels end # return (continuous_values, discrete_values) for the ticks on this axis