sticks recipe; fixed up unicodeplots backend

This commit is contained in:
Thomas Breloff 2016-05-26 11:19:47 -04:00
parent 7be5aebbc9
commit d1d8d196ba
5 changed files with 169 additions and 94 deletions

View File

@ -116,7 +116,7 @@ end
# using the axis extrema and limit overrides, return the min/max value for this axis # using the axis extrema and limit overrides, return the min/max value for this axis
function axis_limits(axis::Axis, letter) function axis_limits(axis::Axis)
amin, amax = axis[:extrema] amin, amax = axis[:extrema]
lims = axis[:lims] lims = axis[:lims]
if isa(lims, Tuple) && length(lims) == 2 if isa(lims, Tuple) && length(lims) == 2

View File

@ -266,16 +266,16 @@ end
# end # end
# using the axis extrema and limit overrides, return the min/max value for this axis # using the axis extrema and limit overrides, return the min/max value for this axis
gr_x_axislims(sp::Subplot) = axis_limits(sp.attr[:xaxis], :x) gr_x_axislims(sp::Subplot) = axis_limits(sp.attr[:xaxis])
gr_y_axislims(sp::Subplot) = axis_limits(sp.attr[:yaxis], :y) gr_y_axislims(sp::Subplot) = axis_limits(sp.attr[:yaxis])
gr_z_axislims(sp::Subplot) = axis_limits(sp.attr[:zaxis], :z) gr_z_axislims(sp::Subplot) = axis_limits(sp.attr[:zaxis])
gr_xy_axislims(sp::Subplot) = gr_x_axislims(sp)..., gr_y_axislims(sp)... gr_xy_axislims(sp::Subplot) = gr_x_axislims(sp)..., gr_y_axislims(sp)...
function gr_lims(axis::Axis, adjust::Bool, expand = nothing) function gr_lims(axis::Axis, adjust::Bool, expand = nothing)
if expand != nothing if expand != nothing
expand_extrema!(axis, expand) expand_extrema!(axis, expand)
end end
lims = axis_limits(axis, axis[:letter]) lims = axis_limits(axis)
if adjust if adjust
GR.adjustrange(lims...) GR.adjustrange(lims...)
else else
@ -668,7 +668,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
if axes_2d if axes_2d
GR.setlinewidth(1) GR.setlinewidth(1)
GR.setlinetype(GR.LINETYPE_DOTTED) # GR.setlinetype(GR.LINETYPE_DOTTED)
GR.setlinecolorind(gr_getcolorind(sp.attr[:foreground_color_grid])) GR.setlinecolorind(gr_getcolorind(sp.attr[:foreground_color_grid]))
ticksize = 0.0075 * diag ticksize = 0.0075 * diag
if outside_ticks if outside_ticks

View File

