add Segments; pyplot: switch bar/hist/hist2d to recipes and path fix; change bar to shape; removed GR from tests

This commit is contained in:
Thomas Breloff 2016-06-20 23:11:23 -04:00
parent e76c3fff69
commit f881bfc4fc
6 changed files with 144 additions and 97 deletions

View File

@ -78,6 +78,7 @@ export
Surface, Surface,
OHLC, OHLC,
arrow, arrow,
Segments,
colorscheme, colorscheme,
ColorScheme, ColorScheme,

View File

@ -33,8 +33,8 @@ supported_args(::PyPlotBackend) = merge_with_base_supported([
]) ])
supported_types(::PyPlotBackend) = [ supported_types(::PyPlotBackend) = [
:path, :steppre, :steppost, :shape, :path, :steppre, :steppost, :shape,
:scatter, :histogram2d, :hexbin, :histogram, :scatter, :hexbin, #:histogram2d, :histogram,
:bar, # :bar,
:heatmap, :pie, :image, :heatmap, :pie, :image,
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe :contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
] ]
@ -140,7 +140,7 @@ function py_path(x, y)
mat[i,1] = x[i] mat[i,1] = x[i]
mat[i,2] = y[i] mat[i,2] = y[i]
nan = !ok(x[i], y[i]) nan = !ok(x[i], y[i])
codes[i] = if nan codes[i] = if nan && i>1
_path_CLOSEPOLY _path_CLOSEPOLY
else else
lastnan ? _path_MOVETO : _path_LINETO lastnan ? _path_MOVETO : _path_LINETO
@ -486,28 +486,28 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end end
end end
if st == :bar # if st == :bar
bw = d[:bar_width] # bw = d[:bar_width]
if bw == nothing # if bw == nothing
bw = mean(diff(isvertical(d) ? x : y)) # bw = mean(diff(isvertical(d) ? x : y))
end # end
extrakw[isvertical(d) ? :width : :height] = bw # extrakw[isvertical(d) ? :width : :height] = bw
fr = get(d, :fillrange, nothing) # fr = get(d, :fillrange, nothing)
if fr != nothing # if fr != nothing
extrakw[:bottom] = fr # extrakw[:bottom] = fr
d[:fillrange] = nothing # d[:fillrange] = nothing
end # end
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,
color = py_fillcolor(d), # color = py_fillcolor(d),
edgecolor = py_linecolor(d), # edgecolor = py_linecolor(d),
linewidth = d[:linewidth], # linewidth = d[:linewidth],
align = d[:bar_edges] ? "edge" : "center", # align = d[:bar_edges] ? "edge" : "center",
extrakw... # extrakw...
)[1] # )[1]
push!(handles, handle) # push!(handles, handle)
end # end
# if st == :sticks # if st == :sticks
# extrakw[isvertical(d) ? :width : :height] = 0.0 # extrakw[isvertical(d) ? :width : :height] = 0.0
@ -557,54 +557,54 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(handles, handle) push!(handles, handle)
end end
if st == :histogram # if st == :histogram
handle = ax[:hist](y; # handle = ax[:hist](y;
label = d[:label], # label = d[:label],
zorder = plt.n, # zorder = plt.n,
color = py_fillcolor(d), # color = py_fillcolor(d),
edgecolor = py_linecolor(d), # edgecolor = py_linecolor(d),
linewidth = d[:linewidth], # linewidth = d[:linewidth],
bins = d[:bins], # bins = d[:bins],
normed = d[:normalize], # normed = d[:normalize],
weights = d[:weights], # weights = d[:weights],
orientation = (isvertical(d) ? "vertical" : "horizontal"), # orientation = (isvertical(d) ? "vertical" : "horizontal"),
histtype = (d[:bar_position] == :stack ? "barstacked" : "bar") # histtype = (d[:bar_position] == :stack ? "barstacked" : "bar")
)[3] # )[3]
push!(handles, handle) # push!(handles, handle)
# expand the extrema... handle is a list of Rectangle objects # # expand the extrema... handle is a list of Rectangle objects
for rect in handle # for rect in handle
xmin, ymin, xmax, ymax = rect[:get_bbox]()[:extents] # xmin, ymin, xmax, ymax = rect[:get_bbox]()[:extents]
expand_extrema!(sp, xmin, xmax, ymin, ymax) # expand_extrema!(sp, xmin, xmax, ymin, ymax)
# expand_extrema!(sp[:xaxis], (xmin, xmax)) # # expand_extrema!(sp[:xaxis], (xmin, xmax))
# expand_extrema!(sp[:yaxis], (ymin, ymax)) # # expand_extrema!(sp[:yaxis], (ymin, ymax))
end # end
end # end
if st == :histogram2d # if st == :histogram2d
clims = sp[:clims] # clims = sp[:clims]
if is_2tuple(clims) # if is_2tuple(clims)
isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) # isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) # isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
end # end
handle = ax[:hist2d](x, y; # handle = ax[:hist2d](x, y;
label = d[:label], # label = d[:label],
zorder = plt.n, # zorder = plt.n,
bins = d[:bins], # bins = d[:bins],
normed = d[:normalize], # normed = d[:normalize],
weights = d[:weights], # weights = d[:weights],
cmap = py_fillcolormap(d), # applies to the pcolorfast object # cmap = py_fillcolormap(d), # applies to the pcolorfast object
extrakw... # extrakw...
)[4] # )[4]
push!(handles, handle) # push!(handles, handle)
needs_colorbar = true # needs_colorbar = true
# expand the extrema... handle is a AxesImage object # # expand the extrema... handle is a AxesImage object
expand_extrema!(sp, handle[:get_extent]()...) # expand_extrema!(sp, handle[:get_extent]()...)
# xmin, xmax, ymin, ymax = handle[:get_extent]() # # xmin, xmax, ymin, ymax = handle[:get_extent]()
# expand_extrema!(sp[:xaxis], (xmin, xmax)) # # expand_extrema!(sp[:xaxis], (xmin, xmax))
# expand_extrema!(sp[:yaxis], (ymin, ymax)) # # expand_extrema!(sp[:yaxis], (ymin, ymax))
end # end
if st == :hexbin if st == :hexbin
clims = sp[:clims] clims = sp[:clims]

