From dd434b89d2cc5105bbd2e74786e2cf47e72098a3 Mon Sep 17 00:00:00 2001 From: Will Grant Date: Wed, 11 Jul 2018 17:17:45 +1000 Subject: [PATCH] add minor grid and tick marks. Works, but doesn't extend beyond major ticks --- src/arg_desc.jl | 2 ++ src/args.jl | 2 ++ src/axes.jl | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 56e3719d..54c3ed48 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -139,6 +139,8 @@ const _arg_desc = KW( :gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.", :gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", :gridlinewidth => "Number. Width of the grid lines (in pixels)", +:minorgrid => "Bool. Add minor grid lines in the same style as the major grid lines. Set minorticks to change number of gridlines", +:minorticks => "Integer. Intervals to divide the gap between major ticks into", :tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`", :showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`", :widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.", diff --git a/src/args.jl b/src/args.jl index 671485d0..69bdb8f4 100644 --- a/src/args.jl +++ b/src/args.jl @@ -381,6 +381,8 @@ const _axis_defaults = KW( :gridstyle => :solid, :gridlinewidth => 0.5, :tick_direction => :in, + :minorticks => false, + :minorgrid => false, :showaxis => true, :widen => true, ) diff --git a/src/axes.jl b/src/axes.jl index 1410b28b..12e989a1 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -286,6 +286,19 @@ _transform_ticks(ticks) = ticks _transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks) _transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2]) +function get_minor_ticks(axis,ticks) + axis[:minorticks] in (nothing, false) && !axis[:minorgrid] && return nothing + length(ticks[1]) < 2 && return nothing + amin, amax = axis_limits(axis) + #Default to 5 intervals between major ticks + n = typeof(axis[:minorticks]) <: Integer && axis[:minorticks] > 1 ? axis[:minorticks] : 5 + minorticks = typeof(ticks[1][1])[] + for (i,hi) in enumerate(ticks[1][2:end]) + lo = ticks[1][i] + append!(minorticks,collect(lo:(hi-lo)/n:hi)) + end + minorticks +end # ------------------------------------------------------------------------- @@ -562,12 +575,16 @@ function axis_drawing_info(sp::Subplot) ymin, ymax = axis_limits(yaxis) xticks = get_ticks(xaxis) yticks = get_ticks(yaxis) + xminorticks = get_minor_ticks(xaxis,xticks) + yminorticks = get_minor_ticks(yaxis,yticks) xaxis_segs = Segments(2) yaxis_segs = Segments(2) xtick_segs = Segments(2) ytick_segs = Segments(2) xgrid_segs = Segments(2) ygrid_segs = Segments(2) + xminorgrid_segs = Segments(2) + yminorgrid_segs = Segments(2) xborder_segs = Segments(2) yborder_segs = Segments(2) @@ -610,6 +627,28 @@ function axis_drawing_info(sp::Subplot) xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid end end + if !(xaxis[:minorticks] in (nothing, false)) || xaxis[:minorgrid] + f = scalefunc(yaxis[:scale]) + invf = invscalefunc(yaxis[:scale]) + ticks_in = xaxis[:tick_direction] == :out ? -1 : 1 + t1 = invf(f(ymin) + 0.01 * (f(ymax) - f(ymin)) * ticks_in) + t2 = invf(f(ymax) - 0.01 * (f(ymax) - f(ymin)) * ticks_in) + t3 = invf(f(0) + 0.01 * (f(ymax) - f(ymin)) * ticks_in) + + for xminortick in xminorticks + if xaxis[:showaxis] + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, t3) + else + xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1) + end + push!(xtick_segs, (xminortick, tick_start), (xminortick, tick_stop)) # bottom tick + end + # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick + xaxis[:minorgrid] && push!(xgrid_segs, (xminortick, ymin), (xminortick, ymax)) # vertical grid + end + end + # yaxis if yaxis[:showaxis] @@ -649,6 +688,27 @@ function axis_drawing_info(sp::Subplot) yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid end end + if !(yaxis[:minorticks] in (nothing, false)) || yaxis[:minorgrid] + f = scalefunc(xaxis[:scale]) + invf = invscalefunc(xaxis[:scale]) + ticks_in = yaxis[:tick_direction] == :out ? -1 : 1 + t1 = invf(f(xmin) + 0.01 * (f(xmax) - f(xmin)) * ticks_in) + t2 = invf(f(xmax) - 0.01 * (f(xmax) - f(xmin)) * ticks_in) + t3 = invf(f(0) + 0.01 * (f(xmax) - f(xmin)) * ticks_in) + + for ytick in yminorticks + if yaxis[:showaxis] + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, t3) + else + xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1) + end + push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick + end + # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick + yaxis[:minorgrid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid + end + end end xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs