fixes for guide/dataframes; 3d/polar projections; delayed subplot init; fg_title
This commit is contained in:
parent
fb60c244f6
commit
1b901673fc
@ -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")
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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])
|
||||
|
||||
71
src/plot.jl
71
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]
|
||||
|
||||
@ -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)))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user