working on GR; series_list and should_add_to_legend; series recipes fix; hist and bar recipes

This commit is contained in:
Thomas Breloff 2016-05-25 13:06:08 -04:00
parent 603dc30bb1
commit dae9dad2f7
9 changed files with 550 additions and 369 deletions

View File

@ -232,13 +232,14 @@ const _axis_defaults = KW(
:foreground_color_guide => :match, # guide text color,
)
const _suppress_warnings = KW(
:x_discrete_indices => nothing,
:y_discrete_indices => nothing,
:z_discrete_indices => nothing,
:subplot => nothing,
:subplot_index => nothing,
)
const _suppress_warnings = Set{Symbol}([
:x_discrete_indices,
:y_discrete_indices,
:z_discrete_indices,
:subplot,
:subplot_index,
:series_plotindex,
])
# add defaults for the letter versions
const _axis_defaults_byletter = KW()
@ -433,9 +434,7 @@ function default(k::Symbol)
return defaults[k]
end
end
if !haskey(_suppress_warnings, k)
error("Unknown key: ", k)
end
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(k::Symbol, v)
@ -446,9 +445,7 @@ function default(k::Symbol, v)
return v
end
end
if !haskey(_suppress_warnings, k)
error("Unknown key: ", k)
end
k in _suppress_warnings || error("Unknown key: ", k)
end
function default(; kw...)
@ -789,7 +786,7 @@ end
function warnOnUnsupportedArgs(pkg::AbstractBackend, d::KW)
for k in sortedkeys(d)
k in supportedArgs(pkg) && continue
haskey(_suppress_warnings, k) && continue
k in _suppress_warnings && continue
if d[k] != default(k)
warn("Keyword argument $k not supported with $pkg. Choose from: $(supportedArgs(pkg))")
end

File diff suppressed because it is too large Load Diff

View File

