From b3ac38a6f11956a38d80d8fa23de715cc5364870 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Wed, 25 May 2016 15:17:51 -0400 Subject: [PATCH] working on gr --- src/backends/gr.jl | 218 +++++++++++++++++++++++++++++---------------- src/recipes.jl | 82 +++++++++++++++-- 2 files changed, 216 insertions(+), 84 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e9d19fac..7f912598 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -38,8 +38,8 @@ supportedArgs(::GRBackend) = [ supportedAxes(::GRBackend) = _allAxes supportedTypes(::GRBackend) = [ :path, :steppre, :steppost, - :scatter, :hist2d, :hexbin, - :bar, :sticks, + :scatter, :hist2d, :hexbin, + :sticks, :hline, :vline, :heatmap, :pie, :image, #:ohlc, :contour, :path3d, :scatter3d, :surface, :wireframe ] @@ -145,8 +145,8 @@ end function gr_polymarker(d, x, y) if d[:vertices] != :none vertices= d[:vertices] - dx = Float64[el[1] for el in vertices] * 0.01 - dy = Float64[el[2] for el in vertices] * 0.01 + dx = Float64[el[1] for el in vertices] * 0.03 + dy = Float64[el[2] for el in vertices] * 0.03 GR.selntran(0) GR.setfillcolorind(gr_getcolorind(d[:markercolor])) GR.setfillintstyle(GR.INTSTYLE_SOLID) @@ -160,26 +160,40 @@ function gr_polymarker(d, x, y) end end -# TODO: simplify function gr_polyline(x, y) - if NaN in x || NaN in y - i = 1 - j = 1 - n = length(x) - while i < n - while j < n && x[j] != Nan && y[j] != NaN - j += 1 - end - if i < j - GR.polyline(x[i:j], y[i:j]) - end - i = j + 1 + i = j = 1 + n = length(x) + while i < n + while j < n && x[j] != NaN && y[j] != NaN + j += 1 end - else - GR.polyline(x, y) + if i < j + GR.polyline(x[i:j], y[i:j]) + end + i = j + 1 end end +# # TODO: simplify +# function gr_polyline(x, y) +# if NaN in x || NaN in y +# i = 1 +# j = 1 +# n = length(x) +# while i < n +# while j < n && x[j] != Nan && y[j] != NaN +# j += 1 +# end +# if i < j +# GR.polyline(x[i:j], y[i:j]) +# end +# i = j + 1 +# end +# else +# GR.polyline(x, y) +# end +# end + function gr_polaraxes(rmin, rmax) GR.savestate() GR.setlinetype(GR.LINETYPE_SOLID) @@ -270,26 +284,50 @@ function gr_fillrect(series::Series, l, r, b, t) GR.fillrect(l, r, b, t) end -function gr_barplot(series::Series, x, y) - # x, y = d[:x], d[:y] - n = length(y) - if length(x) == n + 1 - # 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]) +function gr_draw_markers(series::Series) + d = series.d + msize = 0.5 * d[:markersize] + GR.setmarkercolorind(gr_getcolorind(d[:markercolor])) + gr_setmarkershape(d) + if typeof(msize) <: Number + GR.setmarkersize(msize) + if length(d[:x]) > 0 + gr_polymarker(d, d[:x], d[:y]) 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))") + c = d[:markercolor] + GR.setcolormap(-GR.COLORMAP_GLOWING) + for i = 1:length(d[:x]) + if isa(c, ColorGradient) && d[:marker_z] != nothing + ci = round(Int, 1000 + d[:marker_z][i] * 255) + GR.setmarkercolorind(ci) + end + GR.setmarkersize(msize[i]) + gr_polymarker(d, [d[:x][i]], [d[:y][i]]) + end end end +# function gr_barplot(series::Series, x, y) +# # x, y = d[:x], d[:y] +# n = length(y) +# if length(x) == n + 1 +# # 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 +# end + # -------------------------------------------------------------------------------------- @@ -350,7 +388,7 @@ function gr_display(plt::Plot) # fill in the viewport_canvas background gr_fill_viewport(viewport_canvas, plt.attr[:background_color_outside]) - @show "PLOT SETUP" plt.layout.bbox ratio viewport_canvas + # @show "PLOT SETUP" plt.layout.bbox ratio viewport_canvas # subplots: for sp in plt.subplots @@ -365,7 +403,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # the viewports for this subplot viewport_subplot = gr_viewport_from_bbox(bbox(sp), w, h, viewport_canvas) viewport_plotarea = gr_viewport_from_bbox(plotarea(sp), w, h, viewport_canvas) - @show "SUBPLOT",sp.attr[:subplot_index] bbox(sp) plotarea(sp) viewport_subplot viewport_plotarea + # @show "SUBPLOT",sp.attr[:subplot_index] bbox(sp) plotarea(sp) viewport_subplot viewport_plotarea # fill in the plot area background gr_fill_viewport(viewport_plotarea, sp.attr[:background_color_inside]) @@ -689,6 +727,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setlinecolorind(gr_getcolorind(d[:linecolor])) end + # @show "HERE" d[:markershape] if ispolar(sp) xmin, xmax, ymin, ymax = viewport_plotarea ymax -= 0.05 * (xmax - xmin) @@ -708,19 +747,38 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) x[i] = r[i] * cos(phi[i]) y[i] = r[i] * sin(phi[i]) end - GR.polyline(x, y) + gr_polyline(x, y) elseif st == :path - if length(d[:x]) > 1 - if d[:fillrange] != nothing + x, y = d[:x], d[:y] + if length(x) > 1 + frng = d[:fillrange] + if frng != nothing GR.setfillcolorind(gr_getcolorind(d[:fillcolor])) GR.setfillintstyle(GR.INTSTYLE_SOLID) - GR.fillarea([d[:x][1]; d[:x]; d[:x][length(d[:x])]], [d[:fillrange]; d[:y]; d[:fillrange]]) + # @show map(length,(d[:x], d[:fillrange], d[:y])) + # @show size([d[:x][1]; d[:x]; d[:x][length(d[:x])]], [d[:fillrange]; d[:y]; d[:fillrange]]) + # GR.fillarea([d[:x][1]; d[:x]; d[:x][length(d[:x])]], [d[:fillrange]; d[:y]; d[:fillrange]]) + frng = isa(frng, Number) ? Float64[frng] : frng + nx, ny, nf = length(x), length(y), length(frng) + n = max(nx, ny) + fx, fy = zeros(2n), zeros(2n) + for i=1:n + fx[i] = fx[end-i+1] = x[mod1(i,nx)] + fy[i] = y[mod1(i,ny)] + fy[end-i+1] = frng[mod1(i,nf)] + end + GR.fillarea(fx, fy) end - GR.polyline(d[:x], d[:y]) + gr_polyline(x, y) end # legend[idx] = true + if d[:markershape] != :none && axes_2d + gr_draw_markers(series) + end + + # # TODO: use recipe # elseif st == :line # if length(d[:x]) > 1 @@ -746,7 +804,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) j += 2 end if n > 1 - GR.polyline(x, y) + gr_polyline(x, y) end # legend[idx] = true @@ -754,44 +812,48 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :sticks x, y = d[:x], d[:y] for i = 1:length(y) - GR.polyline([x[i], x[i]], [ymin, y[i]]) + gr_polyline([x[i], x[i]], [ymin, y[i]]) end # legend[idx] = true - elseif st == :scatter || (d[:markershape] != :none && axes_2d) - GR.setmarkercolorind(gr_getcolorind(d[:markercolor])) - gr_setmarkershape(d) - if typeof(d[:markersize]) <: Number - GR.setmarkersize(d[:markersize] / 4.0) - if length(d[:x]) > 0 - gr_polymarker(d, d[:x], d[:y]) - end - else - c = d[:markercolor] - GR.setcolormap(-GR.COLORMAP_GLOWING) - for i = 1:length(d[:x]) - if isa(c, ColorGradient) && d[:marker_z] != nothing - ci = round(Int, 1000 + d[:marker_z][i] * 255) - GR.setmarkercolorind(ci) - end - GR.setmarkersize(d[:markersize][i] / 4.0) - gr_polymarker(d, [d[:x][i]], [d[:y][i]]) - end + elseif st == :scatter + if d[:markershape] != :none && axes_2d + gr_draw_markers(series) end - # legend[idx] = true - - # TODO: use recipe - elseif st == :bar - gr_barplot(series, d[:x], d[:y]) - # for i = 1:length(y) - # gr_fillrect(series, i-0.4, i+0.4, max(0, ymin), y[i]) - # # GR.setfillcolorind(gr_getcolorind(d[:fillcolor])) - # # GR.setfillintstyle(GR.INTSTYLE_SOLID) - # # GR.fillrect(i-0.4, i+0.4, max(0, ymin), y[i]) - # # GR.setfillcolorind(fg) - # # GR.setfillintstyle(GR.INTSTYLE_HOLLOW) - # # GR.fillrect(i-0.4, i+0.4, max(0, ymin), y[i]) + # @show "HERE" d[:markershape] + # GR.setmarkercolorind(gr_getcolorind(d[:markercolor])) + # gr_setmarkershape(d) + # if typeof(d[:markersize]) <: Number + # GR.setmarkersize(d[:markersize] / 4.0) + # if length(d[:x]) > 0 + # gr_polymarker(d, d[:x], d[:y]) + # end + # else + # c = d[:markercolor] + # GR.setcolormap(-GR.COLORMAP_GLOWING) + # for i = 1:length(d[:x]) + # if isa(c, ColorGradient) && d[:marker_z] != nothing + # ci = round(Int, 1000 + d[:marker_z][i] * 255) + # GR.setmarkercolorind(ci) + # end + # GR.setmarkersize(d[:markersize][i] / 4.0) + # gr_polymarker(d, [d[:x][i]], [d[:y][i]]) + # end # end + # legend[idx] = true + + # # TODO: use recipe + # elseif st == :bar + # gr_barplot(series, d[:x], d[:y]) + # # for i = 1:length(y) + # # gr_fillrect(series, i-0.4, i+0.4, max(0, ymin), y[i]) + # # # GR.setfillcolorind(gr_getcolorind(d[:fillcolor])) + # # # GR.setfillintstyle(GR.INTSTYLE_SOLID) + # # # GR.fillrect(i-0.4, i+0.4, max(0, ymin), y[i]) + # # # GR.setfillcolorind(fg) + # # # GR.setfillintstyle(GR.INTSTYLE_HOLLOW) + # # # GR.fillrect(i-0.4, i+0.4, max(0, ymin), y[i]) + # # end # # TODO: use recipe # elseif st in [:hist, :density] @@ -811,9 +873,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st in [:hline, :vline] for xy in d[:y] if st == :hline - GR.polyline([xmin, xmax], [xy, xy]) + gr_polyline([xmin, xmax], [xy, xy]) else - GR.polyline([xy, xy], [ymin, ymax]) + gr_polyline([xy, xy], [ymin, ymax]) end end @@ -985,7 +1047,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) GR.text(x[3] + 0.01, y[3], string(labels[i])) end - GR.polyline(x, y) + gr_polyline(x, y) a1 = a2 end GR.selntran(1) diff --git a/src/recipes.jl b/src/recipes.jl index 9423237c..4f9124d1 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -231,13 +231,53 @@ end end + +# midpoints = d[:x] +# heights = d[:y] +# fillrange = d[:fillrange] == nothing ? 0.0 : d[:fillrange] +# +# # estimate the edges +# dists = diff(midpoints) * 0.5 +# edges = zeros(length(midpoints)+1) +# for i in 1:length(edges) +# if i == 1 +# edge = midpoints[1] - dists[1] +# elseif i == length(edges) +# edge = midpoints[i-1] + dists[i-2] +# else +# edge = midpoints[i-1] + dists[i-1] +# end +# edges[i] = edge +# end +# +# x = Float64[] +# y = Float64[] +# for i in 1:length(heights) +# e1, e2 = edges[i:i+1] +# append!(x, [e1, e1, e2, e2]) +# append!(y, [fillrange, heights[i], heights[i], fillrange]) +# end +# +# d[:x] = x +# d[:y] = y +# d[:seriestype] = :path +# d[:fillrange] = fillrange + # 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]) + edges = if nx == ny + # x is centers, calc the edges + # TODO: use bar_width, etc + midpoints = x + halfwidths = diff(midpoints) * 0.5 + Float64[if i == 1 + midpoints[1] - halfwidths[1] + elseif i == ny+1 + midpoints[i-1] + halfwidths[i-2] + else + midpoints[i-1] + halfwidths[i-1] + end for i=1:ny+1] elseif nx == ny + 1 # x is edges x @@ -245,9 +285,39 @@ end 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 + # make fillto a vector... default fills to 0 + fillto = d[:fillrange] + if fillto == nothing + fillto = zeros(1) + elseif isa(fillto, Number) + fillto = Float64[fillto] + end + nf = length(fillto) - d[:seriestype] = :steppre + npts = 3ny + 1 + heights = y + x = zeros(npts) + y = zeros(npts) + fillrng = zeros(npts) + + # create the path in triplets. after the first bottom-left coord of the first bar: + # add the top-left, top-right, and bottom-right coords for each height + 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 + + d[:x] = x + d[:y] = y + d[:fillrange] = fillrng + d[:seriestype] = :path () end