added fg_guide coloring; allow markers for bar/sticks and sticks fixes; legend text color

This commit is contained in:
Thomas Breloff 2016-04-25 16:57:16 -04:00
parent b3230c5671
commit 36ca485a74
3 changed files with 180 additions and 72 deletions

View File

@ -167,8 +167,9 @@ _plotDefaults[:foreground_color] = :auto # default for al
_plotDefaults[:foreground_color_legend] = :match # foreground of legend _plotDefaults[:foreground_color_legend] = :match # foreground of legend
_plotDefaults[:foreground_color_grid] = :match # grid color _plotDefaults[:foreground_color_grid] = :match # grid color
_plotDefaults[:foreground_color_axis] = :match # axis border/tick colors _plotDefaults[:foreground_color_axis] = :match # axis border/tick colors
_plotDefaults[:foreground_color_text] = :match # tick/guide text color
_plotDefaults[:foreground_color_border] = :match # plot area border/spines _plotDefaults[:foreground_color_border] = :match # plot area border/spines
_plotDefaults[:foreground_color_text] = :match # tick text color
_plotDefaults[:foreground_color_guide] = :match # guide text color
_plotDefaults[:xlims] = :auto _plotDefaults[:xlims] = :auto
_plotDefaults[:ylims] = :auto _plotDefaults[:ylims] = :auto
_plotDefaults[:zlims] = :auto _plotDefaults[:zlims] = :auto
@ -269,10 +270,12 @@ add_aliases(:foreground_color_grid, :fg_grid, :fggrid, :fgcolor_grid, :fg_color_
:foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor) :foreground_colour_grid, :fgcolour_grid, :fg_colour_grid, :gridcolor)
add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis, add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis,
:foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor) :foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor)
add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text,
:foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor)
add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border, add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border,
:foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border) :foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border)
add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text,
:foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor)
add_aliases(:foreground_color_guide, :fg_guide, :fgguide, :fgcolor_guide, :fg_color_guide, :foreground_guide,
:foreground_colour_guide, :fgcolour_guide, :fg_colour_guide, :guidecolor)
# alphas # alphas
add_aliases(:seriesalpha, :alpha, :α, :opacity) add_aliases(:seriesalpha, :alpha, :α, :opacity)
@ -388,19 +391,21 @@ const _themes = KW(
:fgaxis => :match, :fgaxis => :match,
:fgtext => :match, :fgtext => :match,
:fgborder => :match, :fgborder => :match,
:fgguide => :match,
), ),
:ggplot2 => KW( # :ggplot2 => KW(
:bg => :white, # :bg => :white,
:bglegend => _invisible, # :bglegend => _invisible,
:bginside => :lightgray, # :bginside => :lightgray,
:bgoutside => :match, # :bgoutside => :match,
:fg => :white, # :fg => :white,
:fglegend => _invisible, # :fglegend => _invisible,
:fggrid => :match, # :fggrid => :match,
:fgaxis => :match, # :fgaxis => :match,
:fgtext => :gray, # :fgtext => :gray,
:fgborder => :match, # :fgborder => :match,
), # :fgguide => :black,
# ),
) )
function add_theme(sym::Symbol, theme::KW) function add_theme(sym::Symbol, theme::KW)
@ -419,7 +424,8 @@ function add_theme(sym::Symbol;
fggrid = _themes[base][:fggrid], fggrid = _themes[base][:fggrid],
fgaxis = _themes[base][:fgaxis], fgaxis = _themes[base][:fgaxis],
fgtext = _themes[base][:fgtext], fgtext = _themes[base][:fgtext],
fgborder = _themes[base][:fgborder]) fgborder = _themes[base][:fgborder],
fgguide = _themes[base][:fgguide])
_themes[sym] = KW( _themes[sym] = KW(
:bg => bg, :bg => bg,
:bglegend => bglegend, :bglegend => bglegend,
@ -431,9 +437,19 @@ function add_theme(sym::Symbol;
:fgaxis => fgaxis, :fgaxis => fgaxis,
:fgtext => fgtext, :fgtext => fgtext,
:fgborder => fgborder, :fgborder => fgborder,
:fgguide => fgguide,
) )
end end
add_theme(:ggplot2,
bglegend = _invisible,
bginside = :lightgray,
fg = :white,
fglegend = _invisible,
fgtext = :gray,
fgguide = :black
)
function set_theme(sym::Symbol) function set_theme(sym::Symbol)
default(; _themes[sym]...) default(; _themes[sym]...)
end end
@ -805,7 +821,7 @@ function getPlotArgs(pkg::AbstractBackend, kw, idx::Int; set_defaults = true)
end end
function has_black_border_for_default(lt::Symbol) function has_black_border_for_default(lt::Symbol)
like_histogram(lt) || lt == :hexbin like_histogram(lt) || lt in (:hexbin, :bar)
end end
# build the argument dictionary for a series # build the argument dictionary for a series

View File

@ -9,6 +9,7 @@ function _initialize_backend(::PyPlotBackend)
const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path")) const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path"))
const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d")) const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d"))
const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches")) const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches"))
const pyfont = PyPlot.pywrap(PyPlot.pyimport("matplotlib.font_manager"))
# const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar")) # const pycolorbar = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colorbar"))
end end
@ -129,6 +130,14 @@ function getPyPlotStepStyle(linetype::Symbol)
return "default" return "default"
end end
# untested... return a FontProperties object from a Plots.Font
function getPyPlotFont(font::Font)
pyfont.pymember("FontProperties")(
family = font.family,
size = font.size
)
end
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
type PyPlotAxisWrapper type PyPlotAxisWrapper
@ -166,34 +175,34 @@ getLeftAxis(plt::Plot{PyPlotBackend}) = getLeftAxis(plt.o)
getRightAxis(plt::Plot{PyPlotBackend}) = getRightAxis(plt.o) getRightAxis(plt::Plot{PyPlotBackend}) = getRightAxis(plt.o)
getAxis(plt::Plot{PyPlotBackend}, axis::Symbol) = (axis == :right ? getRightAxis : getLeftAxis)(plt) getAxis(plt::Plot{PyPlotBackend}, axis::Symbol) = (axis == :right ? getRightAxis : getLeftAxis)(plt)
# left axis is PyPlot.<func>, right axis is "f.axes[0].twinx().<func>" # # left axis is PyPlot.<func>, right axis is "f.axes[0].twinx().<func>"
function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol) # function getPyPlotFunction(plt::Plot, axis::Symbol, linetype::Symbol)
# # need to access mplot3d functions differently # # # need to access mplot3d functions differently
# if linetype == :surface # # if linetype == :surface
# return mplot3d.pymember("Axes3D")[:plot_surface] # # return mplot3d.pymember("Axes3D")[:plot_surface]
# end # # end
#
# in the 2-axis case we need to get: <rightaxis>[:<func>] # # in the 2-axis case we need to get: <rightaxis>[:<func>]
ax = getAxis(plt, axis) # ax = getAxis(plt, axis)
# ax[:set_ylabel](plt.plotargs[:yrightlabel]) # # ax[:set_ylabel](plt.plotargs[:yrightlabel])
fmap = KW( # fmap = KW(
:hist => :hist, # :hist => :hist,
:density => :hist, # :density => :hist,
:sticks => :bar, # :sticks => :bar,
:bar => :bar, # :bar => :bar,
:hist2d => :hexbin, # :hist2d => :hexbin,
:hexbin => :hexbin, # :hexbin => :hexbin,
:scatter => :scatter, # :scatter => :scatter,
:contour => :contour, # :contour => :contour,
:scatter3d => :scatter, # :scatter3d => :scatter,
:surface => :plot_surface, # :surface => :plot_surface,
:wireframe => :plot_wireframe, # :wireframe => :plot_wireframe,
:heatmap => :pcolor, # :heatmap => :pcolor,
:shape => :add_patch, # :shape => :add_patch,
# :surface => pycolors.pymember("LinearSegmentedColormap")[:from_list] # # :surface => pycolors.pymember("LinearSegmentedColormap")[:from_list]
) # )
return ax[get(fmap, linetype, :plot)] # return ax[get(fmap, linetype, :plot)]
end # end
function handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Bool) function handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Bool)
@ -361,6 +370,7 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
ax = getAxis(plt, d[:axis]) ax = getAxis(plt, d[:axis])
x, y, z = d[:x], d[:y], d[:z] x, y, z = d[:x], d[:y], d[:z]
xyargs = (lt in _3dTypes ? (x,y,z) : (x,y))
# handle zcolor and get c/cmap # handle zcolor and get c/cmap
extrakw = KW() extrakw = KW()
@ -371,8 +381,6 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
# path/line/scatter should all do UP TO 2 series... a line, and a scatter # path/line/scatter should all do UP TO 2 series... a line, and a scatter
if lt in (:path, :line, :scatter, :path3d, :scatter3d, :steppre, :steppost) if lt in (:path, :line, :scatter, :path3d, :scatter3d, :steppre, :steppost)
xyargs = (lt in _3dTypes ? (x,y,z) : (x,y))
# line plot (path, line, steppre, steppost, path3d) # line plot (path, line, steppre, steppost, path3d)
if d[:linewidth] > 0 if d[:linewidth] > 0
handle = ax[:plot](xyargs...; handle = ax[:plot](xyargs...;
@ -386,30 +394,30 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
push!(handles, handle) push!(handles, handle)
end end
# scatter plot (scatter, scatter3d, and line plots that have markers) # # scatter plot (scatter, scatter3d, and line plots that have markers)
if d[:markershape] != :none # if d[:markershape] != :none
if d[:marker_z] == nothing # if d[:marker_z] == nothing
extrakw[:c] = color_fix(pymarkercolor(d), x) # extrakw[:c] = color_fix(pymarkercolor(d), x)
else # else
extrakw[:c] = convert(Vector{Float64}, d[:marker_z]) # extrakw[:c] = convert(Vector{Float64}, d[:marker_z])
extrakw[:cmap] = pymarkercolormap(d) # extrakw[:cmap] = pymarkercolormap(d)
needs_colorbar = true # needs_colorbar = true
end # end
handle = ax[:scatter](xyargs...; # handle = ax[:scatter](xyargs...;
label = d[:label], # label = d[:label],
zorder = plt.n + 0.5, # zorder = plt.n + 0.5,
marker = getPyPlotMarker(d[:markershape]), # marker = getPyPlotMarker(d[:markershape]),
s = d[:markersize] .^ 2, # s = d[:markersize] .^ 2,
edgecolors = pymarkerstrokecolor(d), # edgecolors = pymarkerstrokecolor(d),
linewidths = d[:markerstrokewidth], # linewidths = d[:markerstrokewidth],
extrakw... # extrakw...
) # )
push!(handles, handle) # push!(handles, handle)
end # end
end end
if lt in (:bar, :sticks) if lt == :bar
extrakw[isvertical(d) ? :width : :height] = (lt == :sticks ? 0.1 : 0.9) extrakw[isvertical(d) ? :width : :height] = 0.9
handle = ax[isvertical(d) ? :bar : :barh](x, y; handle = ax[isvertical(d) ? :bar : :barh](x, y;
label = d[:label], label = d[:label],
zorder = plt.n, zorder = plt.n,
@ -422,6 +430,84 @@ function _add_series(pkg::PyPlotBackend, plt::Plot, d::KW)
push!(handles, handle) push!(handles, handle)
end end
if lt == :sticks
extrakw[isvertical(d) ? :width : :height] = 0.0
handle = ax[isvertical(d) ? :bar : :barh](x, y;
label = d[:label],
zorder = plt.n,
color = pylinecolor(d),
edgecolor = pylinecolor(d),
linewidth = d[:linewidth],
align = "center",
extrakw...
)[1]
push!(handles, handle)
end
# if lt in (:bar, :sticks)
# extrakw[isvertical(d) ? :width : :height] = (lt == :sticks ? 0.0 : 0.9)
# handle = ax[isvertical(d) ? :bar : :barh](x, y;
# label = d[:label],
# zorder = plt.n,
# color = pyfillcolor(d),
# edgecolor = lt == :sticks ? py pylinecolor(d),
# linewidth = d[:linewidth],
# align = "center",
# extrakw...
# )[1]
# push!(handles, handle)
#
# # if d[:markershape] != :none
# # extrakw = KW()
# # if d[:marker_z] == nothing
# # extrakw[:c] = color_fix(pymarkercolor(d), x)
# # else
# # extrakw[:c] = convert(Vector{Float64}, d[:marker_z])
# # extrakw[:cmap] = pymarkercolormap(d)
# # needs_colorbar = true
# # end
# # handle = ax[:scatter](x, y;
# # label = d[:label],
# # zorder = plt.n + 0.5,
# # marker = getPyPlotMarker(d[:markershape]),
# # s = d[:markersize] .^ 2,
# # edgecolors = pymarkerstrokecolor(d),
# # linewidths = d[:markerstrokewidth],
# # extrakw...
# # )
# # push!(handles, handle)
# # end
# end
# add markers?
if d[:markershape] != :none && lt in (:path, :line, :scatter, :path3d,
:scatter3d, :steppre, :steppost,
:bar, :sticks)
extrakw = KW()
if d[:marker_z] == nothing
extrakw[:c] = color_fix(pymarkercolor(d), x)
else
extrakw[:c] = convert(Vector{Float64}, d[:marker_z])
extrakw[:cmap] = pymarkercolormap(d)
needs_colorbar = true
end
xyargs = if lt in (:bar, :sticks) && !isvertical(d)
(y, x)
else
xyargs
end
handle = ax[:scatter](xyargs...;
label = d[:label],
zorder = plt.n + 0.5,
marker = getPyPlotMarker(d[:markershape]),
s = d[:markersize] .^ 2,
edgecolors = pymarkerstrokecolor(d),
linewidths = d[:markerstrokewidth],
extrakw...
)
push!(handles, handle)
end
if lt == :hist if lt == :hist
handle = ax[:hist](y; handle = ax[:hist](y;
label = d[:label], label = d[:label],
@ -926,7 +1012,8 @@ end
function updateAxisColors(ax, d::KW) function updateAxisColors(ax, d::KW)
guidecolor = getPyPlotColor(d[:guidefont].color) # guidecolor = getPyPlotColor(d[:guidefont].color)
guidecolor = getPyPlotColor(d[:foreground_color_guide])
for (loc, spine) in ax[:spines] for (loc, spine) in ax[:spines]
spine[:set_color](getPyPlotColor(d[:foreground_color_border])) spine[:set_color](getPyPlotColor(d[:foreground_color_border]))
end end
@ -1117,10 +1204,15 @@ function addPyPlotLegend(plt::Plot, ax)
) )
leg[:set_zorder](1000) leg[:set_zorder](1000)
fgcolor = getPyPlotColor(plt.plotargs[:foreground_color_legend])
for txt in leg[:get_texts]()
PyPlot.plt[:setp](txt, color = fgcolor)
end
# set some legend properties # set some legend properties
frame = leg[:get_frame]() frame = leg[:get_frame]()
frame[:set_facecolor](getPyPlotColor(plt.plotargs[:background_color_legend])) frame[:set_facecolor](getPyPlotColor(plt.plotargs[:background_color_legend]))
frame[:set_edgecolor](getPyPlotColor(plt.plotargs[:foreground_color_legend])) frame[:set_edgecolor](fgcolor)
end end
end end
end end

View File

@ -398,7 +398,7 @@ function handlePlotColors(::AbstractBackend, d::KW)
end end
# update sub-foreground colors # update sub-foreground colors
for fgtype in ("legend", "grid", "axis", "text", "border") for fgtype in ("legend", "grid", "axis", "text", "border", "guide")
fgsym = symbol("foreground_color_" * fgtype) fgsym = symbol("foreground_color_" * fgtype)
if d[fgsym] == :match if d[fgsym] == :match
d[fgsym] = d[:foreground_color] d[fgsym] = d[:foreground_color]