View File

@ -517,8 +517,6 @@ function _plot!(plt::Plot, d::KW, args...)
# "SERIES RECIPES" # "SERIES RECIPES"
# -------------------------------- # --------------------------------
# this is it folks!
# TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes
for kw in kw_list for kw in kw_list
sp = kw[:subplot] sp = kw[:subplot]
idx = get_subplot_index(plt, sp) idx = get_subplot_index(plt, sp)

View File

@ -424,6 +424,11 @@ end
# create a bar plot as a filled step function # create a bar plot as a filled step function
@recipe function f(::Type{Val{:bar}}, x, y, z) @recipe function f(::Type{Val{:bar}}, x, y, z)
# if horizontal, switch x/y
if !isvertical(d)
x, y = y, x
end
nx, ny = length(x), length(y) nx, ny = length(x), length(y)
edges = if nx == ny edges = if nx == ny
# x is centers, calc the edges # x is centers, calc the edges
@ -447,36 +452,54 @@ end
# make fillto a vector... default fills to 0 # make fillto a vector... default fills to 0
fillto = d[:fillrange] fillto = d[:fillrange]
if fillto == nothing if fillto == nothing
fillto = zeros(1) fillto = 0
elseif isa(fillto, Number)
fillto = Float64[fillto]
end end
nf = length(fillto) # if fillto == nothing
# fillto = zeros(1)
# elseif isa(fillto, Number)
# fillto = Float64[fillto]
# end
# nf = length(fillto)
npts = 3ny + 1 # npts = 3ny + 1
heights = y # heights = y
x = zeros(npts) # x = zeros(npts)
y = zeros(npts) # y = zeros(npts)
fillrng = zeros(npts) # fillrng = zeros(npts)
# create the path in triplets. after the first bottom-left coord of the first bar: # shapes = Shape[]
# add the top-left, top-right, and bottom-right coords for each height xseg, yseg = Segments(), Segments()
x[1] = edges[1]
y[1] = fillto[1]
fillrng[1] = fillto[1]
for i=1:ny for i=1:ny
idx = 3i fi = cycle(fillto,i)
rng = idx-1:idx+1 push!(xseg, edges[i], edges[i], edges[i+1], edges[i+1])
fi = fillto[mod1(i,nf)] push!(yseg, y[i], fi, fi, y[i])
x[rng] = [edges[i], edges[i+1], edges[i+1]]
y[rng] = [heights[i], heights[i], fi]
fillrng[rng] = [fi, fi, fi]
end end
x := x
y := y # # create the path in triplets. after the first bottom-left coord of the first bar:
fillrange := fillrng # # add the top-left, top-right, and bottom-right coords for each height
seriestype := :path # x[1] = edges[1]
# y[1] = fillto[1]
# fillrng[1] = fillto[1]
# for i=1:ny
# idx = 3i
# rng = idx-1:idx+1
# fi = fillto[mod1(i,nf)]
# x[rng] = [edges[i], edges[i+1], edges[i+1]]
# y[rng] = [heights[i], heights[i], fi]
# fillrng[rng] = [fi, fi, fi]
# end
# switch back
if !isvertical(d)
xseg, yseg = yseg, xseg
end
x := xseg.pts
y := yseg.pts
# fillrange := fillrng
# seriestype := :path
seriestype := :shape
() ()
end end
@deps bar path @deps bar path
@ -571,6 +594,7 @@ centers(v::AVec) = v[1] + cumsum(diff(v))
x := centers(xedges) x := centers(xedges)
y := centers(yedges) y := centers(yedges)
z := Surface(counts) z := Surface(counts)
linewidth := 0
seriestype := :heatmap seriestype := :heatmap
() ()
end end

View File

@ -137,6 +137,30 @@ function imageHack(d::KW)
end end
# --------------------------------------------------------------- # ---------------------------------------------------------------
type Segments
pts::Vector{Float64}
end
Segments() = Segments(zeros(0))
function Base.push!(segments::Segments, vs...)
push!(segments.pts, NaN)
for v in vs
push!(segments.pts, v)
end
segments
end
function Base.push!(segments::Segments, vs::AVec)
push!(segments.pts, NaN)
for v in vs
push!(segments.pts, v)
end
segments
end
# ----------------------------------------------------- # -----------------------------------------------------
# helper to manage NaN-separated segments # helper to manage NaN-separated segments

View File

@ -30,7 +30,7 @@ facts("GR") do
@fact gr() --> Plots.GRBackend() @fact gr() --> Plots.GRBackend()
@fact backend() --> Plots.GRBackend() @fact backend() --> Plots.GRBackend()
image_comparison_facts(:gr, skip=[30], eps=img_eps) # image_comparison_facts(:gr, skip=[30], eps=img_eps)
end end
facts("Plotly") do facts("Plotly") do