@ -52,14 +52,18 @@ supportedArgs(::UnicodePlotsBackend) = [
# :z, # :z,
] ]
supportedAxes(::UnicodePlotsBackend) = [:auto, :left] supportedAxes(::UnicodePlotsBackend) = [:auto, :left]
supportedTypes(::UnicodePlotsBackend) = [:none, :line, :path, :steppre, :steppost, :sticks, :scatter, :hist2d, :hexbin, :hist, :bar, :hline, :vline] supportedTypes(::UnicodePlotsBackend) = [
:path, :steppre, :steppost, :scatter,
:hist2d, :hline, :vline
]
supportedStyles(::UnicodePlotsBackend) = [:auto, :solid] supportedStyles(::UnicodePlotsBackend) = [:auto, :solid]
supportedMarkers(::UnicodePlotsBackend) = [:none, :auto, :ellipse] supportedMarkers(::UnicodePlotsBackend) = [:none, :auto, :ellipse]
supportedScales(::UnicodePlotsBackend) = [:identity] supportedScales(::UnicodePlotsBackend) = [:identity]
subplotSupported(::UnicodePlotsBackend) = true subplotSupported(::UnicodePlotsBackend) = true
# don't warn on unsupported... there's just too many warnings!!
warnOnUnsupportedArgs(pkg::UnicodePlotsBackend, d::KW) = nothing
# -------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------
@ -72,80 +76,136 @@ end
# ------------------------------- # -------------------------------
# convert_size_from_pixels(sz) =
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning # do all the magic here... build it all at once, since we need to know about all the series at the very beginning
function rebuildUnicodePlot!(plt::Plot) function rebuildUnicodePlot!(plt::Plot)
plt.o = []
for sp in plt.subplots
xaxis = sp.attr[:xaxis]
yaxis = sp.attr[:yaxis]
xlim = axis_limits(xaxis)
ylim = axis_limits(yaxis)
# figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax] # make vectors
sargs = plt.seriesargs xlim = [xlim[1], xlim[2]]
iargs = plt.attr ylim = [ylim[1], ylim[2]]
# get the x/y limits # we set x/y to have a single point, since we need to create the plot with some data.
if get(iargs, :xlims, :auto) == :auto # since this point is at the bottom left corner of the plot, it shouldn't actually be shown
xlim = [Inf, -Inf] x = Float64[xlim[1]]
for d in sargs y = Float64[ylim[1]]
_expand_limits(xlim, d[:x])
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
width, height = plt.attr[:size]
o = UnicodePlots.Plot(x, y;
width = width,
height = height,
title = sp.attr[:title],
xlim = xlim,
ylim = ylim
)
# set the axis labels
UnicodePlots.xlabel!(o, xaxis[:guide])
UnicodePlots.ylabel!(o, yaxis[:guide])
# now use the ! functions to add to the plot
for series in series_list(sp)
addUnicodeSeries!(o, series.d, sp.attr[:legend] != :none, xlim, ylim)
end
# save the object
push!(plt.o, o)
end end
else
xmin, xmax = iargs[:xlims]
xlim = [xmin, xmax]
end
if get(iargs, :ylims, :auto) == :auto
ylim = [Inf, -Inf]
for d in sargs
_expand_limits(ylim, d[:y])
end
else
ymin, ymax = iargs[:ylims]
ylim = [ymin, ymax]
end
# we set x/y to have a single point, since we need to create the plot with some data.
# since this point is at the bottom left corner of the plot, it shouldn't actually be shown
x = Float64[xlim[1]]
y = Float64[ylim[1]]
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
width, height = iargs[:size]
o = UnicodePlots.Plot(x, y; width = width,
height = height,
title = iargs[:title],
# labels = iargs[:legend],
xlim = xlim,
ylim = ylim)
# set the axis labels
UnicodePlots.xlabel!(o, iargs[:xguide])
UnicodePlots.ylabel!(o, iargs[:yguide])
# now use the ! functions to add to the plot
for d in sargs
addUnicodeSeries!(o, d, iargs[:legend] != :none, xlim, ylim)
end
# save the object
plt.o = o
end end
# # do all the magic here... build it all at once, since we need to know about all the series at the very beginning
# function rebuildUnicodePlot!(plt::Plot)
#
# # figure out the plotting area xlim = [xmin, xmax] and ylim = [ymin, ymax]
# sargs = plt.seriesargs
# iargs = plt.attr
#
# # get the x/y limits
# if get(iargs, :xlims, :auto) == :auto
# xlim = [Inf, -Inf]
# for d in sargs
# _expand_limits(xlim, d[:x])
# end
# else
# xmin, xmax = iargs[:xlims]
# xlim = [xmin, xmax]
# end
#
# if get(iargs, :ylims, :auto) == :auto
# ylim = [Inf, -Inf]
# for d in sargs
# _expand_limits(ylim, d[:y])
# end
# else
# ymin, ymax = iargs[:ylims]
# ylim = [ymin, ymax]
# end
#
# # we set x/y to have a single point, since we need to create the plot with some data.
# # since this point is at the bottom left corner of the plot, it shouldn't actually be shown
# x = Float64[xlim[1]]
# y = Float64[ylim[1]]
#
# # create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
# width, height = iargs[:size]
# o = UnicodePlots.Plot(x, y; width = width,
# height = height,
# title = iargs[:title],
# # labels = iargs[:legend],
# xlim = xlim,
# ylim = ylim)
#
# # set the axis labels
# UnicodePlots.xlabel!(o, iargs[:xguide])
# UnicodePlots.ylabel!(o, iargs[:yguide])
#
# # now use the ! functions to add to the plot
# for d in sargs
# addUnicodeSeries!(o, d, iargs[:legend] != :none, xlim, ylim)
# end
#
# # save the object
# plt.o = o
# end
# add a single series # add a single series
function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim)
# get the function, or special handling for step/bar/hist # get the function, or special handling for step/bar/hist
st = d[:seriestype] st = d[:seriestype]
# handle hline/vline separately
if st in (:hline,:vline)
for yi in d[:y]
if st == :hline
UnicodePlots.lineplot!(o, xlim, [yi,yi])
else
UnicodePlots.lineplot!(o, [yi,yi], ylim)
end
end
return
# elseif st == :bar
# UnicodePlots.barplot!(o, d[:x], d[:y])
# return
# elseif st == :hist
# UnicodePlots.histogram!(o, d[:y], bins = d[:bins])
# return
elseif st == :hist2d
UnicodePlots.densityplot!(o, d[:x], d[:y])
return
# handle hline/vline separately
if st in (:hline,:vline)
for yi in d[:y]
if st == :hline
UnicodePlots.lineplot!(o, xlim, [yi,yi])
else
UnicodePlots.lineplot!(o, [yi,yi], ylim)
end
end end
return
end
stepstyle = :post stepstyle = :post
if st == :path if st == :path
@ -195,26 +255,26 @@ function _create_backend_figure(plt::Plot{UnicodePlotsBackend})
# plt # plt
end end
function _series_added(plt::Plot{UnicodePlotsBackend}, series::Series) # function _series_added(plt::Plot{UnicodePlotsBackend}, series::Series)
d = series.d # d = series.d
# TODO don't need these once the "bar" series recipe is done # # TODO don't need these once the "bar" series recipe is done
if d[:seriestype] in (:sticks, :bar) # if d[:seriestype] in (:sticks, :bar)
d = barHack(; d...) # d = barHack(; d...)
elseif d[:seriestype] == :hist # elseif d[:seriestype] == :hist
d = barHack(; histogramHack(; d...)...) # d = barHack(; histogramHack(; d...)...)
end # end
# push!(plt.seriesargs, d) # # push!(plt.seriesargs, d)
# plt # # plt
end # end
#
#
function _update_plot_object(plt::Plot{UnicodePlotsBackend}, d::KW) # function _update_plot_object(plt::Plot{UnicodePlotsBackend}, d::KW)
for k in (:title, :xguide, :yguide, :xlims, :ylims) # for k in (:title, :xguide, :yguide, :xlims, :ylims)
if haskey(d, k) # if haskey(d, k)
plt.attr[k] = d[k] # plt.attr[k] = d[k]
end # end
end # end
end # end
# ------------------------------- # -------------------------------
@ -254,9 +314,10 @@ end
# end # end
function Base.display(::PlotsDisplay, plt::Plot{UnicodePlotsBackend}) function _display(plt::Plot{UnicodePlotsBackend})
rebuildUnicodePlot!(plt) rebuildUnicodePlot!(plt)
show(plt.o) map(show, plt.o)
nothing
end end

View File

@ -151,7 +151,7 @@ function _apply_series_recipe(plt::Plot, d::KW)
if isa(data, RecipeData) if isa(data, RecipeData)
_apply_series_recipe(plt, data.d) _apply_series_recipe(plt, data.d)
else else
warn("Unhandled series: $(series_list)") warn("Unhandled recipe: $(data)")
break break
end end
end end

View File

@ -226,11 +226,25 @@ end
() ()
end end
# create a path from steps @recipe function f(::Type{Val{:sticks}}, x, y, z)
@recipe function f(::Type{Val{:steppre}}, x, y, z) nx = length(x)
n = 3nx
newx, newy = zeros(n), zeros(n)
for i=1:nx
rng = 3i-2:3i
newx[rng] = x[i]
newy[rng] = [0., y[i], 0.]
end
d[:x], d[:y] = newx, newy
d[:seriestype] = :path
()
end end
# # create a path from steps
# @recipe function f(::Type{Val{:steppre}}, x, y, z)
#
# end
# midpoints = d[:x] # midpoints = d[:x]
# heights = d[:y] # heights = d[:y]