GR: rework automatic major/minor ticks for log scales
This commit is contained in:
parent
387f918080
commit
24bcda5e31
82
src/axes.jl
82
src/axes.jl
@ -136,6 +136,23 @@ const _label_func_tex = Dict{Symbol,Function}(
|
|||||||
)
|
)
|
||||||
labelfunc_tex(scale::Symbol) = get(_label_func_tex, scale, convert_sci_unicode)
|
labelfunc_tex(scale::Symbol) = get(_label_func_tex, scale, convert_sci_unicode)
|
||||||
|
|
||||||
|
function scaled_log_ticks(amin, amax, scale, max_ticks=8, strict=true)
|
||||||
|
base = _logScaleBases[scale]
|
||||||
|
log_amin = log(amin) / log(base)
|
||||||
|
log_amax = log(amax) / log(base)
|
||||||
|
|
||||||
|
# number of decades
|
||||||
|
num_decs = floor(Int, log_amax) - ceil(Int, log_amin)
|
||||||
|
step = max(1, min(round(Int, num_decs / max_ticks), num_decs))
|
||||||
|
|
||||||
|
start = (strict ? ceil : floor)(Int, log_amin)
|
||||||
|
stop = (strict ? floor : ceil)(Int, log_amax)
|
||||||
|
exponents = range(start, stop, step=step) |> collect
|
||||||
|
|
||||||
|
# majorticks = base .^ exponents
|
||||||
|
# return exponents, majorticks
|
||||||
|
return exponents
|
||||||
|
end
|
||||||
|
|
||||||
function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
||||||
amin, amax = alims
|
amin, amax = alims
|
||||||
@ -169,12 +186,16 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
|
|||||||
|
|
||||||
# get a list of well-laid-out ticks
|
# get a list of well-laid-out ticks
|
||||||
if ticks === nothing
|
if ticks === nothing
|
||||||
scaled_ticks = optimize_ticks(
|
if scale in _logScales
|
||||||
sf(amin),
|
scaled_ticks = scaled_log_ticks(amin, amax, scale)
|
||||||
sf(amax);
|
else
|
||||||
k_min = 4, # minimum number of ticks
|
scaled_ticks = optimize_ticks(
|
||||||
k_max = 8, # maximum number of ticks
|
sf(amin),
|
||||||
)[1]
|
sf(amax);
|
||||||
|
k_min = 4, # minimum number of ticks
|
||||||
|
k_max = 8, # maximum number of ticks
|
||||||
|
)[1]
|
||||||
|
end
|
||||||
elseif typeof(ticks) <: Int
|
elseif typeof(ticks) <: Int
|
||||||
scaled_ticks, viewmin, viewmax = optimize_ticks(
|
scaled_ticks, viewmin, viewmax = optimize_ticks(
|
||||||
sf(amin),
|
sf(amin),
|
||||||
@ -335,11 +356,12 @@ function get_minor_ticks(sp, axis, ticks)
|
|||||||
ticks = ticks[1]
|
ticks = ticks[1]
|
||||||
length(ticks) < 2 && return nothing
|
length(ticks) < 2 && return nothing
|
||||||
|
|
||||||
|
scale = axis[:scale]
|
||||||
amin, amax = axis_limits(sp, axis[:letter])
|
amin, amax = axis_limits(sp, axis[:letter])
|
||||||
#Add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
|
# Add one phantom tick either side of the ticks to ensure minor ticks extend to the axis limits
|
||||||
if length(ticks) > 2
|
if length(ticks) > 2
|
||||||
ratio = (ticks[3] - ticks[2])/(ticks[2] - ticks[1])
|
ratio = (ticks[3] - ticks[2])/(ticks[2] - ticks[1])
|
||||||
elseif axis[:scale] in (:none, :identity)
|
elseif scale in (:none, :identity)
|
||||||
ratio = 1
|
ratio = 1
|
||||||
else
|
else
|
||||||
return nothing
|
return nothing
|
||||||
@ -348,13 +370,33 @@ function get_minor_ticks(sp, axis, ticks)
|
|||||||
last_step = ticks[end] - ticks[end-1]
|
last_step = ticks[end] - ticks[end-1]
|
||||||
ticks = [ticks[1] - first_step/ratio; ticks; ticks[end] + last_step*ratio]
|
ticks = [ticks[1] - first_step/ratio; ticks; ticks[end] + last_step*ratio]
|
||||||
|
|
||||||
#Default to 5 intervals between major ticks
|
# Default to 5 intervals between major ticks on a linear scale,
|
||||||
n = typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] : 5
|
# base - 1 for integral based log scale and 0 for ℯ based log scale
|
||||||
|
integral_log = scale in (:log2, :log10)
|
||||||
|
base = scale in _logScales ? _logScaleBases[scale] : nothing
|
||||||
|
n_default = integral_log ? base - 1 : (scale == :ln ? 0 : 5)
|
||||||
|
n = typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] : n_default
|
||||||
minorticks = typeof(ticks[1])[]
|
minorticks = typeof(ticks[1])[]
|
||||||
for (i,hi) in enumerate(ticks[2:end])
|
|
||||||
lo = ticks[i]
|
if n > 0
|
||||||
if isfinite(lo) && isfinite(hi) && hi > lo
|
sub = integral_log ? round(Int, log(ratio) / log(base)) : nothing
|
||||||
append!(minorticks,collect(lo + (hi-lo)/n :(hi-lo)/n: hi - (hi-lo)/2n))
|
for (i,hi) in enumerate(ticks[2:end])
|
||||||
|
lo = ticks[i]
|
||||||
|
if isfinite(lo) && isfinite(hi) && hi > lo
|
||||||
|
if integral_log
|
||||||
|
for j in 1:sub
|
||||||
|
lo_ = lo * base^(j - 1)
|
||||||
|
hi_ = lo_ * base
|
||||||
|
step = (hi_ - lo_) / n
|
||||||
|
append!(minorticks, collect(
|
||||||
|
lo_ + (j > 1 ? 0 : step) : step : hi_ - (j < sub ? 0 : step / 2)
|
||||||
|
))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
step = (hi - lo) / n
|
||||||
|
append!(minorticks, collect(lo + step : step : hi - step / 2))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
minorticks[amin .<= minorticks .<= amax]
|
minorticks[amin .<= minorticks .<= amax]
|
||||||
@ -701,7 +743,7 @@ function axis_drawing_info(sp, letter)
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if !(ax[:ticks] in (:none, nothing, false))
|
if ax[:ticks] ∉ (:none, nothing, false)
|
||||||
f = RecipesPipeline.scale_func(oax[:scale])
|
f = RecipesPipeline.scale_func(oax[:scale])
|
||||||
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
|
invf = RecipesPipeline.inverse_scale_func(oax[:scale])
|
||||||
if ax[:tick_direction] !== :none
|
if ax[:tick_direction] !== :none
|
||||||
@ -732,7 +774,10 @@ function axis_drawing_info(sp, letter)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
|
if (
|
||||||
|
(ax[:minorticks] ∉ (:none, nothing, false) || ax[:minorgrid]) &&
|
||||||
|
minor_ticks !== nothing
|
||||||
|
)
|
||||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||||
t = invf(f(0) + 0.006 * (f(oamax) - f(oamin)))
|
t = invf(f(0) + 0.006 * (f(oamax) - f(oamin)))
|
||||||
(-t, t)
|
(-t, t)
|
||||||
@ -877,7 +922,10 @@ function axis_drawing_info_3d(sp, letter)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !(ax[:minorticks] in (:none, nothing, false)) || ax[:minorgrid]
|
if (
|
||||||
|
(ax[:minorticks] ∉ (:none, nothing, false) || ax[:minorgrid]) &&
|
||||||
|
minor_ticks !== nothing
|
||||||
|
)
|
||||||
tick_start, tick_stop = if sp[:framestyle] == :origin
|
tick_start, tick_stop = if sp[:framestyle] == :origin
|
||||||
t = invf(f(0) + 0.006 * (f(namax) - f(namin)))
|
t = invf(f(0) + 0.006 * (f(namax) - f(namin)))
|
||||||
(-t, t)
|
(-t, t)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user