diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f0df3e92..386639b6 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -66,11 +66,17 @@ const _arg_desc = KW( :dpi => "Number. Dots Per Inch of output figures", :display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.", :extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.", +:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides", # subplot args :title => "String. Subplot title.", :title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`", -:titlefont => "Font. Font of subplot title.", +:titlefontfamily => "String or Symbol. Font family of subplot title.", +:titlefontsize => "Integer. Font pointsize of subplot title.", +:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center", +:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center", +:titlefontrotation => "Real. Font rotation of subplot title", +:titlefontcolor => "Color Type. Font color of subplot title", :background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.", :background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.", :background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).", @@ -79,7 +85,12 @@ const _arg_desc = KW( :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", -:legendtitle => "String or nothing (default). Sets the legend title.", +:legendfontfamily => "String or Symbol. Font family of legend entries.", +:legendfontsize => "Integer. Font pointsize of legend entries.", +:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center", +:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center", +:legendfontrotation => "Real. Font rotation of legend entries", +:legendfontcolor => "Color Type. Font color of legend entries", :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", @@ -104,8 +115,18 @@ const _arg_desc = KW( :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).", +:tickfontfamily => "String or Symbol. Font family of tick labels.", +:tickfontsize => "Integer. Font pointsize of tick labels.", +:tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center", +:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center", +:tickfontrotation => "Real. Font rotation of tick labels", +:tickfontcolor => "Color Type. Font color of tick labels", +:guidefontfamily => "String or Symbol. Font family of axes guides.", +:guidefontsize => "Integer. Font pointsize of axes guides.", +:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center", +:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center", +:guidefontrotation => "Real. Font rotation of axes guides", +:guidefontcolor => "Color Type. Font color of axes guides", :foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.", :foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).", :foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.", diff --git a/src/args.jl b/src/args.jl index 2bf63ac6..70fa458c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -273,6 +273,7 @@ const _plot_defaults = KW( :background_color => colorant"white", # default for all backgrounds, :background_color_outside => :match, # background outside grid, :foreground_color => :auto, # default for all foregrounds, and title color, + :fontfamily => "sans-serif", :size => (600,400), :pos => (0,0), :window_title => "Plots.jl", @@ -292,7 +293,13 @@ const _plot_defaults = KW( const _subplot_defaults = KW( :title => "", :title_location => :center, # also :left or :right - :titlefont => font(14), + :fontfamily_subplot => :match, + :titlefontfamily => :match, + :titlefontsize => 14, + :titlefonthalign => :hcenter, + :titlefontvalign => :vcenter, + :titlefontrotation => 0.0, + :titlefontcolor => :match, :background_color_subplot => :match, # default for other bg colors... match takes plot default :background_color_legend => :match, # background of legend :background_color_inside => :match, # background inside grid @@ -304,7 +311,12 @@ const _subplot_defaults = KW( :legendtitle => nothing, :colorbar => :legend, :clims => :auto, - :legendfont => font(8), + :legendfontfamily => :match, + :legendfontsize => 8, + :legendfonthalign => :hcenter, + :legendfontvalign => :vcenter, + :legendfontrotation => 0.0, + :legendfontcolor => :match, :annotations => [], # annotation tuples... list of (x,y,annotation) :projection => :none, # can also be :polar or :3d :aspect_ratio => :none, # choose from :none or :equal @@ -327,8 +339,18 @@ const _axis_defaults = KW( :rotation => 0, :flip => false, :link => [], - :tickfont => font(8), - :guidefont => font(11), + :tickfontfamily => :match, + :tickfontsize => 8, + :tickfonthalign => :hcenter, + :tickfontvalign => :vcenter, + :tickfontrotation => 0.0, + :tickfontcolor => :match, + :guidefontfamily => :match, + :guidefontsize => 11, + :guidefonthalign => :hcenter, + :guidefontvalign => :vcenter, + :guidefontrotation => 0.0, + :guidefontcolor => :match, :foreground_color_axis => :match, # axis border/tick colors, :foreground_color_border => :match, # plot area border/spines, :foreground_color_text => :match, # tick text color, @@ -397,10 +419,10 @@ const _all_defaults = KW[ const _initial_defaults = deepcopy(_all_defaults) # to be able to reset font sizes to initial values -const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefont].pointsize, - :legendfont => _subplot_defaults[:legendfont].pointsize, - :tickfont => _axis_defaults[:tickfont].pointsize, - :guidefont => _axis_defaults[:guidefont].pointsize) +const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefontsize], + :legendfont => _subplot_defaults[:legendfontsize], + :tickfont => _axis_defaults[:tickfontsize], + :guidefont => _axis_defaults[:guidefontsize]) const _all_args = sort(collect(union(map(keys, _all_defaults)...))) @@ -743,6 +765,38 @@ function processGridArg!(d::KW, arg, letter) end end +function processFontArg!(d::KW, fontname::Symbol, arg) + T = typeof(arg) + if T <: Font + d[Symbol(fontname, :family)] = arg.family + d[Symbol(fontname, :size)] = arg.pointsize + d[Symbol(fontname, :halign)] = arg.halign + d[Symbol(fontname, :valign)] = arg.valign + d[Symbol(fontname, :rotation)] = arg.rotation + d[Symbol(fontname, :color)] = arg.color + elseif arg == :center + d[Symbol(fontname, :halign)] = :hcenter + d[Symbol(fontname, :valign)] = :vcenter + elseif arg in (:hcenter, :left, :right) + d[Symbol(fontname, :halign)] = arg + elseif arg in (:vcenter, :top, :bottom) + d[Symbol(fontname, :valign)] = arg + elseif T <: Colorant + d[Symbol(fontname, :color)] = arg + elseif T <: Symbol || T <: AbstractString + try + d[Symbol(fontname, :color)] = parse(Colorant, string(arg)) + catch + d[Symbol(fontname, :family)] = string(arg) + end + elseif typeof(arg) <: Integer + d[Symbol(fontname, :size)] = arg + elseif typeof(arg) <: Real + d[Symbol(fontname, :rotation)] = convert(Float64, arg) + else + warn("Skipped font arg: $arg ($(typeof(arg)))") + end +end _replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape) _replace_markershape(shapes::AVec) = map(_replace_markershape, shapes) @@ -811,6 +865,32 @@ function preprocessArgs!(d::KW) end end + # fonts + for fontname in (:titlefont, :legendfont) + args = pop!(d, fontname, ()) + for arg in wraptuple(args) + processFontArg!(d, fontname, arg) + end + end + # handle font args common to all axes + for fontname in (:tickfont, :guidefont) + args = pop!(d, fontname, ()) + for arg in wraptuple(args) + for letter in (:x, :y, :z) + processFontArg!(d, Symbol(letter, fontname), arg) + end + end + end + # handle individual axes font args + for letter in (:x, :y, :z) + for fontname in (:tickfont, :guidefont) + args = pop!(d, Symbol(letter, fontname), ()) + for arg in wraptuple(args) + processFontArg!(d, Symbol(letter, fontname), arg) + end + end + end + # handle line args for arg in wraptuple(pop!(d, :line, ())) processLineArg(d, arg) @@ -1084,6 +1164,12 @@ const _match_map = KW( :top_margin => :margin, :right_margin => :margin, :bottom_margin => :margin, + :titlefontfamily => :fontfamily_subplot, + :legendfontfamily => :fontfamily_subplot, + :titlefontcolor => :foreground_color_subplot, + :legendfontcolor => :foreground_color_subplot, + :tickfontcolor => :foreground_color_text, + :guidefontcolor => :foreground_color_guide, ) # these can match values from the parent container (axis --> subplot --> plot) @@ -1095,6 +1181,9 @@ const _match_map2 = KW( :foreground_color_grid => :foreground_color_subplot, :foreground_color_guide => :foreground_color_subplot, :foreground_color_text => :foreground_color_subplot, + :fontfamily_subplot => :fontfamily, + :tickfontfamily => :fontfamily_subplot, + :guidefontfamily => :fontfamily_subplot, ) # properly retrieve from plt.attr, passing `:match` to the correct key diff --git a/src/backends.jl b/src/backends.jl index 1dd5d8ad..94199b00 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -51,8 +51,8 @@ _series_updated(plt::Plot, series::Series) = nothing _before_layout_calcs(plt::Plot) = nothing -title_padding(sp::Subplot) = sp[:title] == "" ? 0mm : sp[:titlefont].pointsize * pt -guide_padding(axis::Axis) = axis[:guide] == "" ? 0mm : axis[:guidefont].pointsize * pt +title_padding(sp::Subplot) = sp[:title] == "" ? 0mm : sp[:titlefontsize] * pt +guide_padding(axis::Axis) = axis[:guide] == "" ? 0mm : axis[:guidefontsize] * pt "Returns the (width,height) of a text label." function text_size(lablen::Int, sz::Number, rot::Number = 0) @@ -93,7 +93,7 @@ function tick_padding(axis::Axis) # hgt # get the height of the rotated label - text_size(longest_label, axis[:tickfont].pointsize, rot)[2] + text_size(longest_label, axis[:tickfontsize], rot)[2] end end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 924eca72..f89b8afc 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -10,7 +10,7 @@ TODO =# @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl")) end const _glvisualize_attr = merge_with_base_supported([ @@ -24,10 +24,13 @@ const _glvisualize_attr = merge_with_base_supported([ :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :fillrange, :fillcolor, :fillalpha, :bins, :bar_width, :bar_edges, :bar_position, - :title, :title_location, :titlefont, + :title, :title_location, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :titlefontsize, :titlefontcolor, + :legendfontsize, :legendfontcolor, + :tickfontsize, + :guidefontsize, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :colorbar, :marker_z, @@ -612,7 +615,7 @@ function draw_ticks( axis, ticks, isx, isorigin, lims, m, text = "", positions = Point2f0[], offsets=Vec2f0[] ) - sz = pointsize(axis[:tickfont]) + sz = pointsize(tickfont(axis)) atlas = GLVisualize.get_texture_atlas() font = GLVisualize.defaultfont() @@ -745,7 +748,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are :position => map(x-> x[2], ticklabels), :offset => map(last, ticklabels), :color => fcolor, - :relative_scale => pointsize(xaxis[:tickfont]), + :relative_scale => pointsize(tickfont(xaxis)), :scale_primitive => false ) push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) @@ -760,7 +763,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are :position => map(x-> x[2], ticklabels), :offset => map(last, ticklabels), :color => fcolor, - :relative_scale => pointsize(xaxis[:tickfont]), + :relative_scale => pointsize(tickfont(xaxis)), :scale_primitive => false ) push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) @@ -777,8 +780,8 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are area_w = GeometryTypes.widths(area) if sp[:title] != "" - tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title]) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, tf.rotation, color) + tf = titlefont(sp) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, tf.rotation, tf.color) xy = Point2f0(area.w/2, area_w[2] + pointsize(tf)/2) kw = Dict(:model => text_model(font, xy), :scale_primitive => true) extract_font(font, kw) @@ -786,9 +789,9 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are push!(axis_vis, glvisualize_text(xy, t, kw)) end if xaxis[:guide] != "" - tf = xaxis[:guidefont]; color = gl_color(xaxis[:foreground_color_guide]) + tf = guidefont(xaxis) xy = Point2f0(area.w/2, - pointsize(tf)/2) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, tf.rotation, color) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, tf.rotation, tf.color) kw = Dict(:model => text_model(font, xy), :scale_primitive => true) t = PlotText(xaxis[:guide], font) extract_font(font, kw) @@ -796,8 +799,8 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are end if yaxis[:guide] != "" - tf = yaxis[:guidefont]; color = gl_color(yaxis[:foreground_color_guide]) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 90f0, color) + tf = guidefont(yaxis) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 90f0, tf.color) xy = Point2f0(-pointsize(tf)/2, area.h/2) kw = Dict(:model => text_model(font, xy), :scale_primitive=>true) t = PlotText(yaxis[:guide], font) @@ -1483,9 +1486,8 @@ function make_label(sp, series, i) else series[:label] end - color = sp[:foreground_color_legend] - ft = sp[:legendfont] - font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, color) + ft = legendfont(sp) + font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, ft.color) xy = Point2f0(w+gap, 0.0) kw = Dict(:model => text_model(font, xy), :scale_primitive=>false) extract_font(font, kw) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9619f638..7261ca2c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -22,7 +22,14 @@ const _gr_attr = merge_with_base_supported([ :layout, :title, :window_title, :guide, :lims, :ticks, :scale, :flip, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign, + :titlefontrotation, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign, + :legendfontrotation, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfonthalign, :tickfontvalign, + :tickfontrotation, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefonthalign, :guidefontvalign, + :guidefontrotation, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, :fill_z, :line_z, :marker_z, :levels, @@ -583,10 +590,9 @@ end function gr_set_xticks_font(sp) flip = sp[:yaxis][:flip] mirror = sp[:xaxis][:mirror] - gr_set_font(sp[:xaxis][:tickfont], + gr_set_font(tickfont(sp[:xaxis]), halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], valign = (mirror ? :bottom : :top), - color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) return flip, mirror end @@ -595,10 +601,9 @@ end function gr_set_yticks_font(sp) flip = sp[:xaxis][:flip] mirror = sp[:yaxis][:mirror] - gr_set_font(sp[:yaxis][:tickfont], + gr_set_font(tickfont(sp[:yaxis]), halign = (mirror ? :left : :right), valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2], - color = sp[:yaxis][:foreground_color_axis], rotation = sp[:yaxis][:rotation]) return flip, mirror end @@ -759,8 +764,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end # draw the axes - gr_set_font(xaxis[:tickfont]) - gr_set_textcolor(xaxis[:foreground_color_text]) + gr_set_font(tickfont(xaxis)) GR.setlinewidth(1) if is3d(sp) @@ -887,7 +891,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # add the guides GR.savestate() if sp[:title] != "" - gr_set_font(sp[:titlefont]) + gr_set_font(titlefont(sp)) loc = sp[:title_location] if loc == :left xpos = viewport_plotarea[1] @@ -900,27 +904,24 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) halign = GR.TEXT_HALIGN_CENTER end GR.settextalign(halign, GR.TEXT_VALIGN_TOP) - gr_set_textcolor(sp[:foreground_color_title]) gr_text(xpos, viewport_subplot[4], sp[:title]) end if xaxis[:guide] != "" - gr_set_font(xaxis[:guidefont]) + gr_set_font(guidefont(xaxis)) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM) - gr_set_textcolor(xaxis[:foreground_color_guide]) gr_text(gr_view_xcenter(), viewport_subplot[3], xaxis[:guide]) end if yaxis[:guide] != "" - gr_set_font(yaxis[:guidefont]) + gr_set_font(guidefont(yaxis)) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP) GR.setcharup(-1, 0) - gr_set_textcolor(yaxis[:foreground_color_guide]) gr_text(viewport_subplot[1], gr_view_ycenter(), yaxis[:guide]) end GR.restorestate() - gr_set_font(xaxis[:tickfont]) + gr_set_font(tickfont(xaxis)) # this needs to be here to point the colormap to the right indices GR.setcolormap(1000 + GR.COLORMAP_COOLWARM) @@ -1193,7 +1194,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.savestate() GR.selntran(0) GR.setscale(0) - gr_set_font(sp[:legendfont]) + gr_set_font(legendfont(sp)) w = 0 i = 0 n = 0 @@ -1215,7 +1216,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) w = max(w, tbx[3] - tbx[1]) end if w > 0 - dy = _gr_point_mult[1] * sp[:legendfont].pointsize * 1.75 + dy = _gr_point_mult[1] * sp[:legendfontsize] * 1.75 h = dy*n (xpos,ypos) = gr_legend_pos(sp[:legend],w,h) GR.setfillintstyle(GR.INTSTYLE_SOLID) @@ -1227,7 +1228,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) i = 0 if sp[:legendtitle] != nothing GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) - gr_set_textcolor(sp[:foreground_color_legend]) + gr_set_textcolor(sp[:legendfontcolor]) GR.settransparency(1) gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) ypos -= dy @@ -1269,7 +1270,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) lab = series[:label] end GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) - gr_set_textcolor(sp[:foreground_color_legend]) + gr_set_textcolor(sp[:legendfontcolor]) gr_text(xpos, ypos, lab) ypos -= dy end diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 7d09045a..3718b2ee 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -14,7 +14,7 @@ Add in functionality to Plots.jl: =# @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl")) end # --------------------------------------------------------------------------- @@ -32,10 +32,13 @@ const _inspectdr_attr = merge_with_base_supported([ :markerstrokestyle, #Causes warning not to have it... what is this? :fillcolor, :fillalpha, #:fillrange, # :bins, :bar_width, :bar_edges, :bar_position, - :title, :title_location, :titlefont, + :title, :title_location, :window_title, :guide, :lims, :scale, #:ticks, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :grid, :legend, #:colorbar, # :marker_z, # :line_z, @@ -373,24 +376,24 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot]) l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside]) l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis]) - l[:font_title] = InspectDR.Font(sp[:titlefont].family, - _inspectdr_mapptsize(sp[:titlefont].pointsize), - color = _inspectdr_mapcolor(sp[:foreground_color_title]) + l[:font_title] = InspectDR.Font(sp[:titlefontfamily], + _inspectdr_mapptsize(sp[:titlefontsize]), + color = _inspectdr_mapcolor(sp[:titlefontcolor]) ) #Cannot independently control fonts of axes with InspectDR: - l[:font_axislabel] = InspectDR.Font(xaxis[:guidefont].family, - _inspectdr_mapptsize(xaxis[:guidefont].pointsize), - color = _inspectdr_mapcolor(xaxis[:foreground_color_guide]) + l[:font_axislabel] = InspectDR.Font(xaxis[:guidefontfamily], + _inspectdr_mapptsize(xaxis[:guidefontsize]), + color = _inspectdr_mapcolor(xaxis[:guidefontcolor]) ) - l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfont].family, - _inspectdr_mapptsize(xaxis[:tickfont].pointsize), - color = _inspectdr_mapcolor(xaxis[:foreground_color_text]) + l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfontfamily], + _inspectdr_mapptsize(xaxis[:tickfontsize]), + color = _inspectdr_mapcolor(xaxis[:tickfontcolor]) ) l[:enable_legend] = (sp[:legend] != :none) #l[:halloc_legend] = 150 #TODO: compute??? - l[:font_legend] = InspectDR.Font(sp[:legendfont].family, - _inspectdr_mapptsize(sp[:legendfont].pointsize), - color = _inspectdr_mapcolor(sp[:foreground_color_legend]) + l[:font_legend] = InspectDR.Font(sp[:legendfontfamily], + _inspectdr_mapptsize(sp[:legendfontsize]), + color = _inspectdr_mapcolor(sp[:legendfontcolor]) ) l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend]) end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b0906444..20edb066 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -2,7 +2,7 @@ # https://plot.ly/javascript/getting-started @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) end const _plotly_attr = merge_with_base_supported([ @@ -19,7 +19,12 @@ const _plotly_attr = merge_with_base_supported([ :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle, :fillrange, :fillcolor, :fillalpha, :bins, - :title, :title_location, :titlefont, + :title, :title_location, + :titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign, + :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, @@ -256,9 +261,9 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:range] = map(scalefunc(axis[:scale]), lims) if !(axis[:ticks] in (nothing, :none)) - ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) + ax[:titlefont] = plotly_font(guidefont(axis)) ax[:type] = plotly_scale(axis[:scale]) - ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) + ax[:tickfont] = plotly_font(tickfont(axis)) ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) @@ -331,8 +336,8 @@ function plotly_layout(plt::Plot) 0.5 * (left(bb) + right(bb)) end titlex, titley = xy_mm_to_pcts(xmm, top(bbox(sp)), w*px, h*px) - titlefont = font(sp[:titlefont], :top, sp[:foreground_color_title]) - push!(d_out[:annotations], plotly_annotation_dict(titlex, titley, text(sp[:title], titlefont))) + title_font = font(titlefont(sp), :top) + push!(d_out[:annotations], plotly_annotation_dict(titlex, titley, text(sp[:title], title_font))) end d_out[:plot_bgcolor] = rgba_string(sp[:background_color_inside]) @@ -373,7 +378,7 @@ function plotly_layout(plt::Plot) d_out[:legend] = KW( :bgcolor => rgba_string(sp[:background_color_legend]), :bordercolor => rgba_string(sp[:foreground_color_legend]), - :font => plotly_font(sp[:legendfont], sp[:foreground_color_legend]), + :font => plotly_font(legendfont(sp)), :x => xpos, :y => ypos ) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 1ef9a2d7..d6c9c778 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -19,7 +19,10 @@ const _pyplot_attr = merge_with_base_supported([ :title, :title_location, :titlefont, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, :marker_z, :line_z, :fill_z, @@ -128,6 +131,7 @@ end # # anything else just gets a bluesred gradient # py_colormap(c, α=nothing) = py_colormap(default_gradient(), α) +py_color(s) = py_color(parse(Colorant, string(s))) py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c)) py_color(cs::AVec) = map(py_color, cs) py_color(grad::ColorGradient) = py_color(grad.colors) @@ -923,8 +927,8 @@ function py_set_axis_colors(sp, ax, a::Axis) tickcolor = sp[:framestyle] == :zerolines ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis]) ax[:tick_params](axis=string(a[:letter]), which="both", colors=tickcolor, - labelcolor=py_color(a[:foreground_color_text])) - ax[axissym][:label][:set_color](py_color(a[:foreground_color_guide])) + labelcolor=py_color(a[:tickfontcolor])) + ax[axissym][:label][:set_color](py_color(a[:guidefontcolor])) end end @@ -978,9 +982,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) :title end ax[func][:set_text](sp[:title]) - ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefont].pointsize)) - ax[func][:set_family](sp[:titlefont].family) - ax[func][:set_color](py_color(sp[:foreground_color_title])) + ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefontsize])) + ax[func][:set_family](sp[:titlefontfamily]) + ax[func][:set_color](py_color(sp[:titlefontcolor])) # ax[:set_title](sp[:title], loc = loc) end @@ -1005,10 +1009,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) fig = plt.o cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefont].pointsize),family=sp[:yaxis][:guidefont].family) + cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontamily], color = py_color(sp[:yaxis][:guidefontcolor])) for lab in cb[:ax][:yaxis][:get_ticklabels]() - lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) - lab[:set_family](sp[:yaxis][:tickfont].family) + lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfontsize])) + lab[:set_family](sp[:yaxis][:tickfontfamily]) + lab[:set_color](py_color(sp[:yaxis][:tickfontcolor])) end sp.attr[:cbar_handle] = cb sp.attr[:cbar_ax] = cbax @@ -1068,11 +1073,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() end - pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefont].pointsize)) - pyaxis[:label][:set_family](axis[:guidefont].family) + pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefontsize])) + pyaxis[:label][:set_family](axis[:guidefontfamily]) for lab in ax[Symbol("get_", letter, "ticklabels")]() - lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfont].pointsize)) - lab[:set_family](axis[:tickfont].family) + lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfontsize])) + lab[:set_family](axis[:tickfontfamily]) lab[:set_rotation](axis[:rotation]) end if axis[:grid] && !(ticks in (:none, nothing, false)) @@ -1248,7 +1253,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) labels, loc = get(_pyplot_legend_pos, leg, "best"), scatterpoints = 1, - fontsize = py_dpi_scale(plt, sp[:legendfont].pointsize) + fontsize = py_dpi_scale(plt, sp[:legendfontsize]) # family = sp[:legendfont].family # framealpha = 0.6 ) @@ -1256,8 +1261,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) fgcolor = py_color(sp[:foreground_color_legend]) + lfcolor = py_color(sp[:legendfontcolor]) for txt in leg[:get_texts]() - PyPlot.plt[:setp](txt, color = fgcolor, family = sp[:legendfont].family) + PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily]) end # set some legend properties diff --git a/src/utils.jl b/src/utils.jl index d19a2acb..c5a4baa0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1007,3 +1007,43 @@ xmax(plt::Plot) = ignorenan_maximum([ignorenan_maximum(series.d[:x]) for series "Extrema of x-values in plot" ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt)) + + +# --------------------------------------------------------------- +# get fonts from objects: + +titlefont(sp::Subplot) = font( + sp[:titlefontfamily], + sp[:titlefontsize], + sp[:titlefontvalign], + sp[:titlefonthalign], + sp[:titlefontrotation], + sp[:titlefontcolor], +) + +legendfont(sp::Subplot) = font( + sp[:legendfontfamily], + sp[:legendfontsize], + sp[:legendfontvalign], + sp[:legendfonthalign], + sp[:legendfontrotation], + sp[:legendfontcolor], +) + +tickfont(ax::Axis) = font( + ax[:tickfontfamily], + ax[:tickfontsize], + ax[:tickfontvalign], + ax[:tickfonthalign], + ax[:tickfontrotation], + ax[:tickfontcolor], +) + +guidefont(ax::Axis) = font( + ax[:guidefontfamily], + ax[:guidefontsize], + ax[:guidefontvalign], + ax[:guidefonthalign], + ax[:guidefontrotation], + ax[:guidefontcolor], +)