From c3808c0c5b4ecfbf06ff42dd353e1d4edb2a0364 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 29 Dec 2015 20:07:44 +0100 Subject: [PATCH] gr.jl: implemented line/scatter plots --- src/backends/gr.jl | 130 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 8 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 5888a61f..960bc8e8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1,19 +1,29 @@ # https://github.com/jheinen/GR.jl +fig = Dict() + +fig[:size] = [500, 500] + +@compat const gr_linetype = Dict( + :auto => 0, :solid => 1, :dash => 2, :dot => 3, :dashdot => 4, + :dashdotdot => -1 ) + +@compat const gr_markertype = Dict( + :none => 1, :ellipse => -1, :rect => -7, :diamond => -13, + :utriangle => -3, :dtriangle => -5, :pentagon => -14, + :cross => 2, :xcross => 5, :star5 => 3 ) + function _create_plot(pkg::GRPackage; kw...) + global fig d = Dict(kw) - GR.title(d[:title]) - GR.xlabel(d[:xlabel]) - GR.ylabel(d[:ylabel]) + fig[:size] = d[:size] Plot(nothing, pkg, 0, d, Dict[]) end - function _add_series(::GRPackage, plt::Plot; kw...) + global fig d = Dict(kw) - # TODO: add one series to the underlying package - GR.plot(d[:x], d[:y]) push!(plt.seriesargs, d) plt end @@ -29,11 +39,115 @@ end function _before_update_plot(plt::Plot{GRPackage}) end -# TODO: override this to update plot items (title, xlabel, etc) after creation function _update_plot(plt::Plot{GRPackage}, d::Dict) + global fig + + GR.clearws() + + mwidth, mheight, width, height = GR.inqdspsize() + w, h = fig[:size] + if w > h + ratio = float(h) / w + size = mwidth * w / width + GR.setwsviewport(0, size, 0, size * ratio) + GR.setwswindow(0, 1, 0, ratio) + viewport = [0.1, 0.95, 0.1 * ratio, 0.95 * ratio] + else + ratio = float(w) / h + size = mheight * h / height + GR.setwsviewport(0, size * ratio, 0, size) + GR.setwswindow(0, ratio, 0, 1) + viewport = [0.1 * ratio, 0.95 * ratio, 0.1, 0.95] + end + + xmin = ymin = typemax(Float64) + xmax = ymax = typemin(Float64) + for p in plt.seriesargs + x, y = p[:x], p[:y] + xmin = min(minimum(x), xmin) + xmax = max(maximum(x), xmax) + ymin = min(minimum(y), ymin) + ymax = max(maximum(y), ymax) + end + + xmin, xmax = GR.adjustlimits(xmin, xmax) + ymin, ymax = GR.adjustlimits(ymin, ymax) + majorx = 5 + xtick = GR.tick(xmin, xmax) / majorx + majory = 5 + ytick = GR.tick(ymin, ymax) / majory + + GR.setviewport(viewport[1], viewport[2], viewport[3], viewport[4]) + GR.setwindow(xmin, xmax, ymin, ymax) + + charheight = 0.03 * (viewport[4] - viewport[3]) + GR.setcharheight(charheight) + GR.grid(xtick, ytick, 0, 0, majorx, majory) + ticksize = 0.0125 * (viewport[2] - viewport[1]) + GR.axes(xtick, ytick, xmin, ymin, majorx, majory, ticksize) + GR.axes(xtick, ytick, xmax, ymax, -majorx, -majory, -ticksize) + + if haskey(d, :title) + GR.savestate() + GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP) + GR.text(0.5, min(ratio, 1), d[:title]) + GR.restorestate() + end + if haskey(d, :xlabel) + GR.savestate() + GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM) + GR.text(0.5, 0, d[:xlabel]) + GR.restorestate() + end + if haskey(d, :ylabel) + GR.savestate() + GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP) + GR.setcharup(-1, 0) + GR.text(0, 0.5 * (viewport[3] + viewport[4]), d[:ylabel]) + GR.restorestate() + end + + GR.savestate() + haskey(d, :linewidth) && GR.setlinewidth(d[:linewidth]) + haskey(d, :linestyle) && GR.setlinetype(gr_linetype[d[:linestyle]]) + haskey(d, :markersize) && GR.setmarkersize(d[:markersize]) + haskey(d, :markershape) && GR.setmarkertype(gr_markertype[d[:markershape]]) + GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) + + for p in plt.seriesargs + GR.uselinespec("") + if p[:linetype] == :path + GR.polyline(p[:x], p[:y]) + elseif p[:linetype] == :scatter + GR.polymarker(p[:x], p[:y]) + end + end + + px = viewport[2] - 0.15 + py = viewport[4] - 0.15 + GR.selntran(0) + for p in plt.seriesargs + GR.uselinespec("") + if p[:linetype] == :path + GR.polyline([px, px + 0.04], [py, py]) + elseif p[:linetype] == :scatter + GR.polymarker([px, px + 0.02], [py, py]) + end + GR.text(px + 0.05, py, p[:label]) + py -= 0.03 + end + GR.selntran(1) + + GR.restorestate() + + GR.updatews() end function _update_plot_pos_size(plt::PlottingObject{GRPackage}, d::Dict) + global fig + if haskey(d, :size) + fig[:size] = d[:size] + end end # ---------------------------------------------------------------- @@ -44,7 +158,7 @@ function Base.getindex(plt::Plot{GRPackage}, i::Int) series = plt.o.lines[i] series.x, series.y end - + function Base.setindex!(plt::Plot{GRPackage}, xy::Tuple, i::Integer) series = plt.o.lines[i] series.x, series.y = xy