From e381c13dc66f534ba6e4edc1447c1466533bc644 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Sat, 31 Dec 2016 15:41:11 -0500 Subject: [PATCH 01/26] Initial support for InspectDR. --- src/backends.jl | 1 + src/backends/inspectdr.jl | 411 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100644 src/backends/inspectdr.jl diff --git a/src/backends.jl b/src/backends.jl index 16fcad2c..779b91cc 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -276,6 +276,7 @@ end @init_backend GR @init_backend GLVisualize @init_backend PGFPlots +@init_backend InspectDR # --------------------------------------------------------- diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl new file mode 100644 index 00000000..fb2893f5 --- /dev/null +++ b/src/backends/inspectdr.jl @@ -0,0 +1,411 @@ + +# https://github.com/ma-laforge/InspectDR.jl + +#=TODO: +Not supported by InspectDR: + :foreground_color_title (font), title_location + :background_color_legend, :background_color_inside, :background_color_outside, + :foreground_color_grid, :foreground_color_legend, :foreground_color_title, + :foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text, + :polar, + + +Add in functionality to Plots.jl: + :annotations, :aspect_ratio, +=# + +# --------------------------------------------------------------------------- +#TODO: remove features +const _inspectdr_attr = merge_with_base_supported([ + :annotations, + :background_color_legend, :background_color_inside, :background_color_outside, + :foreground_color_grid, :foreground_color_legend, :foreground_color_title, + :foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text, + :label, + :linecolor, :linestyle, :linewidth, :linealpha, + :markershape, :markercolor, :markersize, :markeralpha, + :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, + :markerstrokestyle, #Causes warning not to have it... what is this? + :fillcolor, :fillalpha, #:fillrange, +# :bins, :bar_width, :bar_edges, :bar_position, + :title, :title_location, :titlefont, + :window_title, + :guide, :lims, :scale, #:ticks, :flip, :rotation, + :tickfont, :guidefont, :legendfont, + :grid, :legend, #:colorbar, +# :marker_z, +# :line_z, +# :levels, + # :ribbon, :quiver, :arrow, +# :orientation, + :overwrite_figure, +# :polar, +# :normalize, :weights, +# :contours, :aspect_ratio, + :match_dimensions, +# :clims, +# :inset_subplots, + :dpi, +# :colorbar_title, + ]) +const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot] +const _inspectdr_seriestype = [ + :path, :scatter #, :steppre, :steppost, :shape, + ] +#see: _allMarkers, _shape_keys +const _inspectdr_marker = Symbol[ + :none, + :auto, + :circle, + :rect, + :diamond, +# :hexagon, + :cross, + :xcross, + :utriangle, + :dtriangle, + :rtriangle, + :ltriangle, +# :pentagon, +# :heptagon, +# :octagon, +# :star4, +# :star5, +# :star6, +# :star7, + :star8, +# :vline, +# :hline, + :+, + :x, +] + +const _inspectdr_scale = [:identity, :ln, :log2, :log10] #Does not really support ln, (plot using log10 instead). + +#Do we avoid Map to avoid possible pre-comile issues? +function _inspectdr_mapglyph(s::Symbol) + s == :rect && return :square + s == :utriangle && return :uarrow + s == :dtriangle && return :darrow + s == :ltriangle && return :larrow + s == :rtriangle && return :rarrow + s == :xcross && return :diagcross + s == :star8 && return :* + +#= Actually supported: + :square, :diamond, + :uarrow, :darrow, :larrow, :rarrow, #usually triangles + :cross, :+, :diagcross, :x, + :circle, :o, :star, :*, +=# + + return s +end + +# py_marker(markers::AVec) = map(py_marker, markers) +function _inspectdr_mapglyph(markers::AVec) + warn("Vectors of markers are currently unsupported in InspectDR.") + _inspectdr_mapglyph(markers[1]) +end + +_inspectdr_mapglyphsize(v::Real) = v +function _inspectdr_mapglyphsize(v::Vector) + warn("Vectors of marker sizes are currently unsupported in InspectDR.") + _inspectdr_mapglyphsize(v[1]) +end + +_inspectdr_mapcolor(v::Colorant) = v +function _inspectdr_mapcolor(g::PlotUtils.ColorGradient) + warn("Vectors of colors are currently unsupported in InspectDR.") + #Pick middle color: + _inspectdr_mapcolor(g.colors[div(1+end,2)]) +end + +#Hack: suggested point size does not seem adequate relative to plot size, for some reason. +_inspectdr_mapptsize(v) = 1.5*v + +# --------------------------------------------------------------------------- +#InspectDR-dependent structures and method signatures. +#(To be evalutated only once ready to load module) +const _inspectdr_depcode = quote + +import InspectDR +export InspectDR + +type InspectDRPlotEnv + #Stores reference to active plot GUI: + cur_gui::Nullable{InspectDR.GtkPlot} +end +InspectDRPlotEnv() = InspectDRPlotEnv(nothing) +const _inspectdr_plotenv = InspectDRPlotEnv() +end #_inspectdr_depcode +# --------------------------------------------------------------------------- + +function _inspectdr_getscale(s::Symbol) +#TODO: Support :ln, :asinh, :sqrt + if :log2 == s + return InspectDR.AxisScale(:log2) + elseif :log10 == s + return InspectDR.AxisScale(:log10) + elseif :ln == s + return InspectDR.AxisScale(:log10) #At least it will be a log-plot + else #identity + return InspectDR.AxisScale(:lin) + end +end + +# --------------------------------------------------------------------------- + +function _initialize_backend(::InspectDRBackend; kw...) + eval(_inspectdr_depcode) +end + +# --------------------------------------------------------------------------- + +# Create the window/figure for this backend. +function _create_backend_figure(plt::Plot{InspectDRBackend}) + mplot = plt.o + + #:overwrite_figure: want to reuse current figure + if plt[:overwrite_figure] && isa(mplot, InspectDR.Multiplot) + mplot.subplots = [] #Reset + if !isnull(_inspectdr_plotenv.cur_gui) #Create new one: + gplot = get(_inspectdr_plotenv.cur_gui) + gplot.src = mplot + end + else #want new one: + mplot = InspectDR.Multiplot() + if !isnull(_inspectdr_plotenv.cur_gui) #Create new one: + _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) + end + end + + #break link with old subplots + for sp in plt.subplots + sp.o = nothing + end + plt.o = mplot + return mplot +end + +# --------------------------------------------------------------------------- + +# # this is called early in the pipeline, use it to make the plot current or something +# function _prepare_plot_object(plt::Plot{InspectDRBackend}) +# end + +# --------------------------------------------------------------------------- + +# Set up the subplot within the backend object. +function _initialize_subplot(plt::Plot{InspectDRBackend}, sp::Subplot{InspectDRBackend}) + plot = sp.o + + #Don't do anything without a "subplot" object: Will process later. + if nothing == plot; return; end + plot.data = [] + + return plot +end + +# --------------------------------------------------------------------------- + +# Add one series to the underlying backend object. +# Called once per series +# NOTE: Seems to be called when user calls plot()... even if backend +# plot, sp.o has not yet been constructed... +function _series_added(plt::Plot{InspectDRBackend}, series::Series) + st = series[:seriestype] + sp = series[:subplot] + plot = sp.o + + #Don't do anything without a "subplot" object: Will process later. + if nothing == plot; return; end + + _vectorize(v) = isa(v, Vector)? v: collect(v) #InspectDR only supports vectors + x = _vectorize(series[:x]); y = _vectorize(series[:y]) + + # doesn't handle mismatched x/y - wrap data (pyplot behaviour): + nx = length(x); ny = length(y) + if nx < ny + series[:x] = Float64[x[mod1(i,nx)] for i=1:ny] + elseif ny > nx + series[:y] = Float64[y[mod1(i,ny)] for i=1:nx] + end + +#= TODO: Eventually support + series[:fillcolor] #I think this is fill under line + zorder = series[:series_plotindex] +=# + + #TODO: scale width & sizes + if st in (:path, :scatter) #, :steppre, :steppost) + #NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think). + linewidth = series[:linewidth] + #More efficient & allows some support for markerstrokewidth: + _style = (0==linewidth? :none: series[:linestyle]) + wfrm = InspectDR.add(plot, x, y, id=series[:label]) + wfrm.line = InspectDR.line( + style = _style, + width = series[:linewidth], + color = series[:linecolor], + ) + #InspectDR does not control markerstrokewidth independently. + if :none == _style + #Use this property only if no line is displayed: + wfrm.line.width = series[:markerstrokewidth] + end + wfrm.glyph = InspectDR.glyph( + shape = _inspectdr_mapglyph(series[:markershape]), + size = _inspectdr_mapglyphsize(series[:markersize]), + color = _inspectdr_mapcolor(series[:markerstrokecolor]), + fillcolor = _inspectdr_mapcolor(series[:markercolor]), + ) + end + return +end + +# --------------------------------------------------------------------------- + +# When series data is added/changed, this callback can do dynamic updates to the backend object. +# note: if the backend rebuilds the plot from scratch on display, then you might not do anything here. +function _series_updated(plt::Plot{InspectDRBackend}, series::Series) + #Nothing to do +end + +# --------------------------------------------------------------------------- + +function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) + const gridon = InspectDR.grid(vmajor=true, hmajor=true) + const gridoff = InspectDR.grid() + const plot = sp.o + + xaxis = sp[:xaxis]; yaxis = sp[:yaxis] + xscale = _inspectdr_getscale(xaxis[:scale]) + yscale = _inspectdr_getscale(yaxis[:scale]) + plot.axes = InspectDR.AxesRect(xscale, yscale) + xmin, xmax = axis_limits(xaxis) + ymin, ymax = axis_limits(yaxis) + #TODO: not sure which extents we should be modifying. + plot.ext = InspectDR.PExtents2D() #reset + plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax) + a = plot.annotation + a.title = sp[:title] + a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide] + + l = plot.layout + l.fnttitle.name = sp[:titlefont].family + l.fnttitle._size = _inspectdr_mapptsize(sp[:titlefont].pointsize) + #Cannot independently control fonts of axes with InspectDR: + l.fntaxlabel.name = xaxis[:guidefont].family + l.fntaxlabel._size = _inspectdr_mapptsize(xaxis[:guidefont].pointsize) + l.fntticklabel.name = xaxis[:tickfont].family + l.fntticklabel._size = _inspectdr_mapptsize(xaxis[:tickfont].pointsize) + #No independent control of grid??? + l.grid = sp[:grid]? gridon: gridoff + leg = l.legend + leg.enabled = (sp[:legend] != :none) + #leg.width = 150 #TODO: compute??? + leg.font.name = sp[:legendfont].family + leg.font._size = _inspectdr_mapptsize(sp[:legendfont].pointsize) +end + +# called just before updating layout bounding boxes... in case you need to prep +# for the calcs +function _before_layout_calcs(plt::Plot{InspectDRBackend}) + mplot = plt.o + resize!(mplot.subplots, length(plt.subplots)) + nsubplots = length(plt.subplots) + for (i, sp) in enumerate(plt.subplots) + if !isassigned(mplot.subplots, i) + mplot.subplots[i] = InspectDR.Plot2D() + end + sp.o = mplot.subplots[i] + _initialize_subplot(plt, sp) + _inspectdr_setupsubplot(sp) + end + + #Do not yet support absolute plot positionning. + #Just try to make things look more-or less ok: + if nsubplots <= 4 + mplot.ncolumns = 2 + elseif nsubplots <= 6 + mplot.ncolumns = 3 + elseif nsubplots <= 12 + mplot.ncolumns = 4 + else + mplot.ncolumns = 5 + end + + for series in plt.series_list + _series_added(plt, series) + end +end + +# ---------------------------------------------------------------- + +# Set the (left, top, right, bottom) minimum padding around the plot area +# to fit ticks, tick labels, guides, colorbars, etc. +function _update_min_padding!(sp::Subplot{InspectDRBackend}) + sp.minpad = (20mm, 5mm, 2mm, 10mm) + #TODO: Add support for padding. +end + +# ---------------------------------------------------------------- + +# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations]) +function _update_plot_object(plt::Plot{InspectDRBackend}) + const mplot = plt.o + if nothing == mplot; return; end + if isnull(_inspectdr_plotenv.cur_gui); return; end + const gplot = get(_inspectdr_plotenv.cur_gui) + + if gplot.destroyed + _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) + else + gplot.src = mplot + InspectDR.refresh(gplot) + end + return mplot +end + +# ---------------------------------------------------------------- + +const _inspectdr_mimeformats_dpi = Dict( + "image/png" => "png" +) +const _inspectdr_mimeformats_nodpi = Dict( + "image/svg+xml" => "svg", + "application/eps" => "eps", + "image/eps" => "eps", +# "application/postscript" => "ps", #TODO: support + "application/pdf" => "pdf" +) +_inspectdr_show(io::IO, mime::MIME, ::Void) = + throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated")) +_inspectdr_show(io::IO, mime::MIME, mplot) = show(io, mime, mplot) + +for (mime, fmt) in _inspectdr_mimeformats_dpi + @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) + dpi = plt[:dpi]#TODO: support + _inspectdr_show(io, mime, plt.o) + end +end +for (mime, fmt) in _inspectdr_mimeformats_nodpi + @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) + _inspectdr_show(io, mime, plt.o) + end +end + +# ---------------------------------------------------------------- + +# Display/show the plot (open a GUI window, or browser page, for example). +function _display(plt::Plot{InspectDRBackend}) + const mplot = plt.o + if isnull(_inspectdr_plotenv.cur_gui) + _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) + else + #redundant... Plots.jl will call _update_plot_object: + #InspectDR.refresh(get(_inspectdr_plotenv.cur_gui)) + end + return get(_inspectdr_plotenv.cur_gui) +end From c78444fc24ce6f188ff72e5addfafe7364653b3d Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Wed, 4 Jan 2017 17:41:05 -0500 Subject: [PATCH 02/26] Improve support for Shapes, markers & colors. Details: Control font & background color. Support arbitrary marker shapes. Support more pre-defined markers. Support Shapes in plots. Support ln-plots. Also: Fix ncolumns. Update supported section. --- src/backends/inspectdr.jl | 186 +++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 62 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index fb2893f5..17399f52 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -2,16 +2,15 @@ # https://github.com/ma-laforge/InspectDR.jl #=TODO: + Tweak scale factor for width & other sizes + Not supported by InspectDR: - :foreground_color_title (font), title_location - :background_color_legend, :background_color_inside, :background_color_outside, - :foreground_color_grid, :foreground_color_legend, :foreground_color_title, - :foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text, + :foreground_color_grid + :foreground_color_border :polar, - Add in functionality to Plots.jl: - :annotations, :aspect_ratio, + :aspect_ratio, =# # --------------------------------------------------------------------------- @@ -50,58 +49,34 @@ const _inspectdr_attr = merge_with_base_supported([ ]) const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot] const _inspectdr_seriestype = [ - :path, :scatter #, :steppre, :steppost, :shape, + :path, :scatter, :shape #, :steppre, :steppost ] #see: _allMarkers, _shape_keys const _inspectdr_marker = Symbol[ - :none, - :auto, - :circle, - :rect, - :diamond, -# :hexagon, - :cross, - :xcross, - :utriangle, - :dtriangle, - :rtriangle, - :ltriangle, -# :pentagon, -# :heptagon, -# :octagon, -# :star4, -# :star5, -# :star6, -# :star7, - :star8, -# :vline, -# :hline, - :+, - :x, + :none, :auto, + :circle, :rect, :diamond, + :cross, :xcross, + :utriangle, :dtriangle, :rtriangle, :ltriangle, + :pentagon, :hexagon, :heptagon, :octagon, + :star4, :star5, :star6, :star7, :star8, + :vline, :hline, :+, :x, ] -const _inspectdr_scale = [:identity, :ln, :log2, :log10] #Does not really support ln, (plot using log10 instead). +const _inspectdr_scale = [:identity, :ln, :log2, :log10] + +is_marker_supported(::InspectDRBackend, shape::Shape) = true #Do we avoid Map to avoid possible pre-comile issues? function _inspectdr_mapglyph(s::Symbol) s == :rect && return :square - s == :utriangle && return :uarrow - s == :dtriangle && return :darrow - s == :ltriangle && return :larrow - s == :rtriangle && return :rarrow - s == :xcross && return :diagcross - s == :star8 && return :* - -#= Actually supported: - :square, :diamond, - :uarrow, :darrow, :larrow, :rarrow, #usually triangles - :cross, :+, :diagcross, :x, - :circle, :o, :star, :*, -=# - return s end +function _inspectdr_mapglyph(s::Shape) + x, y = coords(s) + return InspectDR.GlyphPolyline(x, y) +end + # py_marker(markers::AVec) = map(py_marker, markers) function _inspectdr_mapglyph(markers::AVec) warn("Vectors of markers are currently unsupported in InspectDR.") @@ -124,6 +99,25 @@ end #Hack: suggested point size does not seem adequate relative to plot size, for some reason. _inspectdr_mapptsize(v) = 1.5*v +function _inspectdr_add_annotations(plot, x, y, val) + #What kind of annotation is this? +end + +#plot::InspectDR.Plot2D +function _inspectdr_add_annotations(plot, x, y, val::PlotText) + vmap = Dict{Symbol, Symbol}(:top=>:t, :bottom=>:b) #:vcenter + hmap = Dict{Symbol, Symbol}(:left=>:l, :right=>:r) #:hcenter + align = Symbol(get(vmap, val.font.valign, :c), get(hmap, val.font.halign, :c)) + fnt = InspectDR.Font(val.font.family, val.font.pointsize, + color =_inspectdr_mapcolor(val.font.color) + ) + ann = InspectDR.atext(val.str, x=x, y=y, + font=fnt, angle=val.font.rotation, align=align + ) + InspectDR.add(plot, ann) + return +end + # --------------------------------------------------------------------------- #InspectDR-dependent structures and method signatures. #(To be evalutated only once ready to load module) @@ -132,6 +126,11 @@ const _inspectdr_depcode = quote import InspectDR export InspectDR +#Glyph used when plotting "Shape"s: +const INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline( + 2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y +) + type InspectDRPlotEnv #Stores reference to active plot GUI: cur_gui::Nullable{InspectDR.GtkPlot} @@ -142,13 +141,13 @@ end #_inspectdr_depcode # --------------------------------------------------------------------------- function _inspectdr_getscale(s::Symbol) -#TODO: Support :ln, :asinh, :sqrt +#TODO: Support :asinh, :sqrt if :log2 == s return InspectDR.AxisScale(:log2) elseif :log10 == s return InspectDR.AxisScale(:log10) elseif :ln == s - return InspectDR.AxisScale(:log10) #At least it will be a log-plot + return InspectDR.AxisScale(:ln) else #identity return InspectDR.AxisScale(:lin) end @@ -203,7 +202,10 @@ function _initialize_subplot(plt::Plot{InspectDRBackend}, sp::Subplot{InspectDRB #Don't do anything without a "subplot" object: Will process later. if nothing == plot; return; end plot.data = [] - + plot.markers = [] #Clear old markers + plot.atext = [] #Clear old annotation + plot.apline = [] #Clear old poly lines + return plot end @@ -235,10 +237,44 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) #= TODO: Eventually support series[:fillcolor] #I think this is fill under line zorder = series[:series_plotindex] + +For st in :shape: + zorder = series[:series_plotindex], =# - #TODO: scale width & sizes - if st in (:path, :scatter) #, :steppre, :steppost) + if st in (:shape,) + nmax = 0 + for (i,rng) in enumerate(iter_segments(x, y)) + nmax = i + if length(rng) > 1 + linewidth = series[:linewidth] + linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i)) + fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i)) + line = InspectDR.line( + style=:solid, width=linewidth, color=linecolor + ) + apline = InspectDR.PolylineAnnotation( + x[rng], y[rng], line=line, fillcolor=fillcolor + ) + push!(plot.apline, apline) + end + end + + i = (nmax >= 2? div(nmax, 2): nmax) #Must pick one set of colors for legend + if i > 1 #Add dummy waveform for legend entry: + linewidth = series[:linewidth] + linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i)) + fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i)) + wfrm = InspectDR.add(plot, Float64[], Float64[], id=series[:label]) + wfrm.line = InspectDR.line( + style=:none, width=linewidth, #linewidth affects glyph + ) + wfrm.glyph = InspectDR.glyph( + shape = INSPECTDR_GLYPH_SHAPE, size = 8, + color = linecolor, fillcolor = fillcolor + ) + end + elseif st in (:path, :scatter) #, :steppre, :steppost) #NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think). linewidth = series[:linewidth] #More efficient & allows some support for markerstrokewidth: @@ -261,6 +297,12 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) fillcolor = _inspectdr_mapcolor(series[:markercolor]), ) end + + # this is all we need to add the series_annotations text + anns = series[:series_annotations] + for (xi,yi,str,fnt) in EachAnn(anns, x, y) + _inspectdr_add_annotations(plot, xi, yi, PlotText(str, fnt)) + end return end @@ -285,7 +327,6 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) plot.axes = InspectDR.AxesRect(xscale, yscale) xmin, xmax = axis_limits(xaxis) ymin, ymax = axis_limits(yaxis) - #TODO: not sure which extents we should be modifying. plot.ext = InspectDR.PExtents2D() #reset plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax) a = plot.annotation @@ -293,20 +334,31 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide] l = plot.layout - l.fnttitle.name = sp[:titlefont].family - l.fnttitle._size = _inspectdr_mapptsize(sp[:titlefont].pointsize) + l.framedata.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside]) + l.framedata.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis]) + l.fnttitle = InspectDR.Font(sp[:titlefont].family, + _inspectdr_mapptsize(sp[:titlefont].pointsize), + color = _inspectdr_mapcolor(sp[:foreground_color_title]) + ) #Cannot independently control fonts of axes with InspectDR: - l.fntaxlabel.name = xaxis[:guidefont].family - l.fntaxlabel._size = _inspectdr_mapptsize(xaxis[:guidefont].pointsize) - l.fntticklabel.name = xaxis[:tickfont].family - l.fntticklabel._size = _inspectdr_mapptsize(xaxis[:tickfont].pointsize) + l.fntaxlabel = InspectDR.Font(xaxis[:guidefont].family, + _inspectdr_mapptsize(xaxis[:guidefont].pointsize), + color = _inspectdr_mapcolor(xaxis[:foreground_color_guide]) + ) + l.fntticklabel = InspectDR.Font(xaxis[:tickfont].family, + _inspectdr_mapptsize(xaxis[:tickfont].pointsize), + color = _inspectdr_mapcolor(xaxis[:foreground_color_text]) + ) #No independent control of grid??? l.grid = sp[:grid]? gridon: gridoff leg = l.legend leg.enabled = (sp[:legend] != :none) #leg.width = 150 #TODO: compute??? - leg.font.name = sp[:legendfont].family - leg.font._size = _inspectdr_mapptsize(sp[:legendfont].pointsize) + leg.font = InspectDR.Font(sp[:legendfont].family, + _inspectdr_mapptsize(sp[:legendfont].pointsize), + color = _inspectdr_mapcolor(sp[:foreground_color_legend]) + ) + leg.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend]) end # called just before updating layout bounding boxes... in case you need to prep @@ -322,11 +374,21 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) sp.o = mplot.subplots[i] _initialize_subplot(plt, sp) _inspectdr_setupsubplot(sp) + + sp.o.layout.frame.fillcolor = + _inspectdr_mapcolor(plt[:background_color_outside]) + + # add the annotations + for ann in sp[:annotations] + _inspectdr_add_annotations(mplot.subplots[i], ann...) + end end #Do not yet support absolute plot positionning. #Just try to make things look more-or less ok: - if nsubplots <= 4 + if nsubplots <= 1 + mplot.ncolumns = 1 + elseif nsubplots <= 4 mplot.ncolumns = 2 elseif nsubplots <= 6 mplot.ncolumns = 3 @@ -377,7 +439,7 @@ const _inspectdr_mimeformats_nodpi = Dict( "image/svg+xml" => "svg", "application/eps" => "eps", "image/eps" => "eps", -# "application/postscript" => "ps", #TODO: support +# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface "application/pdf" => "pdf" ) _inspectdr_show(io::IO, mime::MIME, ::Void) = From edf1daa7d7544cb30956db34a094bf5d49d3a2b4 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Thu, 5 Jan 2017 14:39:50 -0500 Subject: [PATCH 03/26] Improve gui handling & remove global state. Also: Add AVec support for colors. Move init code back to _initialize_backend. --- src/backends/inspectdr.jl | 105 ++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 17399f52..76e82168 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -91,10 +91,15 @@ end _inspectdr_mapcolor(v::Colorant) = v function _inspectdr_mapcolor(g::PlotUtils.ColorGradient) - warn("Vectors of colors are currently unsupported in InspectDR.") + warn("Color gradients are currently unsupported in InspectDR.") #Pick middle color: _inspectdr_mapcolor(g.colors[div(1+end,2)]) end +function _inspectdr_mapcolor(v::AVec) + warn("Vectors of colors are currently unsupported in InspectDR.") + #Pick middle color: + _inspectdr_mapcolor(v[div(1+end,2)]) +end #Hack: suggested point size does not seem adequate relative to plot size, for some reason. _inspectdr_mapptsize(v) = 1.5*v @@ -118,26 +123,6 @@ function _inspectdr_add_annotations(plot, x, y, val::PlotText) return end -# --------------------------------------------------------------------------- -#InspectDR-dependent structures and method signatures. -#(To be evalutated only once ready to load module) -const _inspectdr_depcode = quote - -import InspectDR -export InspectDR - -#Glyph used when plotting "Shape"s: -const INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline( - 2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y -) - -type InspectDRPlotEnv - #Stores reference to active plot GUI: - cur_gui::Nullable{InspectDR.GtkPlot} -end -InspectDRPlotEnv() = InspectDRPlotEnv(nothing) -const _inspectdr_plotenv = InspectDRPlotEnv() -end #_inspectdr_depcode # --------------------------------------------------------------------------- function _inspectdr_getscale(s::Symbol) @@ -156,35 +141,53 @@ end # --------------------------------------------------------------------------- function _initialize_backend(::InspectDRBackend; kw...) - eval(_inspectdr_depcode) + @eval begin + import InspectDR + export InspectDR + + #Glyph used when plotting "Shape"s: + const INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline( + 2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y + ) + + type InspecDRPlotRef + mplot::Union{Void, InspectDR.Multiplot} + gui::Union{Void, InspectDR.GtkPlot} + end + + _inspectdr_getmplot(::Any) = nothing + _inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot + + _inspectdr_getgui(::Any) = nothing + _inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed? nothing: gplot) + _inspectdr_getgui(r::InspecDRPlotRef) = _inspectdr_getgui(r.gui) + end end # --------------------------------------------------------------------------- # Create the window/figure for this backend. function _create_backend_figure(plt::Plot{InspectDRBackend}) - mplot = plt.o + mplot = _inspectdr_getmplot(plt.o) + gplot = _inspectdr_getgui(plt.o) #:overwrite_figure: want to reuse current figure - if plt[:overwrite_figure] && isa(mplot, InspectDR.Multiplot) + if plt[:overwrite_figure] && mplot != nothing mplot.subplots = [] #Reset - if !isnull(_inspectdr_plotenv.cur_gui) #Create new one: - gplot = get(_inspectdr_plotenv.cur_gui) + if gplot != nothing #Ensure still references current plot gplot.src = mplot end else #want new one: mplot = InspectDR.Multiplot() - if !isnull(_inspectdr_plotenv.cur_gui) #Create new one: - _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) - end + gplot = nothing #Will be created later end #break link with old subplots for sp in plt.subplots sp.o = nothing end - plt.o = mplot - return mplot + + return InspecDRPlotRef(mplot, gplot) end # --------------------------------------------------------------------------- @@ -364,7 +367,9 @@ end # called just before updating layout bounding boxes... in case you need to prep # for the calcs function _before_layout_calcs(plt::Plot{InspectDRBackend}) - mplot = plt.o + const mplot = _inspectdr_getmplot(plt.o) + if nothing == mplot; return; end + resize!(mplot.subplots, length(plt.subplots)) nsubplots = length(plt.subplots) for (i, sp) in enumerate(plt.subplots) @@ -401,6 +406,7 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) for series in plt.series_list _series_added(plt, series) end + return end # ---------------------------------------------------------------- @@ -416,18 +422,14 @@ end # Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations]) function _update_plot_object(plt::Plot{InspectDRBackend}) - const mplot = plt.o + mplot = _inspectdr_getmplot(plt.o) if nothing == mplot; return; end - if isnull(_inspectdr_plotenv.cur_gui); return; end - const gplot = get(_inspectdr_plotenv.cur_gui) + gplot = _inspectdr_getgui(plt.o) + if nothing == gplot; return; end - if gplot.destroyed - _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) - else - gplot.src = mplot - InspectDR.refresh(gplot) - end - return mplot + gplot.src = mplot #Ensure still references current plot + InspectDR.refresh(gplot) + return end # ---------------------------------------------------------------- @@ -449,25 +451,30 @@ _inspectdr_show(io::IO, mime::MIME, mplot) = show(io, mime, mplot) for (mime, fmt) in _inspectdr_mimeformats_dpi @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) dpi = plt[:dpi]#TODO: support - _inspectdr_show(io, mime, plt.o) + _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o)) end end for (mime, fmt) in _inspectdr_mimeformats_nodpi @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) - _inspectdr_show(io, mime, plt.o) + _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o)) end end +_show(io::IO, mime::MIME"text/plain", plt::Plot{InspectDRBackend}) = nothing #Don't show # ---------------------------------------------------------------- # Display/show the plot (open a GUI window, or browser page, for example). function _display(plt::Plot{InspectDRBackend}) - const mplot = plt.o - if isnull(_inspectdr_plotenv.cur_gui) - _inspectdr_plotenv.cur_gui = display(InspectDR.GtkDisplay(), mplot) + mplot = _inspectdr_getmplot(plt.o) + if nothing == mplot; return; end + gplot = _inspectdr_getgui(plt.o) + + if nothing == gplot && true == plt[:show] + gplot = display(InspectDR.GtkDisplay(), mplot) else #redundant... Plots.jl will call _update_plot_object: - #InspectDR.refresh(get(_inspectdr_plotenv.cur_gui)) + #InspectDR.refresh(gplot) end - return get(_inspectdr_plotenv.cur_gui) + plt.o = InspecDRPlotRef(mplot, gplot) + return gplot end From 1fa34574e8dbef99a256edc063893924f532ef3c Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Mon, 9 Jan 2017 15:14:39 -0500 Subject: [PATCH 04/26] More fixes requested by Tom: Add add_backend_string(). Remove un-necessary test: true == plt[:show]. --- src/backends/inspectdr.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 76e82168..fea44064 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -140,6 +140,14 @@ end # --------------------------------------------------------------------------- +function add_backend_string(::InspectDRBackend) + """ + if !Plots.is_installed("InspectDR") + Pkg.add("InspectDR") + end + """ +end + function _initialize_backend(::InspectDRBackend; kw...) @eval begin import InspectDR @@ -469,7 +477,7 @@ function _display(plt::Plot{InspectDRBackend}) if nothing == mplot; return; end gplot = _inspectdr_getgui(plt.o) - if nothing == gplot && true == plt[:show] + if nothing == gplot gplot = display(InspectDR.GtkDisplay(), mplot) else #redundant... Plots.jl will call _update_plot_object: From c5737db4f5436be472824a6cd0a23aa24f2101e4 Mon Sep 17 00:00:00 2001 From: Naoki Saito Date: Sun, 8 Jan 2017 14:17:38 -0800 Subject: [PATCH 05/26] Add fill_z attribute and plotly impl --- src/arg_desc.jl | 1 + src/args.jl | 2 ++ src/backends/plotly.jl | 6 +++++- src/series.jl | 14 ++++++++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index b4503c1e..4efbf1af 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -29,6 +29,7 @@ const _arg_desc = KW( :z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.", :marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.", :line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).", +:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.", :levels => "Integer, NTuple{2,Integer}. Number of levels (or x-levels/y-levels) for a contour type.", :orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).", :bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)", diff --git a/src/args.jl b/src/args.jl index 119dd125..8f82fec0 100644 --- a/src/args.jl +++ b/src/args.jl @@ -188,6 +188,7 @@ const _series_defaults = KW( :z => nothing, # depth for contour, surface, etc :marker_z => nothing, # value for color scale :line_z => nothing, + :fill_z => nothing, :levels => 15, :orientation => :vertical, :bar_position => :overlay, # for bar plots and histograms: could also be stack (stack up) or dodge (side by side) @@ -431,6 +432,7 @@ add_aliases(:zguide, :zlabel, :zlab, :zl) add_aliases(:zlims, :zlim, :zlimit, :zlimits) add_aliases(:zticks, :ztick) add_aliases(:zrotation, :zrot, :zr) +add_aliases(:fill_z, :fillz, :fz, :surfacecolor, :surfacecolour, :sc, :surfcolor, :surfcolour) add_aliases(:legend, :leg, :key) add_aliases(:colorbar, :cb, :cbar, :colorkey) add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index a70ddf60..bbdd29b9 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -20,7 +20,7 @@ const _plotly_attr = merge_with_base_supported([ :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, :grid, :legend, :colorbar, - :marker_z, :levels, + :marker_z, :fill_z, :levels, :ribbon, :quiver, :orientation, # :overwrite_figure, @@ -371,6 +371,7 @@ end plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α) # plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha) + const _plotly_markers = KW( :rect => "square", :xcross => "x", @@ -488,6 +489,9 @@ function plotly_series(plt::Plot, series::Series) d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines) else d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) + if series[:fill_z] != nothing + d_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z]) + end end elseif st == :pie diff --git a/src/series.jl b/src/series.jl index 02e9eca2..81307677 100644 --- a/src/series.jl +++ b/src/series.jl @@ -257,12 +257,23 @@ end # # 1 argument # # -------------------------------------------------------------------- +# helper function to ensure relevant attributes are wrapped by Surface +function wrap_surfaces(d::KW) + if haskey(d, :fill_z) + v = d[:fill_z] + if !isa(v, Surface) + d[:fill_z] = Surface(v) + end + end +end + @recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing) # return a surface if this is a 3d plot, otherwise let it be sliced up @recipe function f{T<:Union{Integer,AbstractFloat}}(mat::AMat{T}) if all3D(d) n,m = size(mat) + wrap_surfaces(d) SliceIt, 1:m, 1:n, Surface(mat) else SliceIt, nothing, mat, nothing @@ -274,6 +285,7 @@ end if all3D(d) mat = fmt.data n,m = size(mat) + wrap_surfaces(d) SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter) else SliceIt, nothing, fmt, nothing @@ -400,6 +412,7 @@ end @recipe function f(x::AVec, y::AVec, zf::Function) # x = X <: Number ? sort(x) : x # y = Y <: Number ? sort(y) : y + wrap_surfaces(d) SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported end @@ -410,6 +423,7 @@ end if !like_surface(get(d, :seriestype, :none)) d[:seriestype] = :contour end + wrap_surfaces(d) SliceIt, x, y, Surface(z) end From 3236e06fb9ed53c49f535cb9b9465f07c2baff0b Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Tue, 10 Jan 2017 11:35:57 -0500 Subject: [PATCH 06/26] wrap_surfaces for 3 matrices --- src/series.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/series.jl b/src/series.jl index 81307677..f7233c1a 100644 --- a/src/series.jl +++ b/src/series.jl @@ -403,6 +403,7 @@ end # seriestype := :path3d # end # end + wrap_surfaces(d) SliceIt, x, y, z end From 199a3306db73c29bce2dd8e96d2e1762ed38d776 Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Wed, 11 Jan 2017 10:37:54 -0500 Subject: [PATCH 07/26] fix support for fill_z in pyplot --- src/backends/pyplot.jl | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index b1f7e2c0..84ea6718 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -18,8 +18,7 @@ const _pyplot_attr = merge_with_base_supported([ :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, :grid, :legend, :colorbar, - :marker_z, - :line_z, + :marker_z, :line_z, :fill_z, :levels, :ribbon, :quiver, :arrow, :orientation, @@ -124,8 +123,8 @@ end py_colormap(c) = py_colormap(cgrad()) -function py_shading(c, z, α=nothing) - cmap = py_colormap(c, α) +function py_shading(c, z) + cmap = py_colormap(c) ls = pycolors.pymember("LightSource")(270,45) ls[:shade](z, cmap, vert_exag=0.1, blend_mode="soft") end @@ -668,21 +667,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) x = repmat(x', length(y), 1) y = repmat(y, 1, length(series[:x])) end - # z = z' z = transpose_z(series, z) if st == :surface - if series[:marker_z] != nothing - extrakw[:facecolors] = py_shading(series[:fillcolor], series[:marker_z], series[:fillalpha]) + if series[:fill_z] != nothing + # the surface colors are different than z-value + extrakw[:facecolors] = py_shading(series[:fillcolor], transpose_z(series, series[:fill_z].surf)) extrakw[:shade] = false - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - end else extrakw[:cmap] = py_fillcolormap(series) - needs_colorbar = true end + needs_colorbar = true end handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z; label = series[:label], From 3b570edea1807a983c1265478cf9d38e42098568 Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Fri, 13 Jan 2017 09:33:02 -0500 Subject: [PATCH 08/26] added back precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 3515e75b..c957ab8a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From c250d7c073ac1c057e299f46f402a65f84be93ea Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Thu, 19 Jan 2017 14:45:16 -0500 Subject: [PATCH 09/26] working on fixing pyplot issue for ubuntu --- src/backends/pyplot.jl | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 84ea6718..36d0d5f5 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -56,6 +56,34 @@ function add_backend_string(::PyPlotBackend) Pkg.build("PyPlot") end """ + if !Plots.is_installed("PyPlot") + Pkg.add("PyPlot") + end + withenv("PYTHON" => "") do + Pkg.build("PyPlot") + end + import Conda # TODO since this only known to occur on Ubuntu we could also check the user's OS here + Conda.add("qt=4.8.5") # run the old version of Conda + # TO AVOID: + # 1) Segfault when attempting to run pylplot + # caused by Conda update to Segfault with qt >=4.8.6 on Ubuntu https://github.com/JuliaPy/PyPlot.jl/issues/234 + # 2) precomilation issue after updating Plots.jl + #= + INFO: Recompiling stale cache file /home/febbo/.julia/lib/v0.5/Plots.ji for module Plots. + ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled. + in __precompile__(::Bool) at ./loading.jl:300 + in include_from_node1(::String) at ./loading.jl:488 + in macro expansion; at ./none:2 [inlined] + in anonymous at ./:? + in eval(::Module, ::Any) at ./boot.jl:234 + in process_options(::Base.JLOptions) at ./client.jl:239 + in _start() at ./client.jl:318 + while loading /home/febbo/.julia/v0.5/Plots/src/Plots.jl, in expression starting on line 1 + ERROR: LoadError: Failed to precompile Plots to /home/febbo/.julia/lib/v0.5/Plots.ji. + in compilecache(::String) at ./loading.jl:593 + in require(::Symbol) at ./loading.jl:393 + in include_from_node1(::String) at ./loading.jl:488 + =# end function _initialize_backend(::PyPlotBackend) From cd8939fe0bd69a64f5b9d5d3dd85324304b4c3f3 Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Thu, 19 Jan 2017 17:32:37 -0500 Subject: [PATCH 10/26] finished fixing segfault issue when qt>v4.8.5 on Ubuntu using pyplot --- src/backends/pyplot.jl | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 36d0d5f5..64ae74bd 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -56,34 +56,6 @@ function add_backend_string(::PyPlotBackend) Pkg.build("PyPlot") end """ - if !Plots.is_installed("PyPlot") - Pkg.add("PyPlot") - end - withenv("PYTHON" => "") do - Pkg.build("PyPlot") - end - import Conda # TODO since this only known to occur on Ubuntu we could also check the user's OS here - Conda.add("qt=4.8.5") # run the old version of Conda - # TO AVOID: - # 1) Segfault when attempting to run pylplot - # caused by Conda update to Segfault with qt >=4.8.6 on Ubuntu https://github.com/JuliaPy/PyPlot.jl/issues/234 - # 2) precomilation issue after updating Plots.jl - #= - INFO: Recompiling stale cache file /home/febbo/.julia/lib/v0.5/Plots.ji for module Plots. - ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled. - in __precompile__(::Bool) at ./loading.jl:300 - in include_from_node1(::String) at ./loading.jl:488 - in macro expansion; at ./none:2 [inlined] - in anonymous at ./:? - in eval(::Module, ::Any) at ./boot.jl:234 - in process_options(::Base.JLOptions) at ./client.jl:239 - in _start() at ./client.jl:318 - while loading /home/febbo/.julia/v0.5/Plots/src/Plots.jl, in expression starting on line 1 - ERROR: LoadError: Failed to precompile Plots to /home/febbo/.julia/lib/v0.5/Plots.ji. - in compilecache(::String) at ./loading.jl:593 - in require(::Symbol) at ./loading.jl:393 - in include_from_node1(::String) at ./loading.jl:488 - =# end function _initialize_backend(::PyPlotBackend) @@ -109,7 +81,18 @@ function _initialize_backend(::PyPlotBackend) const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections")) const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d")) end - + if is_linux() + @eval begin + # avoid Conda update that causes Segfault with qt >=4.8.6 on Ubuntu https://github.com/JuliaPy/PyPlot.jl/issues/234 + import Conda + kw = Conda._installed_packages_dict() + if (!haskey(kw,"qt") || (qt_version=get(kw,"qt",0)[1]!=v"4.8.5")) + print("\n Switching to qt v4.8.5!! \n") + Conda.add("qt=4.8.5") + error("\n Please RESTART julia to use qt v4.8.5!! \n If we did not error here, a Segmentation fault error would occur. \n \n") + end + end + end # we don't want every command to update the figure PyPlot.ioff() end From 43a213643bdb268050fbdaf4dcaf5e12b2f84eaa Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Thu, 19 Jan 2017 18:04:09 -0500 Subject: [PATCH 11/26] changed code so it does not automatically change qt version --- src/backends/pyplot.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 64ae74bd..c02a512f 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -55,6 +55,10 @@ function add_backend_string(::PyPlotBackend) withenv("PYTHON" => "") do Pkg.build("PyPlot") end + import Conda + Conda.add("qt=4.8.5") + + # now restart julia! """ end @@ -87,9 +91,8 @@ function _initialize_backend(::PyPlotBackend) import Conda kw = Conda._installed_packages_dict() if (!haskey(kw,"qt") || (qt_version=get(kw,"qt",0)[1]!=v"4.8.5")) - print("\n Switching to qt v4.8.5!! \n") - Conda.add("qt=4.8.5") - error("\n Please RESTART julia to use qt v4.8.5!! \n If we did not error here, a Segmentation fault error would occur. \n \n") + print("\n If the code has a Segmentation fault error switch to qt v4.8.5 by pasting the following code into julia: \n \n") + add_backend_string(backend()) end end end From 1a91eacdcb784ab778424266db95a9130edc7076 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Fri, 20 Jan 2017 15:26:54 +0100 Subject: [PATCH 12/26] Enable histogram plotting in pgfplot --- src/backends/pgfplots.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index b42e8629..a1548b5e 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -32,7 +32,7 @@ const _pgfplots_attr = merge_with_base_supported([ :aspect_ratio, # :match_dimensions, ]) -const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour] +const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon] #vcat(_allMarkers, Shape) const _pgfplots_scale = [:identity, :ln, :log2, :log10] @@ -147,7 +147,7 @@ function pgf_series(sp::Subplot, series::Series) push!(style, pgf_linestyle(d)) push!(style, pgf_marker(d)) - if d[:fillrange] != nothing + if d[:fillcolor] != nothing push!(style, pgf_fillstyle(d)) end From bcd5d9ef9087cbf9577ce5ff4710b5e56f750045 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Sun, 22 Jan 2017 16:57:28 +0100 Subject: [PATCH 13/26] Fix issue where every series is plotted with a fillcolor --- src/backends/pgfplots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index a1548b5e..754ebaa0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -147,7 +147,7 @@ function pgf_series(sp::Subplot, series::Series) push!(style, pgf_linestyle(d)) push!(style, pgf_marker(d)) - if d[:fillcolor] != nothing + if d[:fillrange] != nothing || st in (:shape,) push!(style, pgf_fillstyle(d)) end From caf86686ddf8e7c190ffbf8ed8ae011fce89d3dd Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Mon, 23 Jan 2017 13:56:40 +0100 Subject: [PATCH 14/26] Fix yshift of subplots. Calculation of coordinate transformation from bb to pgf did not consider the height of the plot. --- src/backends/pgfplots.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 754ebaa0..9ecc0ae4 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -249,8 +249,12 @@ end function _update_plot_object(plt::Plot{PGFPlotsBackend}) plt.o = PGFPlots.Axis[] + # Obtain the total height of the plot by extracting the maximal bottom + # coordinate from the bounding box. + # TODO: Maybe there is a better way to get the total height of the plot. + total_height = maximum([bottom(bbox(sp)) for sp in plt.subplots]) for sp in plt.subplots - # first build the PGFPlots.Axis object + # first build the PGFPlots.Axis object style = ["unbounded coords=jump"] kw = KW() @@ -268,7 +272,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) bb = bbox(sp) push!(style, """ xshift = $(left(bb).value)mm, - yshift = $((height(bb) - (bottom(bb))).value)mm, + yshift = $((total_height - (bottom(bb))).value)mm, axis background/.style={fill=$(pgf_color(sp[:background_color_inside])[1])} """) kw[:width] = "$(width(bb).value)mm" From f8b84185acb747cb827aed29ca59bf39825b2e33 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Mon, 23 Jan 2017 14:28:26 +0100 Subject: [PATCH 15/26] Add rounding and obtain plot height from layout bbox --- src/backends/pgfplots.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 9ecc0ae4..4feb46d0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -251,8 +251,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) plt.o = PGFPlots.Axis[] # Obtain the total height of the plot by extracting the maximal bottom # coordinate from the bounding box. - # TODO: Maybe there is a better way to get the total height of the plot. - total_height = maximum([bottom(bbox(sp)) for sp in plt.subplots]) + total_height = bottom(bbox(plt.layout)) for sp in plt.subplots # first build the PGFPlots.Axis object style = ["unbounded coords=jump"] @@ -269,10 +268,12 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # bounding box values are in mm # note: bb origin is top-left, pgf is bottom-left + # A round on 2 decimal places should be enough precision for 300 dpi + # plots. bb = bbox(sp) push!(style, """ xshift = $(left(bb).value)mm, - yshift = $((total_height - (bottom(bb))).value)mm, + yshift = $(round((total_height - (bottom(bb))).value,2))mm, axis background/.style={fill=$(pgf_color(sp[:background_color_inside])[1])} """) kw[:width] = "$(width(bb).value)mm" From ebf92d30332ea2e5d0ecd3eab83671e77694fc1b Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Mon, 23 Jan 2017 21:25:55 -0500 Subject: [PATCH 16/26] Add support for layout & plot size. Also: Add basic support for polar plots. Add support for plot title & background color of entire figure. --- src/backends/inspectdr.jl | 61 ++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index fea44064..af95c76a 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -38,7 +38,7 @@ const _inspectdr_attr = merge_with_base_supported([ # :ribbon, :quiver, :arrow, # :orientation, :overwrite_figure, -# :polar, + :polar, # :normalize, :weights, # :contours, :aspect_ratio, :match_dimensions, @@ -66,6 +66,9 @@ const _inspectdr_scale = [:identity, :ln, :log2, :log10] is_marker_supported(::InspectDRBackend, shape::Shape) = true +_inspectdr_to_pixels(bb::BoundingBox) = + InspectDR.BoundingBox(to_pixels(left(bb)), to_pixels(right(bb)), to_pixels(top(bb)), to_pixels(bottom(bb))) + #Do we avoid Map to avoid possible pre-comile issues? function _inspectdr_mapglyph(s::Symbol) s == :rect && return :square @@ -237,6 +240,12 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) _vectorize(v) = isa(v, Vector)? v: collect(v) #InspectDR only supports vectors x = _vectorize(series[:x]); y = _vectorize(series[:y]) + #No support for polar grid... but can still perform polar transformation: + if ispolar(sp) + Θ = x; r = y + x = r.*cos(Θ); y = r.*sin(Θ) + end + # doesn't handle mismatched x/y - wrap data (pyplot behaviour): nx = length(x); ny = length(y) if nx < ny @@ -338,6 +347,12 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) plot.axes = InspectDR.AxesRect(xscale, yscale) xmin, xmax = axis_limits(xaxis) ymin, ymax = axis_limits(yaxis) + if ispolar(sp) + #Plots.jl appears to give (xmin,xmax) ≜ (Θmin,Θmax) & (ymin,ymax) ≜ (rmin,rmax) + rmax = max(abs(ymin), abs(ymax)) + xmin, xmax = -rmax, rmax + ymin, ymax = -rmax, rmax + end plot.ext = InspectDR.PExtents2D() #reset plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax) a = plot.annotation @@ -345,6 +360,7 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide] l = plot.layout + l.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot]) l.framedata.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside]) l.framedata.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis]) l.fnttitle = InspectDR.Font(sp[:titlefont].family, @@ -378,6 +394,13 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) const mplot = _inspectdr_getmplot(plt.o) if nothing == mplot; return; end + mplot.title = plt[:plot_title] + if "" == mplot.title + #Don't use window_title... probably not what you want. + #mplot.title = plt[:window_title] + end + mplot.frame.fillcolor = _inspectdr_mapcolor(plt[:background_color_outside]) + resize!(mplot.subplots, length(plt.subplots)) nsubplots = length(plt.subplots) for (i, sp) in enumerate(plt.subplots) @@ -385,15 +408,15 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) mplot.subplots[i] = InspectDR.Plot2D() end sp.o = mplot.subplots[i] + plot = sp.o _initialize_subplot(plt, sp) _inspectdr_setupsubplot(sp) - - sp.o.layout.frame.fillcolor = - _inspectdr_mapcolor(plt[:background_color_outside]) + graphbb = _inspectdr_to_pixels(plotarea(sp)) + plot.plotbb = InspectDR.plotbounds(plot.layout, graphbb) # add the annotations for ann in sp[:annotations] - _inspectdr_add_annotations(mplot.subplots[i], ann...) + _inspectdr_add_annotations(plot, ann...) end end @@ -422,8 +445,19 @@ end # Set the (left, top, right, bottom) minimum padding around the plot area # to fit ticks, tick labels, guides, colorbars, etc. function _update_min_padding!(sp::Subplot{InspectDRBackend}) - sp.minpad = (20mm, 5mm, 2mm, 10mm) - #TODO: Add support for padding. + plot = sp.o + if !isa(plot, InspectDR.Plot2D); return sp.minpad; end + #Computing plotbounds with 0-BoundingBox returns required padding: + bb = InspectDR.plotbounds(plot.layout, InspectDR.BoundingBox(0,0,0,0)) + #NOTE: plotbounds always pads for titles, legends, etc. even if not in use. + #TODO: possibly zero-out items not in use?? + + # add in the user-specified margin to InspectDR padding: + leftpad = abs(bb.xmin)*px + sp[:left_margin] + toppad = abs(bb.ymax)*px + sp[:top_margin] + rightpad = abs(bb.xmax)*px + sp[:right_margin] + bottompad = abs(bb.ymin)*px + sp[:bottom_margin] + sp.minpad = (leftpad, toppad, rightpad, bottompad) end # ---------------------------------------------------------------- @@ -432,6 +466,9 @@ end function _update_plot_object(plt::Plot{InspectDRBackend}) mplot = _inspectdr_getmplot(plt.o) if nothing == mplot; return; end + + #TODO: should plotbb be computed here?? + gplot = _inspectdr_getgui(plt.o) if nothing == gplot; return; end @@ -452,19 +489,21 @@ const _inspectdr_mimeformats_nodpi = Dict( # "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface "application/pdf" => "pdf" ) -_inspectdr_show(io::IO, mime::MIME, ::Void) = +_inspectdr_show(io::IO, mime::MIME, ::Void, w, h) = throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated")) -_inspectdr_show(io::IO, mime::MIME, mplot) = show(io, mime, mplot) +function _inspectdr_show(io::IO, mime::MIME, mplot, w, h) + InspectDR._show(io, mime, mplot, Float64(w), Float64(h)) +end for (mime, fmt) in _inspectdr_mimeformats_dpi @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) dpi = plt[:dpi]#TODO: support - _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o)) + _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...) end end for (mime, fmt) in _inspectdr_mimeformats_nodpi @eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend}) - _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o)) + _inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...) end end _show(io::IO, mime::MIME"text/plain", plt::Plot{InspectDRBackend}) = nothing #Don't show From caed94328ff67ce9a0807909461a51334b7d2f57 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Wed, 25 Jan 2017 11:40:47 -0500 Subject: [PATCH 17/26] Fix exception calling backend() in _initialize_backend(). --- src/backends/pyplot.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index c02a512f..68f45be9 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -92,7 +92,7 @@ function _initialize_backend(::PyPlotBackend) kw = Conda._installed_packages_dict() if (!haskey(kw,"qt") || (qt_version=get(kw,"qt",0)[1]!=v"4.8.5")) print("\n If the code has a Segmentation fault error switch to qt v4.8.5 by pasting the following code into julia: \n \n") - add_backend_string(backend()) + print(add_backend_string(PyPlotBackend())) end end end From 95a26f50809cad7b1bfe2c94648c1269130f2afa Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Sat, 28 Jan 2017 11:47:10 -0500 Subject: [PATCH 18/26] Fix inversion in padding. --- src/backends/inspectdr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index af95c76a..4f6a57f9 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -454,9 +454,9 @@ function _update_min_padding!(sp::Subplot{InspectDRBackend}) # add in the user-specified margin to InspectDR padding: leftpad = abs(bb.xmin)*px + sp[:left_margin] - toppad = abs(bb.ymax)*px + sp[:top_margin] + toppad = abs(bb.ymin)*px + sp[:top_margin] rightpad = abs(bb.xmax)*px + sp[:right_margin] - bottompad = abs(bb.ymin)*px + sp[:bottom_margin] + bottompad = abs(bb.ymax)*px + sp[:bottom_margin] sp.minpad = (leftpad, toppad, rightpad, bottompad) end From 2e1c86c0c7315affa1432e8cc16492ebbcced102 Mon Sep 17 00:00:00 2001 From: John Rinehart Date: Tue, 31 Jan 2017 23:55:16 -0500 Subject: [PATCH 19/26] path spaces fix stolen from http://stackoverflow.com/a/13692919 Spaces in Windows paths resulted in improper DOS command. Fix designed according to the above-referenced StackOverflow post. --- src/backends/web.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/web.jl b/src/backends/web.jl index 2fd4ae6e..6781314e 100644 --- a/src/backends/web.jl +++ b/src/backends/web.jl @@ -27,7 +27,7 @@ function open_browser_window(filename::AbstractString) return run(`xdg-open $(filename)`) end @static if is_windows() - return run(`$(ENV["COMSPEC"]) /c start $(filename)`) + return run(`$(ENV["COMSPEC"]) /c start "" "$(filename)"`) end warn("Unknown OS... cannot open browser window.") end From d5eafad48ed0fff9b52fdad044f9bbfac7b5f370 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Thu, 2 Feb 2017 16:05:17 +0100 Subject: [PATCH 20/26] Add annotations and series_annotations to pgfplots --- src/backends/pgfplots.jl | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 4feb46d0..6d8be4ba 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -3,7 +3,7 @@ # significant contributions by: @pkofod const _pgfplots_attr = merge_with_base_supported([ - # :annotations, + :annotations, # :background_color_legend, :background_color_inside, # :background_color_outside, @@ -27,7 +27,7 @@ const _pgfplots_attr = merge_with_base_supported([ # :ribbon, :quiver, :arrow, # :orientation, # :overwrite_figure, - # :polar, + :polar, # :normalize, :weights, :contours, :aspect_ratio, # :match_dimensions, @@ -136,6 +136,20 @@ function pgf_marker(d::KW) }""" end +function pgf_add_annotation!(o,x,y,val) + # Construct the style string. + # Currently supports color and orientation + halign = val.font.halign == :hcenter ? "" : string(val.font.halign) + cstr,a = pgf_color(val.font.color) + push!(o, PGFPlots.Plots.Node(val.str, # Annotation Text + x, y, # x,y + style=""" + $halign, + color=$cstr, draw opacity=$(convert(Float16,a)), + rotate=$(val.font.rotation) + """)) +end + # -------------------------------------------------------------------------------------- function pgf_series(sp::Subplot, series::Series) @@ -298,14 +312,25 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # add the series object to the PGFPlots.Axis for series in series_list(sp) push!(o, pgf_series(sp, series)) + + # add series annotations + anns = series[:series_annotations] + for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y]) + pgf_add_annotation!(o, xi, yi, PlotText(str, fnt)) + end end + # add the annotations + for ann in sp[:annotations] + pgf_add_annotation!(o,ann...) + end + + # add the PGFPlots.Axis to the list push!(plt.o, o) end end - function _show(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend}) show(io, mime, plt.o) end From 48ff2fb8b80bd2477c0a6335d7909a725eb8ccea Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Thu, 2 Feb 2017 16:06:59 +0100 Subject: [PATCH 21/26] Merge branch 'master' of https://github.com/JuliaPlots/Plots.jl --- src/backends/inspectdr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index af95c76a..4f6a57f9 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -454,9 +454,9 @@ function _update_min_padding!(sp::Subplot{InspectDRBackend}) # add in the user-specified margin to InspectDR padding: leftpad = abs(bb.xmin)*px + sp[:left_margin] - toppad = abs(bb.ymax)*px + sp[:top_margin] + toppad = abs(bb.ymin)*px + sp[:top_margin] rightpad = abs(bb.xmax)*px + sp[:right_margin] - bottompad = abs(bb.ymin)*px + sp[:bottom_margin] + bottompad = abs(bb.ymax)*px + sp[:bottom_margin] sp.minpad = (leftpad, toppad, rightpad, bottompad) end From dd505fedccf89204c6a99021d4a7006fb4821c43 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Thu, 2 Feb 2017 16:43:30 +0100 Subject: [PATCH 22/26] Add support for polar axis --- src/backends/pgfplots.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 6d8be4ba..c9bd9fba 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -307,7 +307,11 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:legendPos] = _pgfplots_legend_pos[legpos] end - o = PGFPlots.Axis(; style = style, kw...) + axisf = PGFPlots.Axis + if sp[:projection] == :polar + axisf = PGFPlots.PolarAxis + end + o = axisf(; style = style, kw...) # add the series object to the PGFPlots.Axis for series in series_list(sp) From 1111000217396f9bae5dd2c3db4e3b95156c73b0 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Thu, 2 Feb 2017 17:39:34 +0100 Subject: [PATCH 23/26] Add support for ticks rotation --- src/backends/pgfplots.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index c9bd9fba..c45f9157 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -225,6 +225,9 @@ function pgf_axis(sp::Subplot, letter) # axis guide kw[Symbol(letter,:label)] = axis[:guide] + # ticks + push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}") + # flip/reverse? axis[:flip] && push!(style, "$letter dir=reverse") From 3ca39728d8a15cc25e723b7b5d7365e053dc47b3 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Thu, 2 Feb 2017 20:38:34 -0500 Subject: [PATCH 24/26] Make compatible with InspectDR v0.1.4. --- src/backends/inspectdr.jl | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 4f6a57f9..72034473 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -128,16 +128,17 @@ end # --------------------------------------------------------------------------- -function _inspectdr_getscale(s::Symbol) +function _inspectdr_getscale(s::Symbol, yaxis::Bool) #TODO: Support :asinh, :sqrt + kwargs = yaxis? (:tgtmajor=>8, :tgtminor=>2): () #More grid lines on y-axis if :log2 == s - return InspectDR.AxisScale(:log2) + return InspectDR.AxisScale(:log2; kwargs...) elseif :log10 == s - return InspectDR.AxisScale(:log10) + return InspectDR.AxisScale(:log10; kwargs...) elseif :ln == s - return InspectDR.AxisScale(:ln) + return InspectDR.AxisScale(:ln; kwargs...) else #identity - return InspectDR.AxisScale(:lin) + return InspectDR.AxisScale(:lin; kwargs...) end end @@ -337,14 +338,17 @@ end # --------------------------------------------------------------------------- function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) - const gridon = InspectDR.grid(vmajor=true, hmajor=true) - const gridoff = InspectDR.grid() + const gridon = InspectDR.GridRect(vmajor=true, hmajor=true) + const gridoff = InspectDR.GridRect() const plot = sp.o + const strip = plot.strips[1] #Only 1 strip supported with Plots.jl + + #No independent control of grid??? + strip.grid = sp[:grid]? gridon: gridoff xaxis = sp[:xaxis]; yaxis = sp[:yaxis] - xscale = _inspectdr_getscale(xaxis[:scale]) - yscale = _inspectdr_getscale(yaxis[:scale]) - plot.axes = InspectDR.AxesRect(xscale, yscale) + plot.xscale = _inspectdr_getscale(xaxis[:scale], false) + strip.yscale = _inspectdr_getscale(yaxis[:scale], true) xmin, xmax = axis_limits(xaxis) ymin, ymax = axis_limits(yaxis) if ispolar(sp) @@ -353,11 +357,13 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) xmin, xmax = -rmax, rmax ymin, ymax = -rmax, rmax end - plot.ext = InspectDR.PExtents2D() #reset - plot.ext_full = InspectDR.PExtents2D(xmin, xmax, ymin, ymax) + plot.xext = InspectDR.PExtents1D() #reset + strip.yext = InspectDR.PExtents1D() #reset + plot.xext_full = InspectDR.PExtents1D(xmin, xmax) + strip.yext_full = InspectDR.PExtents1D(ymin, ymax) a = plot.annotation a.title = sp[:title] - a.xlabel = xaxis[:guide]; a.ylabel = yaxis[:guide] + a.xlabel = xaxis[:guide]; a.ylabels = [yaxis[:guide]] l = plot.layout l.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot]) @@ -376,8 +382,6 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) _inspectdr_mapptsize(xaxis[:tickfont].pointsize), color = _inspectdr_mapcolor(xaxis[:foreground_color_text]) ) - #No independent control of grid??? - l.grid = sp[:grid]? gridon: gridoff leg = l.legend leg.enabled = (sp[:legend] != :none) #leg.width = 150 #TODO: compute??? From d883274586c0774d51c5c64d50600e6faaeb9540 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Fri, 3 Feb 2017 08:25:55 +0100 Subject: [PATCH 25/26] Fix comments --- src/backends/pgfplots.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index c45f9157..de4d4a6a 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -142,7 +142,7 @@ function pgf_add_annotation!(o,x,y,val) halign = val.font.halign == :hcenter ? "" : string(val.font.halign) cstr,a = pgf_color(val.font.color) push!(o, PGFPlots.Plots.Node(val.str, # Annotation Text - x, y, # x,y + x, y, style=""" $halign, color=$cstr, draw opacity=$(convert(Float16,a)), @@ -225,7 +225,7 @@ function pgf_axis(sp::Subplot, letter) # axis guide kw[Symbol(letter,:label)] = axis[:guide] - # ticks + # Add ticklabel rotations push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}") # flip/reverse? From 0880487be2eff61464b644cff6614533776c0fa0 Mon Sep 17 00:00:00 2001 From: YongHee Kim Date: Mon, 6 Feb 2017 21:29:41 +0900 Subject: [PATCH 26/26] enable standalone window for plotlyjs() backen --- src/backends/plotlyjs.jl | 12 +++++++++++- src/output.jl | 10 ++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 6d4ad145..0a2ad219 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -102,8 +102,18 @@ _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hac _show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "pdf") _show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "eps") +function write_temp_html(plt::Plot{PlotlyJSBackend}) + filename = string(tempname(), ".html") + savefig(plt, filename) + filename +end + function _display(plt::Plot{PlotlyJSBackend}) - display(plt.o) + if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") + display(plt.o) + else + standalone_html_window(plt) + end end diff --git a/src/output.jl b/src/output.jl index ee9972ab..f3efd812 100644 --- a/src/output.jl +++ b/src/output.jl @@ -302,6 +302,10 @@ function setup_atom() Media.render(pane, Atom.div(".fill", Atom.HTML(stringmime(MIME("text/html"), plt)))) plt[:size] = sz end + # special handling for PlotlyJS + function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyJSBackend}) + display(Plots.PlotsDisplay(), plt) + end else # function Media.render(pane::Atom.PlotPane, plt::Plot) @@ -317,11 +321,5 @@ function setup_atom() s = "PlotPane turned off. The plotly and plotlyjs backends cannot render in the PlotPane due to javascript issues." Media.render(pane, Atom.div(Atom.HTML(s))) end - - # special handling for PlotlyJS to pass through to that render method - function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyJSBackend}) - Plots.prepare_output(plt) - Media.render(pane, plt.o) - end end end