diff --git a/src/args.jl b/src/args.jl index 1e14cee5..55f629a8 100644 --- a/src/args.jl +++ b/src/args.jl @@ -193,6 +193,7 @@ _subplot_defaults[:background_color_inside] = :match # background in _subplot_defaults[:foreground_color_subplot] = :match # default for other fg colors... match takes plot default _subplot_defaults[:foreground_color_legend] = :match # foreground of legend _subplot_defaults[:foreground_color_grid] = :match # grid color +_subplot_defaults[:foreground_color_title] = :match # title color _subplot_defaults[:color_palette] = :auto _subplot_defaults[:legend] = :best _subplot_defaults[:colorbar] = :legend @@ -312,6 +313,8 @@ add_aliases(:foreground_color_legend, :fg_legend, :fglegend, :fgcolor_legend, :f :foreground_colour_legend, :fgcolour_legend, :fg_colour_legend) add_aliases(:foreground_color_grid, :fg_grid, :fggrid, :fgcolor_grid, :fg_color_grid, :foreground_grid, :foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor) +add_aliases(:foreground_color_title, :fg_title, :fgtitle, :fgcolor_title, :fg_color_title, :foreground_title, + :foreground_colour_title, :fgcolour_title, :fg_colour_title, :titlecolor) add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis, :foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor) add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border, @@ -348,7 +351,7 @@ add_aliases(:xguide, :xlabel, :xlab, :xl) add_aliases(:xlims, :xlim, :xlimit, :xlimits) add_aliases(:xticks, :xtick) add_aliases(:xrotation, :xrot, :xr) -add_aliases(:xguide, :ylabel, :ylab, :yl) +add_aliases(:yguide, :ylabel, :ylab, :yl) add_aliases(:ylims, :ylim, :ylimit, :ylimits) add_aliases(:yticks, :ytick) # add_aliases(:yrightlabel, :yrlab, :yrl, :ylabel2, :y2label, :ylab2, :y2lab, :ylabr, :ylabelright) @@ -947,6 +950,7 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I fg = color_or_match!(spargs, :foreground_color_subplot, pargs[:foreground_color]) color_or_match!(spargs, :foreground_color_legend, fg) color_or_match!(spargs, :foreground_color_grid, fg) + color_or_match!(spargs, :foreground_color_title, fg) # info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") # DD(spargs, "before loop") diff --git a/src/axes.jl b/src/axes.jl index e162274d..21dbb362 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -28,7 +28,6 @@ function update!(a::Axis, args...; kw...) for arg in args T = typeof(arg) arg = get(_scaleAliases, arg, arg) - # scale, flip, label, lim, tick = axis_symbols(letter, "scale", "flip", "label", "lims", "ticks") if typeof(arg) <: Font d[:tickfont] = arg @@ -41,7 +40,7 @@ function update!(a::Axis, args...; kw...) d[:flip] = true elseif T <: @compat(AbstractString) - d[:label] = arg + d[:guide] = arg # xlims/ylims elseif (T <: Tuple || T <: AVec) && length(arg) == 2 diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 79d0f9c5..4d695da9 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -94,7 +94,7 @@ end getPyPlotColor(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha)) getPyPlotColor(cvec::ColorVector, α=nothing) = map(getPyPlotColor, convertColor(cvec, α).v) getPyPlotColor(scheme::ColorScheme, α=nothing) = getPyPlotColor(convertColor(getColor(scheme), α)) -getPyPlotColor(vec::AVec, α=nothing) = map(c->getPyPlotColor(c,α), vec) +getPyPlotColor(vec::AVec, α=nothing) = map(c->getPyPlotColor(c,α), vec) getPyPlotColor(c, α=nothing) = getPyPlotColor(convertColor(c, α)) function getPyPlotColorMap(c::ColorGradient, α=nothing) @@ -321,6 +321,7 @@ min_padding_bottom(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout, # `func` is one of (left,top,right,bottom), and we multiply by 1 or -1 depending on direction function compute_min_padding(sp::Subplot{PyPlotBackend}, func::Function, mult::Number) ax = sp.o + ax == nothing && return 0mm plotbb = py_bbox(ax) # @show func, mult plotbb # @show func, py_bbox_axis(ax, "x") @@ -375,6 +376,7 @@ end function update_position!(sp::Subplot{PyPlotBackend}) ax = sp.o + ax == nothing && return figw, figh = size(py_bbox_fig(sp.plt)) # plot_bb = plotarea_bbox(sp) @@ -402,6 +404,8 @@ function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend label = string(gensym()), projection = (proj in (nothing,:none) ? nothing : string(proj)) ) + + # @show proj, ax # projection = # ax = fig[:add_subplot](111, projection = _py_projections[sp.attr[:projection]]) # for axis in (:xaxis, :yaxis) @@ -512,11 +516,11 @@ function pyplot_figure(plotargs::KW) fig end -function pyplot_3d_setup!(wrap, d) - if trueOrAllTrue(st -> st in _3dTypes, get(d, :seriestype, :none)) - push!(wrap.kwargs, (:projection, "3d")) - end -end +# function pyplot_3d_setup!(wrap, d) +# if trueOrAllTrue(st -> st in _3dTypes, get(d, :seriestype, :none)) +# push!(wrap.kwargs, (:projection, "3d")) +# end +# end # --------------------------------------------------------------------------- @@ -584,11 +588,11 @@ function _add_series(plt::Plot{PyPlotBackend}, series::Series) error("seriestype $(st) is unsupported in PyPlot. Choose from: $(supportedTypes(plt.backend))") end - # 3D plots have a different underlying Axes object in PyPlot - # TODO: BUG: this adds to kwargs but never changes anything... source of subplot(wireframe(...)) bug? - if st in _3dTypes && isempty(plt.o.kwargs) - push!(plt.o.kwargs, (:projection, "3d")) - end + # # 3D plots have a different underlying Axes object in PyPlot + # # TODO: BUG: this adds to kwargs but never changes anything... source of subplot(wireframe(...)) bug? + # if st in _3dTypes && isempty(plt.o.kwargs) + # push!(plt.o.kwargs, (:projection, "3d")) + # end # PyPlot doesn't handle mismatched x/y fix_xy_lengths!(plt, d) @@ -619,6 +623,8 @@ function _add_series(plt::Plot{PyPlotBackend}, series::Series) error("Only numbers and vectors are supported with levels keyword") end + # @show ax d + # for each plotting command, optionally build and add a series handle to the list # line plot @@ -1139,14 +1145,17 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) # figorax = plt.o # ax = getLeftAxis(figorax) for sp in plt.subplots - spargs = sp.attr + attr = sp.attr ax = getAxis(sp) + if ax == nothing + continue + end # ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize - # guidesz = get(d, :guidefont, spargs[:guidefont]).pointsize + # guidesz = get(d, :guidefont, attr[:guidefont]).pointsize # title - if haskey(spargs, :title) - loc = lowercase(string(spargs[:title_location])) + if haskey(attr, :title) + loc = lowercase(string(attr[:title_location])) field = if loc == "left" :_left_title elseif loc == "right" @@ -1154,10 +1163,11 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) else :title end - ax[field][:set_text](spargs[:title]) - ax[field][:set_fontsize](spargs[:titlefont].pointsize) - ax[field][:set_color](getPyPlotColor(spargs[:titlefont].color)) - ax[:set_title](spargs[:title], loc = loc) + ax[field][:set_text](attr[:title]) + ax[field][:set_fontsize](attr[:titlefont].pointsize) + # ax[field][:set_color](getPyPlotColor(attr[:titlefont].color)) + ax[field][:set_color](getPyPlotColor(attr[:foreground_color_title])) + ax[:set_title](attr[:title], loc = loc) # TODO: set other font attributes end @@ -1166,17 +1176,17 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) # axes = [getLeftAxis(figorax)] # if usingRightAxis(plt) # push!(axes, getRightAxis(figorax)) - # if get(spargs, :yrightlabel, "") != "" + # if get(attr, :yrightlabel, "") != "" # rightax = getRightAxis(figorax) - # rightax[:set_ylabel](spargs[:yrightlabel]) + # rightax[:set_ylabel](attr[:yrightlabel]) # end # end for letter in (:x, :y, :z) axissym = symbol(letter, :axis) - axis = spargs[axissym] + axis = attr[axissym] # @show axis - # DD(axis.spargs, "updateplot") + # DD(axis.attr, "updateplot") # @show haskey(ax, axissym) haskey(ax, axissym) || continue applyPyPlotScale(ax, axis[:scale], letter) @@ -1193,8 +1203,8 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) lab[:set_fontsize](axis[:tickfont].pointsize) lab[:set_rotation](axis[:rotation]) end - if get(spargs, :grid, false) - fgcolor = getPyPlotColor(spargs[:foreground_color_grid]) + if get(attr, :grid, false) + fgcolor = getPyPlotColor(attr[:foreground_color_grid]) tmpax[axissym][:grid](true, color = fgcolor) tmpax[:set_axisbelow](true) end @@ -1208,20 +1218,20 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) # axis, scale, lims, ticks, flip, lab, rotation = # axis_symbols(letter, "axis", "scale", "lims", "ticks", "flip", "label", "rotation") # haskey(ax, axis) || continue - # haskey(spargs, scale) && applyPyPlotScale(ax, spargs[scale], letter) - # haskey(spargs, lims) && addPyPlotLims(ax, spargs[lims], letter) - # haskey(spargs, ticks) && addPyPlotTicks(ax, spargs[ticks], letter) - # haskey(spargs, lab) && ax[symbol("set_", letter, "label")](spargs[lab]) - # if get(spargs, flip, false) + # haskey(attr, scale) && applyPyPlotScale(ax, attr[scale], letter) + # haskey(attr, lims) && addPyPlotLims(ax, attr[lims], letter) + # haskey(attr, ticks) && addPyPlotTicks(ax, attr[ticks], letter) + # haskey(attr, lab) && ax[symbol("set_", letter, "label")](attr[lab]) + # if get(attr, flip, false) # ax[symbol("invert_", letter, "axis")]() # end # for tmpax in axes # tmpax[axis][:label][:set_fontsize](guidesz) # for lab in tmpax[symbol("get_", letter, "ticklabels")]() # lab[:set_fontsize](ticksz) - # haskey(spargs, rotation) && lab[:set_rotation](spargs[rotation]) + # haskey(attr, rotation) && lab[:set_rotation](attr[rotation]) # end - # if get(spargs, :grid, false) + # if get(attr, :grid, false) # fgcolor = getPyPlotColor(plt.plotargs[:foreground_color_grid]) # tmpax[axis][:grid](true, color = fgcolor) # tmpax[:set_axisbelow](true) @@ -1230,7 +1240,7 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW) # end # do we want to change the aspect ratio? - aratio = get(spargs, :aspect_ratio, :none) + aratio = get(attr, :aspect_ratio, :none) if aratio != :none ax[:set_aspect](isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C") end @@ -1402,6 +1412,7 @@ function finalizePlot(plt::Plot{PyPlotBackend}) for sp in plt.subplots # ax = getLeftAxis(plt) ax = getAxis(sp) + ax == nothing && continue addPyPlotLegend(plt, sp, ax) for asym in (:xaxis, :yaxis, :zaxis) updateAxisColors(ax, sp.attr[asym]) diff --git a/src/plot.jl b/src/plot.jl index be6e02fa..a00fc897 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -46,26 +46,18 @@ function plot(args...; kw...) pkg = backend() d = KW(kw) preprocessArgs!(d) - # DD(d,"pre") # create an empty Plot, update the args using the inputs, then pass it # to the backend to finish backend-specific initialization plt = Plot() _update_plot_args(plt, d) - # DD(plt.plotargs,"pargs") plt.o = _create_backend_figure(plt) # create the layout and subplots from the inputs plt.layout, plt.subplots, plt.spmap = build_layout(plt.plotargs) for (idx,sp) in enumerate(plt.subplots) - # update the subplot/axis args from inputs, then pass to backend to init further sp.plt = plt _update_subplot_args(plt, sp, copy(d), idx) - # DD(sp.attr[:xaxis].d,"$idx") - - # TODO: i'd like to know what projection we're using by this point... can I push this off until later?? - # I won't easily be able to auto-determine what series types are coming... - _initialize_subplot(plt, sp) end # now update the plot @@ -97,58 +89,6 @@ function strip_first_letter(s::Symbol) str[1:1], symbol(str[2:end]) end -# # TODO: need to apply axis args to the axes, subplot args to the subplots, and plot args to the plot -# # merge the KW d into the plot args -# function _add_plotargs!(plt::Plot, d::KW) -# # @show d -# -# # handle axis updates from a recipe -# for letter in ("x","y","z") -# # get the Axis object -# asym = symbol(letter * "axis") -# axis = plt.plotargs[asym] -# if axis == nothing -# # create a new one on first pass -# axis = Axis(letter) -# end -# # @show 1,typeof(axis) -# -# # update xlabel, xscale, etc -# for k in _axis_symbols -# lk = symbol(letter * string(k)) -# if haskey(d, lk) -# axis[k] = d[lk] -# end -# end -# # @show 2,axis -# -# # update guidefont, etc -# for k in _axis_symbols_fonts_colors -# if haskey(d, k) -# axis[k] = d[k] -# end -# end -# # @show 3,axis -# -# # update extrema and discrete values -# datasym = symbol(letter) -# if haskey(d, datasym) -# v = d[datasym] -# if eltype(v) <: Number -# expand_extrema!(axis, v) -# else -# d[datasym] = discrete_value!(axis, v) -# end -# end -# # @show 4,axis -# end -# -# for k in keys(_plot_defaults) -# if haskey(d, k) -# plt.plotargs[k] = pop!(d, k) -# end -# end -# end # this method recursively applies series recipes when the seriestype is not supported # natively by the backend @@ -164,6 +104,17 @@ function _apply_series_recipe(plt::Plot, d::KW) sp_idx = get_subplot_index(plt, sp) _update_subplot_args(plt, sp, d, sp_idx) + # change to a 3d projection for this subplot? + if is3d(st) + sp.attr[:projection] = "3d" + end + + # initialize now that we know the first series type + if !haskey(sp.attr, :init) + _initialize_subplot(plt, sp) + sp.attr[:init] = true + end + # adjust extrema and discrete info for s in (:x, :y, :z) data = d[s] diff --git a/src/recipes.jl b/src/recipes.jl index 30a8b96e..0fb196c5 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -36,7 +36,7 @@ if is_installed("DataFrames") function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, dfs::DFS) if isa(dfs, Symbol) - get!(d, symbol(letter * "label"), string(dfs)) + get!(d, symbol(letter * "guide"), string(dfs)) collect(df[dfs]) else get!(d, :label, reshape(dfs, 1, length(dfs)))