@ -1127,13 +1127,16 @@ function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
# gotta do this to ensure both axes are included
labels = []
handles = []
for series in plt.series_list
if get_subplot(series) === sp &&
series.d[:label] != "" &&
!(series.d[:seriestype] in (
:hexbin,:hist2d,:hline,:vline,
:contour,:contour3d,:surface,:wireframe,
:heatmap,:path3d,:scatter3d, :pie, :image))
# for series in plt.series_list
# if get_subplot(series) === sp &&
# series.d[:label] != "" &&
# !(series.d[:seriestype] in (
# :hexbin,:hist2d,:hline,:vline,
# :contour,:contour3d,:surface,:wireframe,
# :heatmap,:path3d,:scatter3d, :pie, :image))
for series in series_list(sp)
if should_add_to_legend(series)
# add a line/marker and a label
push!(handles, if series.d[:seriestype] == :hist
PyPlot.plt[:Line2D]((0,1),(0,0), color=pyfillcolor(series.d), linewidth=4)
else
@ -1142,6 +1145,8 @@ function addPyPlotLegend(plt::Plot, sp::Subplot, ax)
push!(labels, series.d[:label])
end
end
# if anything was added, call ax.legend and set the colors
if !isempty(handles)
leg = ax[:legend](handles,
labels,

View File

@ -20,11 +20,11 @@ function _create_backend_figure(plt::Plot{[PkgName]Backend})
end
# this is called early in the pipeline, use it to make the plot current or something
function _prepare_plot_object(plt::Plot{[PkgName]})
function _prepare_plot_object(plt::Plot{[PkgName]Backend})
end
# Set up the subplot within the backend object.
function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
function _initialize_subplot(plt::Plot{[PkgName]Backend}, sp::Subplot{[PkgName]Backend})
end
# ---------------------------------------------------------------------------
@ -42,7 +42,7 @@ end
# called just before updating layout bounding boxes... in case you need to prep
# for the calcs
function _before_layout_calcs(plt::Plot)
function _before_layout_calcs(plt::Plot{[PkgName]Backend})
end
# Set the (left, top, right, bottom) minimum padding around the plot area

View File

@ -1,8 +1,8 @@
defaultOutputFormat(plt::AbstractPlot) = "png"
defaultOutputFormat(plt::Plot) = "png"
function png(plt::AbstractPlot, fn::@compat(AbstractString))
function png(plt::Plot, fn::@compat(AbstractString))
fn = addExtension(fn, "png")
io = open(fn, "w")
writemime(io, MIME("image/png"), plt)
@ -10,7 +10,7 @@ function png(plt::AbstractPlot, fn::@compat(AbstractString))
end
png(fn::@compat(AbstractString)) = png(current(), fn)
function svg(plt::AbstractPlot, fn::@compat(AbstractString))
function svg(plt::Plot, fn::@compat(AbstractString))
fn = addExtension(fn, "svg")
io = open(fn, "w")
writemime(io, MIME("image/svg+xml"), plt)
@ -19,7 +19,7 @@ end
svg(fn::@compat(AbstractString)) = svg(current(), fn)
function pdf(plt::AbstractPlot, fn::@compat(AbstractString))
function pdf(plt::Plot, fn::@compat(AbstractString))
fn = addExtension(fn, "pdf")
io = open(fn, "w")
writemime(io, MIME("application/pdf"), plt)
@ -28,7 +28,7 @@ end
pdf(fn::@compat(AbstractString)) = pdf(current(), fn)
function ps(plt::AbstractPlot, fn::@compat(AbstractString))
function ps(plt::Plot, fn::@compat(AbstractString))
fn = addExtension(fn, "ps")
io = open(fn, "w")
writemime(io, MIME("application/postscript"), plt)
@ -37,7 +37,7 @@ end
ps(fn::@compat(AbstractString)) = ps(current(), fn)
function tex(plt::AbstractPlot, fn::@compat(AbstractString))
function tex(plt::Plot, fn::@compat(AbstractString))
fn = addExtension(fn, "tex")
io = open(fn, "w")
writemime(io, MIME("application/x-tex"), plt)
@ -78,7 +78,7 @@ function addExtension(fn::@compat(AbstractString), ext::@compat(AbstractString))
end
end
function savefig(plt::AbstractPlot, fn::@compat(AbstractString))
function savefig(plt::Plot, fn::@compat(AbstractString))
# get the extension
local ext
@ -101,7 +101,7 @@ savefig(fn::@compat(AbstractString)) = savefig(current(), fn)
# ---------------------------------------------------------
gui(plt::AbstractPlot = current()) = display(PlotsDisplay(), plt)
gui(plt::Plot = current()) = display(PlotsDisplay(), plt)
function Base.display(::PlotsDisplay, plt::Plot)
prepare_output(plt)
@ -109,7 +109,7 @@ function Base.display(::PlotsDisplay, plt::Plot)
end
# override the REPL display to open a gui window
Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::AbstractPlot) = gui(plt)
Base.display(::Base.REPL.REPLDisplay, ::MIME"text/plain", plt::Plot) = gui(plt)
# ---------------------------------------------------------
@ -123,12 +123,12 @@ const _mimeformats = Dict(
)
# a backup for html... passes to svg
function Base.writemime(io::IO, ::MIME"text/html", plt::AbstractPlot)
function Base.writemime(io::IO, ::MIME"text/html", plt::Plot)
writemime(io, MIME("image/svg+xml"), plt)
end
for mime in keys(_mimeformats)
@eval function writemime(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
@eval function Base.writemime(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
prepare_output(plt)
_writemime(io, m, plt)
end
@ -151,13 +151,13 @@ function setup_ijulia()
global _ijulia_output
_ijulia_output[1] = mimestr
end
function IJulia.display_dict(plt::AbstractPlot)
function IJulia.display_dict(plt::Plot)
global _ijulia_output
Dict{ASCIIString, ByteString}(_ijulia_output[1] => sprint(writemime, _ijulia_output[1], plt))
end
end
# IJulia.display_dict(plt::AbstractPlot) = Dict{ASCIIString, ByteString}("text/html" => sprint(writemime, "text/html", plt))
# IJulia.display_dict(plt::Plot) = Dict{ASCIIString, ByteString}("text/html" => sprint(writemime, "text/html", plt))
set_ijulia_output("text/html")
end
end
@ -174,15 +174,15 @@ function setup_atom()
# connects the render function
for T in (GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend)
Atom.Media.media(AbstractPlot{T}, Atom.Media.Plot)
Atom.Media.media(Plot{T}, Atom.Media.Plot)
end
# Atom.Media.media{T <: Union{GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend}}(Plot{T}, Atom.Media.Plot)
# Atom.displaysize(::AbstractPlot) = (535, 379)
# Atom.displaytitle(plt::AbstractPlot) = "Plots.jl (backend: $(backend(plt)))"
# Atom.displaysize(::Plot) = (535, 379)
# Atom.displaytitle(plt::Plot) = "Plots.jl (backend: $(backend(plt)))"
# this is like "display"... sends an html div with the plot to the PlotPane
function Atom.Media.render(pane::Atom.PlotPane, plt::AbstractPlot)
function Atom.Media.render(pane::Atom.PlotPane, plt::Plot)
Atom.Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt))))
end

View File

