From 5a2d39320f3cc499fd0b297886f96fe6e956e2d3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 16:13:01 +0200 Subject: [PATCH] framestyle attribute for gr, pyplot and glvisualize --- src/arg_desc.jl | 2 +- src/args.jl | 18 ++++++++++++++-- src/axes.jl | 42 +++++++++++++++++++++---------------- src/backends/glvisualize.jl | 13 ++++++++++-- src/backends/gr.jl | 20 ++++++++++++++---- src/backends/pyplot.jl | 36 +++++++++++++++++++++++-------- 6 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f3b56493..2aad42a5 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -93,7 +93,7 @@ const _arg_desc = KW( :bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.", :subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.", :colorbar_title => "String. Title of colorbar.", -:draw_axes_border => "Bool. Draw a border around the axes.", +:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)", # axis args :guide => "String. Axis guide (label).", diff --git a/src/args.jl b/src/args.jl index 5daf08e8..bc9ce5af 100644 --- a/src/args.jl +++ b/src/args.jl @@ -181,6 +181,14 @@ function hasgrid(arg::Symbol, letter) end hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) +const _allFramestyles = [:box, :semi, :axes, :grid, :none] +const _framestyleAliases = Dict{Symbol, Symbol}( + :frame => :box, + :border => :box, + :on => :box, + :transparent => :semi, + :semitransparent => :semi, +) # ----------------------------------------------------------------------------- const _series_defaults = KW( @@ -282,7 +290,7 @@ const _subplot_defaults = KW( :bottom_margin => :match, :subplot_index => -1, :colorbar_title => "", - :draw_axes_border => false, + :framestyle => :axes, ) const _axis_defaults = KW( @@ -494,7 +502,7 @@ add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) -add_aliases(:draw_axes_border, :axes_border, :show_axes_border, :box, :frame) +add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box) # add all pluralized forms to the _keyAliases dict @@ -721,6 +729,7 @@ function preprocessArgs!(d::KW) if haskey(d, :axis) && d[:axis] in (:none, nothing, false) d[:ticks] = nothing d[:foreground_color_border] = RGBA(0,0,0,0) + d[:foreground_color_axis] = RGBA(0,0,0,0) d[:grid] = false delete!(d, :axis) end @@ -823,6 +832,11 @@ function preprocessArgs!(d::KW) d[:colorbar] = convertLegendValue(d[:colorbar]) end + + if haskey(d, :framestyle) && haskey(_framestyleAliases, d[:framestyle]) + d[:framestyle] = _framestyleAliases[d[:framestyle]] + end + # warnings for moved recipes st = get(d, :seriestype, :path) if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots) diff --git a/src/axes.jl b/src/axes.jl index 22c868ff..6b3962a6 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -490,40 +490,46 @@ function axis_drawing_info(sp::Subplot) ymin, ymax = axis_limits(yaxis) xticks = get_ticks(xaxis) yticks = get_ticks(yaxis) - xspine_segs = Segments(2) - yspine_segs = Segments(2) + xaxis_segs = Segments(2) + yaxis_segs = Segments(2) xgrid_segs = Segments(2) ygrid_segs = Segments(2) + xborder_segs = Segments(2) + yborder_segs = Segments(2) - if !(xaxis[:ticks] in (nothing, false)) + if !(sp[:framestyle] == :none) + # xaxis f = scalefunc(yaxis[:scale]) invf = invscalefunc(yaxis[:scale]) t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - push!(xspine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine - sp[:draw_axes_border] && push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine - for xtick in xticks[1] - push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick - # sp[:draw_axes_border] && push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick - xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + sp[:framestyle] == :grid || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine + if !(xaxis[:ticks] in (nothing, false)) + for xtick in xticks[1] + push!(xaxis_segs, (xtick, ymin), (xtick, t1)) # bottom tick + # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick + xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + end end - end - if !(yaxis[:ticks] in (nothing, false)) + # yaxis f = scalefunc(xaxis[:scale]) invf = invscalefunc(xaxis[:scale]) t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - push!(yspine_segs, (xmin,ymin), (xmin,ymax)) # left spine - sp[:draw_axes_border] && push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine - for ytick in yticks[1] - push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick - # sp[:draw_axes_border] && push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick - yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + sp[:framestyle] == :grid || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine + if !(yaxis[:ticks] in (nothing, false)) + for ytick in yticks[1] + push!(yaxis_segs, (xmin, ytick), (t1, ytick)) # left tick + # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick + yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + end end end - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs + xticks, yticks, xaxis_segs, yaxis_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 91deb56c..1d4fc017 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -40,7 +40,7 @@ const _glvisualize_attr = merge_with_base_supported([ :inset_subplots, :dpi, :hover, - :draw_axes_border, + :framestyle, ]) const _glvisualize_seriestype = [ :path, :shape, @@ -678,7 +678,7 @@ function text_model(font, pivot) end end function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area) - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = Plots.axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp) xaxis = sp[:xaxis]; yaxis = sp[:yaxis] xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid])) @@ -728,6 +728,15 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) end + xbc = Colors.color(Plots.gl_color(xaxis[:foreground_color_border])) + ybc = Colors.color(Plots.gl_color(yaxis[:foreground_color_border])) + intensity = sp[:framestyle] == :semi ? 0.5f0 : 1.0f0 + if sp[:framestyle] in (:box, :semi) + xborder = draw_grid_lines(sp, xborder_segs, intensity, :solid, model, RGBA(xbc, intensity)) + yborder = draw_grid_lines(sp, yborder_segs, intensity, :solid, model, RGBA(ybc, intensity)) + push!(axis_vis, xborder, yborder) + end + area_w = GeometryTypes.widths(area) if sp[:title] != "" tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title]) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0c01b8f4..60e7df00 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -32,7 +32,7 @@ const _gr_attr = merge_with_base_supported([ :inset_subplots, :bar_width, :arrow, - :draw_axes_border, + :framestyle, ]) const _gr_seriestype = [ :path, :scatter, @@ -609,7 +609,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # TODO: can these be generic flags? outside_ticks = false cmap = false - draw_axes = true + draw_axes = sp[:framestyle] != :none # axes_2d = true for series in series_list(sp) st = series[:seriestype] @@ -711,7 +711,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setwindow(xmin, xmax, ymin, ymax) end - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp) # @show xticks yticks #spine_segs grid_segs # draw the grid lines @@ -729,7 +729,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end GR.settransparency(1.0) - # spine (border) and tick marks + # axis lines gr_set_line(1, :solid, xaxis[:foreground_color_axis]) GR.setclip(0) gr_polyline(coords(xspine_segs)...) @@ -738,6 +738,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_polyline(coords(yspine_segs)...) GR.setclip(1) + # tick marks if !(xticks in (nothing, false)) # x labels flip = sp[:yaxis][:flip] @@ -771,6 +772,17 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) end end + + # border + intensity = sp[:framestyle] == :semi ? 0.5 : 1.0 + if sp[:framestyle] in (:box, :semi) + gr_set_line(intensity, :solid, xaxis[:foreground_color_border]) + GR.settransparency(intensity) + gr_polyline(coords(xborder_segs)...) + gr_set_line(intensity, :solid, yaxis[:foreground_color_border]) + GR.settransparency(intensity) + gr_polyline(coords(yborder_segs)...) + end end # end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 5e4d4c82..5db0ba6b 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -32,7 +32,7 @@ const _pyplot_attr = merge_with_base_supported([ :inset_subplots, :dpi, :colorbar_title, - :draw_axes_border, + :framestyle, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -1054,7 +1054,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end py_set_scale(ax, axis) py_set_lims(ax, axis) - py_set_ticks(ax, get_ticks(axis), letter) + ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis) + py_set_ticks(ax, ticks, letter) ax[Symbol("set_", letter, "label")](axis[:guide]) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() @@ -1066,7 +1067,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) lab[:set_family](axis[:tickfont].family) lab[:set_rotation](axis[:rotation]) end - if axis[:grid] + if axis[:grid] && sp[:framestyle] != :none fgcolor = py_color(axis[:foreground_color_grid]) pyaxis[:grid](true, color = fgcolor, @@ -1090,17 +1091,34 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # this sets the bg color inside the grid ax[set_facecolor_sym](py_color(sp[:background_color_inside])) - if !sp[:draw_axes_border] - if ispolar(sp) + # framestyle + if !ispolar(sp) && !is3d(sp) + if sp[:framestyle] == :semi + intensity = 0.5 + ax[:spines]["right"][:set_alpha](intensity) + ax[:spines]["top"][:set_alpha](intensity) + ax[:spines]["right"][:set_linewidth](intensity) + ax[:spines]["top"][:set_linewidth](intensity) + elseif sp[:framestyle] == :axes + ax[:spines]["right"][:set_visible](false) + ax[:spines]["top"][:set_visible](false) + elseif sp[:framestyle] in (:grid, :none) for (loc, spine) in ax[:spines] spine[:set_visible](false) end - else - # hide the right and top spines - ax[:spines]["right"][:set_visible](false) - ax[:spines]["top"][:set_visible](false) end end + # if !sp[:draw_axes_border] + # if ispolar(sp) + # for (loc, spine) in ax[:spines] + # spine[:set_visible](false) + # end + # else + # # hide the right and top spines + # ax[:spines]["right"][:set_visible](false) + # ax[:spines]["top"][:set_visible](false) + # end + # end end py_drawfig(fig) end