@ -95,6 +95,7 @@ end
# natively by the backend
function _apply_series_recipe(plt::Plot, d::KW)
st = d[:seriestype]
@show st
if st in supportedTypes()
# getting ready to add the series... last update to subplot from anything
@ -138,7 +139,7 @@ function _apply_series_recipe(plt::Plot, d::KW)
else
# get a sub list of series for this seriestype
series_list = try
datalist = try
RecipesBase.apply_recipe(d, Val{st}, d[:x], d[:y], d[:z])
catch
warn("Exception during apply_recipe(Val{$st}, ...) with types ($(typeof(d[:x])), $(typeof(d[:y])), $(typeof(d[:z])))")
@ -146,9 +147,9 @@ function _apply_series_recipe(plt::Plot, d::KW)
end
# assuming there was no error, recursively apply the series recipes
for series in series_list
if isa(series, Series)
_apply_series_recipe(plt, series.d)
for data in datalist
if isa(data, RecipeData)
_apply_series_recipe(plt, data.d)
else
warn("Unhandled series: $(series_list)")
break
@ -221,6 +222,10 @@ function _plot!(plt::Plot, d::KW, args...)
kw[:fillrange] = (kw[:y] - rib, kw[:y] + rib)
end
# add the plot index
plt.n += 1
kw[:series_plotindex] = plt.n
# check that the backend will support the command and add it to the list
warnOnUnsupportedScales(plt.backend, kw)
push!(kw_list, kw)
@ -248,9 +253,9 @@ function _plot!(plt::Plot, d::KW, args...)
# this is it folks!
# TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes
for (i,kw) in enumerate(kw_list)
if !(get(kw, :seriestype, :none) in (:xerror, :yerror))
plt.n += 1
end
# if !(get(kw, :seriestype, :none) in (:xerror, :yerror))
# plt.n += 1
# end
# get the Subplot object to which the series belongs
sp = get(kw, :subplot, :auto)

View File

@ -226,6 +226,55 @@ end
()
end
# create a path from steps
@recipe function f(::Type{Val{:steppre}}, x, y, z)
end
# create a bar plot as a filled step function
@recipe function f(::Type{Val{:bar}}, x, y, z)
nx, ny = length(x), length(y)
d[:x] = if nx == ny
# x is centers
halfwidths = 0.5 * diff(x)
vcat(halfwidths[1], halfwidths, halfwidths[end])
elseif nx == ny + 1
# x is edges
x
else
error("bar recipe: x must be same length as y (centers), or one more than y (edges).\n\t\tlength(x)=$(length(x)), length(y)=$(length(y))")
end
# TODO: use y/fillrange to compute new y/fillrange vectors
d[:seriestype] = :steppre
()
end
# # x is edges
# for i=1:n
# gr_fillrect(series, x[i], x[i+1], 0, y[i])
# end
# elseif length(x) == n
# # x is centers
# leftwidth = length(x) > 1 ? abs(0.5 * (x[2] - x[1])) : 0.5
# for i=1:n
# rightwidth = (i == n ? leftwidth : abs(0.5 * (x[i+1] - x[i])))
# gr_fillrect(series, x[i] - leftwidth, x[i] + rightwidth, 0, y[i])
# end
# else
# error("gr_barplot: x must be same length as y (centers), or one more than y (edges).\n\t\tlength(x)=$(length(x)), length(y)=$(length(y))")
# end
@recipe function f(::Type{Val{:hist}}, x, y, z)
edges, counts = Base.hist(y, d[:bins])
d[:x] = edges
d[:y] = counts
d[:seriestype] = :bar
()
end
# ---------------------------------------------------------------------------
# Box Plot

View File

@ -7,7 +7,8 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
# n = plt.n
# attr = getattr(plt, n)
# plotIndex = convertSeriesIndex(plt, n)
globalIndex = plt.n
# globalIndex = plt.n
globalIndex = d[:series_plotindex]
# # add defaults?
# for k in keys(_series_defaults)

View File

@ -33,4 +33,14 @@ get_subplot(series::Series) = series.d[:subplot]
get_subplot_index(plt::Plot, idx::Integer) = idx
get_subplot_index(plt::Plot, sp::Subplot) = findfirst(_ -> _ === sp, plt.subplots)
series_list(sp::Subplot) = filter(series -> series.d[:subplot] === sp, sp.plt.series_list)
function should_add_to_legend(series::Series)
!(series.d[:label] == "" || series.d[:seriestype] in (
:hexbin,:hist2d,:hline,:vline,
:contour,:contour3d,:surface,:wireframe,
:heatmap,:path3d,:scatter3d, :pie, :image
))
end
# ----------------------------------------------------------------------